Java集合类-Collection
Collection与Map的简介:
(1)Collection:单列集合类的根接口,用于存储一系列符合某种规则的元素,它有两个重要的子接口,分别是List和Set。
- List的特点是元素有序、元素可重复。主要接口有:ArrayList和LinkedList
- Set的特点是元素无序,而且不可重复。主要接口有:HashSet和TreeSet
(2)Map:双列集合类的根接口,用于存储具有键(Key)、值(Value)映射关系的元素,每个元素都包含一对键值,在使用Map集合时可以通过指定的Key找到对应的Value,例如根据一个学生的学号就可以找到对应的学生。主要接口有:HashMap和TreeMap

接下来,先对Collection接口进行详细的解释把。
Collection接口:
Collection是所有单列集合的父接口,因此在Collection中定义了单列集合(List和Set)通用的一些方法,这些方法可用于操作所有的单列集合。

Collection coll = new ArrayList();
coll.add("abc"); //向集合coll中加入元素
coll.add("def");
coll.add("123");
System.out.println(coll.size()); //输出集合coll中共有几个类
System.out.println(coll.isEmpty()); //判断集合coll是否为空——->返回Boolean
coll.remove("123"); //移除集合coll中的数据“123”
System.out.println(coll.size());
System.out.println("============================");
Collection coll1 = new ArrayList();
coll1.add("ABC");
coll1.add(new String("AAA"));
coll1.add(new Person("VXXL",22));
coll1.add("DEF");
coll1.add("123");
System.out.println(coll1.size());
System.out.println(coll1);
System.out.println(coll1.contains(new String("AAA")));
//true使用contains相当于重写调用equals
// System.out.println(coll1.contains(new Person("VXXL", 22)));
//false自定义对象则需要自己重写equals
System.out.println(coll1.contains(new Person("VXXL", 22)));
//true 重写equals后使用contains
coll.addAll(coll1);
//向集合coll中加入集合coll1集合中的所有数据
System.out.println(coll.size());
System.out.println("========================");
coll.removeAll(coll1);
System.out.println(coll);
//在集合coll中移除与coll1集合里面相同的元素
Collection coll2 = Arrays.asList("abc","def","ABC");
System.out.println(coll.contains("abc"));
//判断集合coll里面是否存在数据"abc",返回Boolean
System.out.println(coll.containsAll(coll2));
//判断集合coll里面是否存在集合coll2集合里面的所有数据
coll.retainAll(coll2);
//求出coll集合与coll2集合里面相同的数据
System.out.println(coll);
Object[] s1 = coll2.toArray(); //将集合转换称为数组
for (int i = 0; i < s1.length; i++) {
System.out.print(s1[i] + "、");
}
System.out.println();
System.out.println("===================================");
List<String> coll3 = Arrays.asList(new String[]{"ABC","DEF"}); //将数组转换成集合
System.out.println(coll3);
List coll4 = Arrays.asList(new int[]{123,456}); //int类型打印出错
System.out.println(coll4);
List<Integer> coll5 = Arrays.asList(new Integer[]{123,456}); //使用包类打印不会出错
System.out.println(coll5);
Iterator接口:
java需要遍历集合中所有元素的时候就可以用Iterator,Iterator接口也是Java集合中的一员,但它与Collection、Map接口有所不同,Collection接口与Map接口主要用于存储元素,而Iterator主要用于迭代访问(即遍历)Collection中的元素,因此Iterator对象也被称为迭代器。下面是Iterator的运行原理:

图解:
在调用next()方法之前,迭代器的索引会指向第一个元素的前一个位置,而hasNext()则会判断第一个元素是不是空值,来决定进不进行下一次调用;当第一次调用next()方法后,会指向第一个元素,hasNext()会指向下一个元素的位置;以此类推,当hasNext()判断到当前元素为空是,next()则会在将上一个元素输出后停止执行。
Iterator通常用next()与hasNext()方法一起使用:
-
next():返回集合中迭代的下一个元素
-
hasNext():判断集合中是否为空
-
remove():从集合中移除这个迭代器返回一个元素
-
使用iterator返回的元素都会被当作Object类型,如果想得到特定类型则需要进行强制转换
Collection coll = new ArrayList(); //创建一个集合
coll.add("abcd");
coll.add("efgh");
coll.add("ABCD");
Iterator iterator = coll.iterator(); //创建iterator迭代器,用于遍历集合
//iterator使用hasNext()加next()进行调用:
while (iterator1.hasNext()) {
System.out.println(iterator1.next()); //输出集合中每个元素
}
foreach循环:
foreach循环是一种更加简洁的for循环,也称增强for循环。foreach循环用于遍历数组或集合中的元素,其具体语法格式如下:
//对于数组对象------->for(数组元素的类型 局部变量 : 数组对象)
int[] a = new int[]{1,2,3,4,5,6};
for (int x : a) {
System.out.print(x);
}
//对于集合对象------>for(集合元素的类型 局部变量 : 集合对象)
for (Object obj : coll) { //使用foreach遍历集合coll,返回类型是object
System.out.println(obj);
}
ArrayList、LinkedList、Vector:
ArrayList、LinkedList、Vector三者都实现了List接口,存储有序的、可重复的数据。
- ArrayList:
ArrayList是List接口的一个实现类,它是程序中最常见的一种集合。在ArrayList内部封装了一个长度可变的数组对象,当存入的元素超过数组长度时,ArrayList会在内存中分配一个更大的数组来存储这些元素,因此可以将ArrayList集合看作一个长度可变的数组,在查询元素时速度很快,但在增删元素时效率较低。线程不安全,效率高; - LinkedList:该集合内部维护了一个双向循环链表,链表中的每一个元素都使用引用的方式来记住它的前一个元素和后一个元素,从而可以将所有的元素彼此连接起来。当插入一个新元素时,只需要修改元素之间的这种引用关系即可,删除一个节点也是如此。正因为这样的存储结构,所以LinkedList集合对于元素的增删操作具有很高的效率。

- Vector:是List接口最早引入的实现类,线程安全,效率低。(现在基本不用)
ArrayList:
List接口继承自Collection接口,是单列集合的一个重要分支,习惯性地会将实现了List接口的对象称为List集合。允许出现重复的元素,所有的元素是以一种线性方式进行存储的,可通过索引访问集合中的指定元素。且元素的存入顺序和取出顺序一致。
List作为Collection集合的子接口,不但继承了Collection接口中的全部方法,而且还增加了一些根据元素索引来操作集合的特有方法:

ArrayList coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new Person("VX",7));
coll.add("abc");
coll.add(123);
System.out.println("原始集合:" + coll);
coll.add(1,"AAA"); //在索引为1的位置上插入元素"AAA"
System.out.println("使用add(index,e)后的集合:" + coll);
List coll1 = Arrays.asList(123,456);
coll.addAll(6,coll1); //在索引为6的位置上插入集合coll1的所有元素
System.out.println("使用addall(index,coll)后的集合:" + coll);
Object o = coll1.get(0); //使用get(index)获取集合coll1中索引为0的元素
System.out.println(o);
coll.remove(6); //使用remove(index)删除指定索引中的元素
System.out.println("使用remove(index)删除索引为6的集合" + coll);
coll.set(0,"aaa"); //使用set(index,e)修改指定索引中的元素
System.out.println("使用set(index,e)修改元素:" + coll);
int i = coll.indexOf(456); //返回456在集合中第一次出现的位置索引
System.out.println(i);
int i1 = coll.lastIndexOf(456); //返回456在集合中最后一次出现的位置索引
System.out.println(i1);
List list = coll.subList(2, 5); //使用subList(fromIndex,toIndex)返回fromIndex到toIndex中元素
System.out.println("使用subList后的结果:" + list);
LinkedList:
LinkedList存取方式为双链表模式,对集合具有增删元素效率高的特点。以下是其特有的方法:

LinkedList coll = new LinkedList();
coll.add(123);
coll.add(456);
coll.add(new Person("VX",7));
coll.add("abc");
coll.add(123);
System.out.println("原始集合:" + coll);
coll.addFirst("first"); //addFirst() 在指定元素添加此列表开头
System.out.println("使用addFirst()的集合:" + coll);
coll.addLast("last"); //addLast() 在指定元素添加此列表末尾
System.out.println("使用addLas()的集合:" + coll);
System.out.println(coll.getFirst()); //getFirst()返回此列表的第一个元素
System.out.println(coll.removeLast()); //removeLast()移除此列表的最后一个元素
HashSet和TreeSet:
Set接口和List接口一样,同样继承自Collection接口。Set接口同样拥有Collection接口的所有方法,但是没有引入新的方法。同时,Set接口里面的元素是无序的,不可重复的。它的主要接口有:HashSet和TreeSet
Set接口主要有两个实现类,分别是HashSet和TreeSet。
- HashSet是根据对象的哈希值来确定元素在集合中的存储位置,且通过equals()进行对比,防止元素重复。存储的元素是不可重复的,并且元素都是无序的,因此具有良好的存取和查找性能。
- LinkedHashSet:HashSet的子类,可以按照集合添加的顺序确定添加存储位置。 在添加数据的同时,每个数据还维护了两个引用,记录此数据前一个数据和后一个数据。
- TreeSet是以二叉树的方式来存储元素,且集合里面的元素必须为同一数据类型,它可以实现对集合中的元素进行排序。可以添加对象指定属性,进行自定义排序。
HashSet:
HashSet集合确保不出现重复的元素的解析:
- 当我们调用HashSet()的add()方法是,首先会去调用hasCode()方法获取此对象的哈希值,再用此哈希值与Set集合里面原有的数据的哈希值进行对比:
- 如果哈希值不相同,那么先添加的这个数据不构成重复性,可以直接添加到集合里去。
- 如果哈希值相同,则会调用equals()方法进行对比:
- 如果equals()对比不相同,返回false,那么先添加的这个数据不构成重复性,可以直接添加到集合里去。
- 如果equals对比相同,返回true,则代表集合中已有这个元素,不能添加进去。

//HashSet():无序,不可重复
Set coll = new HashSet();
coll.add(123);
coll.add(456);
coll.add("ABC");
Iterator iterator = coll.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next()); // ABC 456 123
}
//双向链表按添加顺序排列
Set coll = new LinkedHashSet();
coll.add(123);
coll.add(456);
coll.add("ABC");
System.out.println(coll); //123 456 ABC
TreeSet:
TreeSet底层实际是用TreeMap实现的,内部维持了一个简化版的TreeMap,通过key来存储Set的元素。TreeSet内部需要对存储的元素进行排序,可以通过实现Comparable接口,再根据compareTo()方法比较对象的大小。而且TreeSet不能放入null。
public void test3() { //自然排序:compareTo()返回0,不再是equals();
Set coll = new TreeSet();
coll.add(789);
coll.add(456);
coll.add(123);
System.out.println(coll); //123 456 789
}
public void test4() { //定制排序:compare()返回0,不再是equals();
Comparator test = new Comparator() { //自定义Comparator方法test
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Person && o2 instanceof Person) {
Person u1 = (Person) o1;
Person u2 = (Person) o2;
return Integer.compare(u1.getAge(), u2.getAge());
} else {
throw new RuntimeException("输入类型数据不匹配");
}
}
};
TreeSet coll1 = new TreeSet(test); //TreeSet(com)里面有参数,则按照参数定义的排序方法进行排序
coll1.add(new Person("VX",4));
coll1.add(new Person("XV",2));
coll1.add(new Person("LX",6));
coll1.add(new Person("HK",6));
coll1.add(new Person("HK",10));
Iterator iterator = coll1.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
/*
Person{name='XV', age=2}
Person{name='VX', age=4}
Person{name='LX', age=6}
Person{name='HK', age=10}
*/

浙公网安备 33010602011771号