一.Collection 集合体系介绍
Colletion是集合的根接口,其子接口List和Set分别继承根接口.而ArrayList集合,LinkedList集合以及Vector集合是List集合的实现类.HashSet集合,LinkedHashSet集合以及TreeSet集合是Set集合的实现类.Collection,List,Set接口中的方法,其相对应的实现类也就可以直接使用,因为继承下来了.每个实现类不仅继承了其父接口中的方法,还都有自己独特的方法.
1.单列表集合的工具类Collections类
public static <T > void sort (List < T > list); 对集合进行排序, 默认按照自然顺序
public static <T > int binarySearch (List < ? > list, T key); 二分查找查找集合中的元素
public static <T > T max(Collection < ? > coll); 获取集合中的最大值
public static void reverse (List < ? > list); 反转集合中的元素
public static void shuffle (List < ? > list); 随机置换集合中的元素,即打乱集合中的元素位置
除此之外,单列集合还有一个针对集合操作的Collections工具类,其中包含了很多常用的静态方法
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class Test1 {
public static void main(String[] args) {
//Collections工具类中给方法
ArrayList<Integer> list = new ArrayList<>();
list.add(20);
list.add(24);
list.add(25);
list.add(22);
list.add(20);
list.add(26);
//list.sort();
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer a, Integer b) {
return a - b;
}
});
System.out.println(list); //[20, 20, 22, 24, 25, 26]
//二分查找,元素必须有序
int index = Collections.binarySearch(list, 24);
System.out.println(index); //3
//获取最大最小值
Integer max = Collections.max(list);
Integer min = Collections.min(list);
System.out.println(max); //26
System.out.println(min); //20
//反转
Collections.reverse(list);
System.out.println(list); //[26, 25, 24, 22, 20, 20]
//随机置换
Collections.shuffle(list);
System.out.println(list); //[25, 20, 20, 22, 26, 24]
}
}
2.Collection接口和Conllections工具类的区别
Collection 是一个集合接口.它提供了对集合对象进行基本操作的通用接口方法.Collection接口在Java 类库中有很多具体的实现.Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式.
Collections 是一个包装类.它包含有各种有关集合操作的静态多态方法.此类不能实例化,是一个工具类,服务于Java的Collection框架(单列表集合).
*** :Collections 是一个包装类,Collection 表示一组对象,这些对象也称为 collection 的元素。
二.集合中的根接口:Collection接口
Collection接口是集合中的根接口,里面有很多方法,会被子接口以及实现类所继承和使用.
1.Collection接口中的方法
add(Object obj); 往集合中添加元素
addAll(Collection c): 添加一个集合的元素 (给一个集合添加进另一个集合中的所有元素)
clear(): 移除所有元素
remove(Object o): 移除一个素
removeAll(Collection c): 移除一个集合的元素(移除一个以上返回的就是true) 删除的元素是两个集合的交集元素 ,如果没有交集元素 则删除失败 返回false
contains(Object o): 判断集合中是否包含指定的元素
containsAll(Collection c): 判断集合中是否包含指定的集合元素(这个集合 包含 另一个集合中所有的元素才算包含,才返回true)
isEmpty(): 判断集合是否为空
iterator(); 获取集合中的迭代器,通常用来遍历集合.
size(): 元素的个数,也就是集合的长度
retainAll(Collection c): 获取两个集合的交集元素放在集合中,返回的布尔值表示的是A集合是否发生变化
toArray(); 把集合转换为数组
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Test {
public static void main(String[] args) {
//Collection
Collection c1 = new ArrayList(); //多态,ArrayList是实现类
//往集合中添加元素
c1.add("aaa");
c1.add("bbb");
c1.add("ccc");
c1.add("ddd");
c1.add("eee");
Collection c2 = new ArrayList();
c2.add("aaa");
c2.add("bbb");
c2.add("ccc");
//集合只能存储引用数据类型的元素。
int num = 100;
c1.add(num); //Integer 自动装箱
c1.add(3.25);//Double
System.out.println(c1); //[aaa, bbb, ccc, ddd, eee, 100, 3.25]
boolean b = c1.addAll(c2);
System.out.println(b); //true
//删除集合中的某个元素
boolean b2 = c1.remove("aaa");
if (b2) {
System.out.println(c1); //[bbb, ccc, ddd, eee, 100, 3.25, aaa, bbb, ccc]
}
//c1 会删除掉两个集合的交集元素,c2的元素不影响。
boolean b3 = c1.removeAll(c2); //如果有交集元素被删除,返回true,没有交集元素被删除返回false
System.out.println(b3); //true
System.out.println(c1); //[ddd, eee, 100, 3.25]
System.out.println(c2); //[aaa, bbb, ccc]
//a集合.containsAll(b集合); 看a集合是否包含了所有b集合的元素,如果包含了返回true ,如果有一个没有包含就会false
boolean b4 = c1.containsAll(c2);
System.out.println(b4); //false
//获取长度的方法
int size = c1.size();
System.out.println(size); //4
//清空集合
System.out.println(c2); //[aaa, bbb, ccc]
c2.clear();
System.out.println(c2); //[]
}
}
3.集合与数组相互转换
3.1 集合转换为数组:
- 方法一: 遍历集合放入到数组中
- 方法二: toArray()方法
3.2 数组转换为集合:(asList())
- 第一种情况:面对一个数组时,是把数组中的元素放入到集合中
- 第二种情况:面对两个以上的数组或者传入的是基本数据类型的数组,都是把数组放到集合中
import java.util.*;
public class Test {
public static void main(String[] args) {
Student s1 = new Student("张三", 23);
Student s2 = new Student("李四", 24);
Student s3 = new Student("王五", 25);
Collection list = new ArrayList();
list.add(s1);
list.add(s2);
list.add(s3);
//集合转换为数组
//遍历放入到数组中
Student[] arr = new Student[list.size()];
Iterator iterator2 = list.iterator();
int index = 0;
while (iterator2.hasNext()) {
Student stu = (Student) iterator2.next();
arr[index++] = stu;
}
System.out.println(Arrays.toString(arr));
//[Student{name='张三', age=23}, Student{name='李四', age=24}, Student{name='王五', age=25}]
System.out.println("====================================");
//toArray()
Object[] objects = list.toArray();
System.out.println(Arrays.toString(objects));
//[Student{name='张三', age=23}, Student{name='李四', age=24}, Student{name='王五', age=25}]
//数组转换为集合
//面对一个数组时,是把数组中的的元素取出来放到集合中
Integer[] arr1 = {20, 30, 40};
List<Integer> integers = Arrays.asList(arr1);
System.out.println(integers);
//传入的是两个以上的数组,是把数组放到集合中
Integer[] arr2 = {20, 30, 40};
Integer[] arr3 = {50, 60, 70};
List<Integer[]> list2 = Arrays.asList(arr2, arr3);
Integer[] integers1 = list2.get(0);
System.out.println(integers1[0]);
int[] arr4 = {20, 30, 40};
//传入的元素为基本类型的数组,也是把数组放到集合中
List<int[]> ints = Arrays.asList(arr4);
int[] integers2 = ints.get(0);
System.out.println(integers2[0]);
}
}
三.Collection的子接口List接口
1.List集合
List集合中的元素有序,就是存入元素和取出元素的顺序一致,并且每一个元素都存在一个索引.元素是可以重复的.List接口是Conllection接口的子接口,那么也就继承了根接口Collection中的方法(也就是可以使用Collection中的各种方法).
2.List集合中特有的方法
add(int index,E element); 在指定索引处添加元素(重写后的方法)
remove(int index); 移除指定索引处的元素 ,返回的是移除的元素(重写后的方法)
get(int index); 获取指定索引处的元素
set(int index,E element); 更改指定索引处的元素 返回的而是被替换的元素
indexOf(Object o); 返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1.
lastIndexOf(Object o); 返回此列表中最后出现的指定元素的索引;如果列表不包含此元素,则返回 -1.
package com.xingyun.test;
import java.util.ArrayList;
import java.util.List;
public class ListTest {
public static void main(String[] args) {
List list = new ArrayList(); //ArrayList为实现类
//在指定索引位置,添加元素。
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add(0, "ddd");
System.out.println(list);
//根据索引来删除元素
list.remove(0);
System.out.println(list);
List list2 = new ArrayList();
list2.add(100);
list2.add(200);
list2.add(200);
list2.add(200);
list2.add(200);
list2.add(300);
list2.add(400);
list2.add(500);
//根据索引获取元素
Object o = list2.get(0);
System.out.println(o);
//修改元素,返回的是修改之前的旧元素。
Object oldEle = list2.set(0, 20000);
System.out.println(list2);
System.out.println(oldEle);
/* int indexOf (Object o)
返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 - 1。
int lastIndexOf (Object o)
返回此列表中最后出现的指定元素的索引;如果列表不包含此元素,则返回 - 1。*/
int index = list2.indexOf(200);
System.out.println(index);
int i = list2.lastIndexOf(200);
System.out.println(i);
}
}
3. 遍历List集合
*** :List集合中特有一个方法get方法,集合的遍历又出现了新的遍历方式!
方法一: Collection中的iterator()获取迭代器
方法二: for循环(结合使用List集合中的get方法)
方法三: 列表迭代器,List中的iterator()获取迭代器(List集合特有的迭代器)
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class ListTest2 {
public static void main(String[] args) {
List list = new ArrayList();
list.add(100);
list.add(200);
list.add(200);
list.add(300);
list.add(400);
list.add(500);
//List 集合的遍历方式
//可以使用父接口中的迭代器
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next);
}
System.out.println("===========================");
//for循环
for (int i = 0; i < list.size(); i++) {
Object o = list.get(i);
System.out.println(o);
}
System.out.println("============================");
//使用子接口List中的迭代器
ListIterator listIterator = list.listIterator();
while (listIterator.hasNext()) {
Object next = listIterator.next();
System.out.println(next);
}
}
}
四 .LIst接口的实现类
1.ArrayList集合
ArrayList 底层数据结构是数组,查询快,增删慢,线程不安全,效率高.
ArrayList集合特有的方法:
forEach() :遍历集合(JDK1.8新增的方法)
sort(): 对集合进行排序(底层使用提供的 Comparator比较元素)
subList(): 截取集合中的一部分元素到新的集合中(返回的不是ArrayList集合是内部类subList集合.)
补:ArrayList集合可以遍历的方法: a.for循环 / b.forEach / c.Collection的迭代器 / d.列表迭代器
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;
public class ArrayListTest {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(10);
list.add(50);
list.add(60);
list.add(20);
list.add(30);
list.add(10);
list.add(50);
list.add(60);
list.add(20);
list.add(30);
//subList
List list1 = list.subList(0, 2);
list1.add(600);
System.out.println(list1 +" "); //[10, 50, 600]
//forEach(之前的各种遍历也是可以使用的)
list.forEach(new Consumer() {
@Override
public void accept(Object ele) {
System.out.print(ele+" ");
}
});
//10 50 600 60 20 30 10 50 60 20 30
System.out.println();
//sort
list.sort(new Comparator() {
@Override
public int compare(Object a, Object b) {
Integer x = (Integer) a;
Integer y = (Integer) b;
return -(x - y); //根据返回值的 正 负 0 进行排序
}
});
System.out.print(list+" ");
//[600, 60, 60, 50, 50, 30, 30, 20, 20, 10, 10]
}
}
2.ArrayList集合和数组的区别
区别 | 数组 | 集合 |
长度 | 固定的 | 可变的 |
数据类型 | 基本数据类型、引用数据类型 | 基本数据类型 |
元素种类 | 同一种 | 任意种 |
3.Vector集合
Vector的底层数据结构是数组,查询快,增删慢,线程安全,效率低
Vector集合特有的方法
addElement (); 添加元素到集合中
elementAt (int index); 返回指定索引处的元素
firstElement (); 返回第一个元素
lastElement (); 返回最后一个元素
insertElement(); 插入元素到集合中
elements (); 遍历,相当于遍历器的东西
补:Vector集合可以遍历的方法: a.for循环 / b.forEach / c.Collection的迭代器 / d.列表迭代器 / e.Vector集合特有的elements ()
import java.util.Enumeration;
import java.util.Vector;
import java.util.function.Consumer;
public class VectorTest {
public static void main(String[] args) {
Vector vector = new Vector();
vector.add(100); //继承下来的方法
vector.add(100);
//添加元素
vector.addElement(600);
vector.addElement(200);
//插入元素
vector.insertElementAt(400, 0);
//返回第一个和最后面的元素
Object o = vector.get(0);
Object o1 = vector.firstElement();
Object o2 = vector.lastElement();
System.out.println(o);
System.out.println(o1);
System.out.println(o2);
//遍历
//for
for (int i = 0; i < vector.size(); i++) {
Object o3 = vector.get(i);
}
System.out.println("===============================");
//forEach
vector.forEach(new Consumer() {
@Override
public void accept(Object o) {
System.out.println(o);
}
});
System.out.println("==================================");
//elements()
Enumeration elements = vector.elements();
while (elements.hasMoreElements()) {
Object o3 = elements.nextElement();
System.out.println(o3);
}
}
}
4.LinkedList集合
LinkedList 底层数据结构是链表,查询慢,增删快,线程不安全,效率高
LinkedList集合中的特有方法
addLast(); 将元素添加到最后一个
addFirst(); 将元素添加到第一个
getFirst (); 获取第一个元素
getLast(); 获取最后一个元素
removeFirst () ; 删除第一个元素
poll (); 检索并删除此列表的第一个元素,返回删除后的集合
pop (); 检索并删除此列表的第一个元素,返回删除后的集合
poll方法与pop方法有什么区别?
当集合为空时,掉用pop方法会抛异常,而调用poll方法会返回null.唯一的区别就在这,其它功能以及效果都是一样的.
五.Collection的子接口Set接口中的实现类
Set集合元素无序且唯一(无序是指存储和取出的顺序不同).
1.HashSet集合(元素无序且唯一)
HashSet 底层数据结构是哈希表. HashSet 线程不安全.集合元素可以是 null.哈希表是数组+链表,jdk1.8版本后哈希表优化为数组+链表+红黑树.
元素的唯一性是靠元素重写hashCode()和equals()方法来保证的,如果不重写则无法保证唯一性.(Integer以及String类等都已经重写了这两个方法,一定要注意自己定义的类需要重写才能确保唯一性!)
2.LinkedHashSet集合(元素有序且唯一)
LinkedHashSet集合底层数据结构是哈希表和链表,元素有序且唯一.其中链表保证了元素有序,哈希表保证了元素唯一.且该集合中没有get方法,就不能直接使用for循环.
3.TreeSet集合(元素唯一且可对元素进行排序)
TreeSet集合底层数据结构是二叉树.元素唯一且可对元素进行排序.一般默认排序是自然排序,也可以用比较器排序.