java的集合框架
java.util.Collection接口
Collection:是所有集合的顶级接口,里面规定了集合操作元素的相关功能方法集合与数组一样,用于存储一组元素,但是集合又多个不同的实现类来实现不同的数据结构
Collection下面有两个常见的子接口
1.1 java.util.List:** *线性表,特点:可以存放重复元素并且有序,可以通过下标操作
List常见的实现类:
java.util.ArraysList:内部使用数组实现,查询性能更好
java.util.LinkedList:内部用链表实现,增删元素性能更好,首尾增删元素性能最佳
(这里的重复元素判定是依靠元素自身equals方法比较的结果而定)
1.2: java.util.Set:不可以重复的集合,并且无序
Set常见的实现类:
1.java.util.HashSet
HashSet底层就是HashMap
HashMap连接
队列继承Collection所以队列本身也是一种集合:
队列链接地址
2.java.util.TreeSet(二叉树)
创建集合
Collection c = new ArrayList();
boolean add(E e):向当前集合添加一个元素,成功添加后返回true否则返回false
c.add("one");
int size():返回当前集合的元素个数
int size = c.size();
boolean isEmpty():判断集合是否为空集,当集合的size为0时,isEmpty返回true
boolean isEmpty = c.isEmpty();
c.clear():清空集合
boolean contains(Object o):判断当前集合是否包含给定元素
集合的contains判断包含时的依据为:给定元素是否与集合中现有的元素存在equals比较为true的情况,存在则认为包含
boolean contains = c.contains(p);
remove方法删除元素时也是删除与集合中equals比较为true的,元素对于List集合而言,重复元素仅删除一次
c.remove(p);
集合只能存放引用类型元素,并且存放的是元素的引用(地址)
Point p = new Point(1,2);
c.add(p);
p.setX(2); //修改p的第一个参数为2:(2,2)
boolean addAll(Collection c):将给定集合中的所有元素添加到当前集合
Collection c1 = new ArrayList();
c1.add("java");
c1.add("c++");
Collection c2 = new ArrayList();
c2.add("android");
c2.add("ios");
c1.addAll(c2);
boolean containsAll(Collection e):判断当前集合是否包含给定集合中的所有元素
Collection c3 = new ArrayList();
c3.add("java");
boolean contains = c1.containsAll(c3);
removerAll:删除当前集合中与给定集合的共有元素
c1.removeAll(c3);
集合的遍历
- Collection提供了一个方法
- Iterator iterator()
- 该方法会返回一个用于遍历当前集合的迭代器实现类,使用它可以对集合进行遍历
java.util.Iterator接口:迭代器
- 迭代器中规定了遍历集合元素所需要的相关方法,使用迭代器遍历遵循的原则为:问,取,删,其中删除元素不是遍历过程中的必要操作
- 注:不同的集合实现类都提供一个用于遍历自身的迭代器实现类,我们不需要知道它们的名字,用多态的思想把它们看成Iterator进行操作即可.
JDK5推出时推出了一个新特性:泛型
泛型又称为参数实例化类型,允许我们我们在使用一个类型的时候去指定它里面某些属性或方法的参数和返回值的类型,使得我们使用这个类时更符合我们的需求
泛型在集合中被大量使用,用于规定集合中的元素类型
Collection<String> c = new ArrayList<>();
c.add("one");
c.add("#");
c.add("two");
c.add("#");
c.add("three");
System.out.println(c);
// 迭代器也支持泛型,使用时指定的类型与集合元素类型一致即可
Iterator<String> it = c.iterator();
// boolean hasNext():判断集合是否还有元素可以迭代
while (it.hasNext()){
// E next():获取集合下一个元素(第一次调用时获取第一个元素,以此类推)
String str = it.next();
System.out.println(str);
if ("#".equals(str)){
/*
迭代器有一个要求,在遍历的过程中不能通过集合的方法
增删元素,否则会出现异常
*/
/*
迭代器提供的remover方法可以删除本次遍历出来的元素
*/
it.remove();
}
}
java.util.List接口:
List list = new ArrayList<>();
E get(int index):获取指定下标所对应的元素
E set(int index,E e):将给定元素设置到指定位置,返回值为该位置原有元素
void add(int index,E e):将给定元素添加到指定位置,原位置及后续元素顺序向后移动
list.add(2,"3");
E remove(int index):删除并返回指定位置的元素
String old = list.remove(3);
List subList(int start,int end): 获取当前集合指定范围内的子集
List<Integer> list = new ArrayList<>();
for(int i=0;i<10;i++){
list.add(i);
}
System.out.println(list);
List<Integer> subList = list.subList(3,8);
System.out.println(subList);
//将子集每个元素扩大10倍
for (int i=0;i<subList.size();i++){
int a = subList.get(i);
int b = a*10;
subList.set(i,b);
}
System.out.println(subList);
*//*
当我们通过一个List集合获取到一个子集后,对这个子集的任何操作
就是对原集合这段元素的操作
*//*
System.out.println(list);
增强型for循环 JDK5推出时推出的一个新特性
- 它也称为:增强for循环
- 新循环不取代传统的for循环的工作,它只是用相同的语法去遍历集合或数组使用
- 新循环是编译器认可,而不是java虚拟机认可,编译器在编译源代码时发现使用新循环遍历数组时,会将代码改为普通的for循环进行
- 新循环遍历集合会被编译器修改为迭代器遍历 因此在使用新循环遍历过程中,仍然不能通过集合的方法增删元素
集合转换为数组:Collection提供了一个方法:toArray(),可以将当前集合转换为一个数组
将当前集合转换为数组,该方法要求传入一个数组,如果该数组可以用(数组长度>=集合的size时)会将当前集合元素存入该数组后再将该数组返回
如果不可以用会创建一个与参数数组同类型并且长度与size一致的数组并将元素存放后返回
Collection<String> c = new ArrayList<>(); //集合
String[] array = c.toArray(new String[c.size()]); //数组
数组转换为集合:数组的工具类:Arrays提供了一个静态方法:asList,可以将一个数组转换为一个List集合
-
通过数组转化而来的集合,对该集合的元素操作就是对原数组的操作这一点需要特别注意!
-
由于数组是定长的,因此从从数组转换的集合不可以调用增删元素等会影响数组的长度,否则会抛出异常:UnsupportedOperationException
如果想向集合中增删元素,需要自行创建一个集合,然后将原集合元素导入到该集合即可
所有的集合元素都支持一个参数类型为Collection的构造方法,作用是在创建当前集合的同时包含给定集合中的所有元素
String[] array = {"one","two","three","four","five"}; //数组
List<String> list = Arrays.asList(array); //集合
集合排序
随机生成19个100以内的数进行排序
List<Integer> list = new ArrayList<>();
Random random = new Random();
for(int i=0;i<10;i++){
list.add(random.nextInt(100));
}
System.out.println(list);
Collections.sort(list); //从小到大排序
System.out.println(list);
Collection.sort(List list)该方法对List集合进行自然排序
即:从小到大排序,但是该方法对集合又一个要求,元素必须实现了接口
Comparable,否则编译不通过
该接口中有一个抽象方法要求实现类重写,用于定义该类元素之间的大小关系
java中很多常用的类都实现了它,比如String,包装类
当我们调用一个方法,而这个方法反过来还要求我们为其修改其他地方的代码
(比如这里我们要求我们修改Point类去实现Comparable接口并重写方法)
这种现象称为侵入性,侵入性越高(改的代码越多)越不利,写程序应当尽量
避免侵入性
// Collections.sort(list, new Comparator<Integer>() {
// public int compare(Integer o1, Integer o2) {
// return o2-o1;
// }
// });
/*匿名内部类排序,此方式可以进行升序和降序*/
Collections.sort(list,(o1,o2)->o2-o1);
System.out.println(list);
// Collections.reverse(list); //集合的反转,变为从大到小
// System.out.println(list);
Comparable和Comparator区别
Comparable, Comparator都可以用来实现集合中元素的比较、排序的接口
Comparable:位于包java.lang下,是在集合内部定义的方法,该接口中有一个抽象方法要求实现类重写,定义该类元素之间的大小关系,java中很多常用的类都实现了它,比如String,包装类
Comparator:是比较器的接口,位于包java.util下,是在集合外部定义的方法,实现它就需要重写compare来定义,因此实现这个接口的类是可比较的,通过这里直接以匿名内部类形式创建为,
Collection和Collections的区别
**Collection:**是所有集合的顶级接口,规定了所有集合都要具备的功能。集合与数组一样,用于保存一组元素,但是实现类众多(有多种不同的数据结构)
**Collections:**是个一个工具类,提供了一系列的静态方法来辅助容器操作,这些方法包括对容器的搜索、排序、线程安全化等等。