List(列表)
ArrayList
ArrayList:动态数组,可看作自动分配数组容量的数组。ArrayList通过一个内部Object对象数组实现,并分配初始容量,当元素个数超过其容量时,会自动扩充数组。
添加元素
:通过arraylist.add(element)
添加元素,可通过arraylist.size()
查看当前元素个数。
ArrayList<String> arrayList = new ArrayList<String>();
可通过泛型<> , 指定元素的类型,默认为Object类型
System.out.println("add前List:"+arrayList.toString());
System.out.println("元素数量 "+arrayList.size());
//添加元素
arrayList.add("0号小白鼠");
arrayList.add("1号小白鼠");
arrayList.add("2号小白鼠");
arrayList.add("3号小白鼠");
arrayList.add("4号小白鼠");
System.out.println("add后List:"+arrayList.toString());
System.out.println("元素数量 "+arrayList.size());
代码输出:
按索引添加,获取元素
每个被加入到ArrayList的元素都会给其分配一个索引,可通过arraylist.get(index)
获取元素,也可通过arrayList.add(index, element)
按索引添加元素,按索引插入后,原有的元素后自动向后移动。
System.out.println("当前ArrayList: " + arrayList);
//展示当前ArrayList
System.out.println("按索引取: "+arrayList.get(3));
//按索引取元素
arrayList.add(2, "新增2号小白鼠");
System.out.println("新增2号小白鼠后: "+arrayList.toString());
代码输出:
删除元素
arrayList.remove()
可删除元素,可传入元素索引,或元素本身。
System.out.println("当前ArrayList: " + arrayList);
//展示当前ArrayList
arrayList.remove(2);
System.out.println("删除索引为2的元素"+arrayList.toString());
arrayList.remove("0号小白鼠");
System.out.println("删除0号小白鼠""+arrayList.toString());
代码输出:
包含元素
可通过arrayList.contains(element)判断元素是否在集合内
System.out.println("当前ArrayList: " + arrayList);//展示当前ArrayList
System.out.println(arrayList.contains("sss"));
System.out.println(arrayList.contains("1号小白鼠"));
代码输出:
遍历元素
遍历ArrayList中的元素有几3种方法
1:使用for循环配合 ArrayList.size()
,通过索引遍历集合
System.out.println("当前ArrayList: " + arrayList);//展示当前ArrayList
for (int i = 0; i < arrayList.size(); i++) {
System.out.println(arrayList.get(i));
}
代码输出:
2:通过迭代器Iterator遍历
每个集合都可以通过Iterator方法返回迭代器,可认为迭代器含有一个指针指向两个元素之间的位置,初始指向第一个元素之前,通过next()方法移动指针,并返回指针划过的元素。通过hasnext()判断指针后是否还有元素。
System.out.println("当前ArrayList: " + arrayList);//展示当前ArrayList
Iterator<String> iterator = arrayList.iterator();
while (iterator.hasNext()) {
String element = iterator.next();
System.out.println(element);
}
代码输出:
3:增强的for循环
可通过foreach关键字得到代码提示
System.out.println("当前ArrayList: " + arrayList);//展示当前ArrayList
for (String string : arrayList) {
System.out.println(string);
}
代码输出:
Vector和LinkedList
Vector 和 LinkedList的 API(函数方法) 和 ArrayList基本完全相同,不同的是他们的的内部实现。
Vector是线程安全类,效率低于ArrayList。
ArrayList 不是线程安全类,效率高于Vector。
ArrayList内部实现采用的是顺序表数组结构,可实现随机访问存储。
LinkedList内部实现采用的是链表结构,访问中间元素需要将前面的元素遍历一遍,但添加删除元素无需进行大量移动操作。所以当添加删除元素频繁时应采用LinkedList。详细内容请参考数据结构的基础知识。
将上述代码中的ArrayList替换为Vector或LinkedList,结果完全相同。
Set(集)
上述List集合(ArrayList,LinkedList,Vector)中的元素都是有序的(按插入顺序排序),可重复的。
Set类型的集合中的元素是乱序的,不重复的。
HashSet
HashSet内部采用哈希表结构实现
ArrayList<String> arrayList = new ArrayList<String>() ;
arrayList.add("0号小白鼠");
arrayList.add("1号小白鼠");
arrayList.add("2号小白鼠");
arrayList.add("3号小白鼠");
arrayList.add("3号小白鼠");
System.out.println("arraylist:"+arrayList);
HashSet<String> hashSet = new HashSet<String>() ;
hashSet.add("0号小白鼠");
hashSet.add("1号小白鼠");
hashSet.add("2号小白鼠");
hashSet.add("3号小白鼠");
hashSet.add("3号小白鼠");
System.out.println("hashset:"+hashSet);
代码输出:
HashSet是乱序的,所以没有get()方法,其他的API与上述集合基本一致。
TreeSet
TreeSet中的元素是有序的,按指定的比较器Comparator进行排序,若无比较器,则需要TreeSet中的元素实现了Comparable接口。
TreeSet内部实现使用的数据结构是红黑树。
TreeSet<String> tSet = new TreeSet<String>() ;
tSet.add("3号小白鼠");
tSet.add("1号小白鼠");
tSet.add("2号小白鼠");
tSet.add("0号小白鼠");
tSet.add("3号小白鼠");
System.out.println("treeSet:"+tSet);
代码输出:
Map(映射表)
Map集合就是键值对的集合。
HashMap利用散列表数据结构对键进行散列。
向Map中插入元素需要输入键key和值value,Map.put(key, value)
键不能重复,重复键key会用新插入的值value覆盖之前key所对应的value.
map.get(key)
可以返回key对应的value
HashMap<Integer, String> hashMap = new HashMap<Integer, String>();
hashMap.put(1, "第1个放进去");
hashMap.put(1, "第1个放进去,重新放一次");
hashMap.put(22, "第2个放进去");
hashMap.put(73, "第3个放进去");
hashMap.put(24, "第4个放进去");
hashMap.put(15, "第5个放进去");
hashMap.put(7, "第6个放进去");
hashMap.put(69, "第7个放进去");
System.out.println(hashMap.toString());
System.out.println(hashMap.get(24)); //通过键,取值
代码输出:
遍历Map
虽然可单独得到键,值,键值对的集合,但还是推荐通过键访问值,而不是直接访问值。
Entry类型就是存储单独键值对所使用的类型Entry<key, value>
,Map内部实现都是使用了Entry类型。
System.out.println("Map:\n"+hashMap.toString()); //展示Map
System.out.println("\n---单独遍历键---");
for (Integer in : hashMap.keySet()) {
System.out.print(in+" ");
//单独遍历所有键
}
System.out.println();
System.out.println("\n---单独遍历值---");
for (String string : hashMap.values()) {
System.out.print(string+" ");
//单独遍历所有值
}
System.out.println();
System.out.println("\n---通过遍历键遍历键值对---");
for (Integer in : hashMap.keySet()) {
System.out.print(in+"="+hashMap.get(in)+" ");
//通过遍历键遍历键值对
}
System.out.println();
System.out.println("\n---通过entrys遍历键值对---");
for (Entry<Integer, String> entry : hashMap.entrySet()){
System.out.print(entry.getKey()+"-"+entry.getValue()+" ");
//直接遍历键值对,entry内存储一堆键值对
}
代码输出:
TreeMap
TreeMap 和 HashMap的使用方法基本一致,不同的是使用的数据结构不同。
HashMap使用的是散列表,TreeMap 使用的是红黑树。
这也导致了HashMap的键是乱序的,而TreeMap的键是有序的(类比TreeSet),TreeMap的键需要实现Comparable接口,或者传入比较器Comparator对键提供比较方法。