序言
- 这章笔记,只要讲述jdk8中关于Collection的知识,例如,Collection的体系结构,
Set
,List
,Map
等抽象接口的区别,和其具体的implement
1.接口
1.1Collection的体系结构
- 图例[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r0xF5xcx-1602060161785)(E:\typora\image\image-20200812151334631.png)]
- 补充说明
Colleciton
接口是其他collection接口的父接口,该接口代表着一组元素(数据接口),并且定义一些方法,可以对这些数据进行访问,遍历,操作等Set
接口其表示的是不可重复,无序的collecion类型,该接口可以表示例如线程等的抽象,其可以利用其的一些方法,来进行数论的操作(例如:并,交,差等),SortedSet
接口,继承Set
接口,其主要的功能可以对元素进行排序(不过要注意的是,该集合中的元素要实现Comparable
接口,在comparableTo
方法中指定比较大小的规则,或者提供Comparator
类)List
接口是可重复,有序的collection类型,其可以进行位置的操作,例如对搜索出某元素的index,或者可以替换某index上的元素- 所有有关
Collection
接口的实现类都需要提供一个构造函数,该参数为Collection
类型,目的是提供不同类型的Colleciton
接口,或者不同实现类之间的相互转换,例如Set
接口的实现类可以转化为List
接口实现类,HashSet
转化为TreeSet
Map
接口表示一组保存键值对的数据的容器,注意的是,其key不可重复,所以一个key最多只能映射一位valueSortedMap
接口跟SortedSet
的接口差不多,注意的地方也是key元素需要实现Comparable
或者提供Comparator
类- 所有有关
Map
接口的实现类都需要提供一个构造函数,该参数为Map
类型,目的是提供Map
实现类之间的相互转化
1.2 Colleciton
interface
-
说明:
-
该节说明
Collecion
接口中定义哪些基本的方法,这些方法可以进行哪些操作 -
在
Colleciton
定义的方法,由于其他关于collection的实现类继承该接口,所以这些方法一般为通用的
-
-
基本的操作
-
int size()
,boolean isEmpty()
,boolean contains(Object element)
,boolean add(E element)
,boolean remove(Object element)
, andIterator iterator()
-
add方法如果添加成功,则返回true,如果不添加成功,则放回false**(问题:如果元素的对象,应该加入的是对象的地址**),该方法在不同类型的colleciton中会有不同的行为
-
remove方法删除的是当前的元素,(问题:当前元素应该指的是cursor,即光标指定的元素吧),该方法在不同类型的colleciton中会有不同的行为,例如在
List
中remove一个对象,如果这个对象存在多个,那个其删除的规则又是什么? -
对
Collection
进行的遍历的方法有三种:聚合操作,for-each操作和Iterator操作-
//聚合操作 myShapesCollection.stream() .filter(e -> e.getColor() == Color.RED) .forEach(e -> System.out.println(e.getName())); String joined = elements.stream() .map(Object::toString) .collect(Collectors.joining(", ")); int total = employees.stream() .collect(Collectors.summingInt(Employee::getSalary))); //for-each操作 String joined = elements.stream() .map(Object::toString) .collect(Collectors.joining(", ")); //迭代操作 static void filter(Collection<?> c) { for (Iterator<?> it = c.iterator(); it.hasNext(); ) if (!cond(it.next())) it.remove(); } //我们可以看到,在聚合操作和for-each操作对集合进行遍历的期间,不可对集合进行add,remove等操作,但iterator则可以进行remove操作,这样可以进行过滤操作,但注意的是,该remove只能在调用next()方法之后进行调用,其删除的元素是next()返回的那个元素
-
-
-
批操作
containsAll(Collection c)
,boolean addAll(Collection c)
,boolean removeAll(Collection c)
,boolean retainAll(Collection c)
, andvoid clear()
.- retainAll方法是删除两个集合中没有的
- clear方法是删除所有的元素
1.3 Set
interface
-
说明
Set
接口只包含继承来自Collecition
中的方法,但在Add
方法中则加入一下限制,如不能有重复元素,还有在equal
和hashCode
方法中在实现方法上加入一下stronger contact,例如在比较两个List上,只有它们的元素完全相等,才相等- 介绍一下
Set
该类型接口的用途,例如可以进行数论的操作 - 该实现类:
HashSet
,TreeSet
,andLinkedHashSet
-
操作方法的介绍
- s1.addAll(s2),->交集
- s1.retainAll(s2)->并集
- s1.removeAll(s2)->删除s1中交集(s1和s2的交集)
-
用法
//创建集合 Collection<Type> noDups = new HashSet<Type>(c); c.stream() .collect(Collectors.toSet()); // no duplicates //转化为TreeSet Set<String> set = people.stream() .map(Person::getName) .collect(Collectors.toCollection(TreeSet::new)); //注意的是,如果传入进来的colletion中重复的元素(list),在构建set的过程中会自动删除掉重复的元素 //新创建的集合与原本的集合都是存储着对象的链接,所以一个对象元素内容的更改,会导致另一个集合中的相应的对象元素也修改 //数论的操作 Set<Type> symmetricDiff = new HashSet<Type>(s1); //并集 symmetricDiff.addAll(s2); Set<Type> tmp = new HashSet<Type>(s1); //交集 tmp.retainAll(s2); //得出该集合中只包含s1,s2不同时存在的元素 symmetricDiff.removeAll(tmp);
1.4 List
interface
-
说明
- 该
List
接口除了从Colleciton
继承的方法外,还额外定义了一下其他方法- 位置访问:get,set,add,addAll,remove
- search:查找某元素的index,方法有:indexOf,lastIndexOf
- 迭代:listIterator
- Range-view:subList
- 两个List相等的标准:元素相等并且顺序也相同
List
接口的实现类:ArrayList
LinkedList
- 该
-
方法使用
//添加,注意的是add,addAll,其把元素添加到list集合的末尾 list1.addAll(list2); //构建list List<String> list = people.stream() .map(Person::getName) .collect(Collectors.toList()); List<Type> list3 = new ArrayList<Type>(list1); list3.addAll(list2); Person person = new Person("lirisheng",5); List<Person> list = new ArrayList<>(); list.add(person); System.out.println(list.indexOf(person)); list.add(0,new Person("aaa",4)); System.out.println(list.indexOf(person)); System.out.println(list); list.remove(0); System.out.println(list.indexOf(person)); System.out.println(list); //运行结果 //0 //1 //[Person{name='aaa', age=4}, Person{name='lirisheng', age=5}] //0 //[Person{name='lirisheng', age=5}] //结果分析 // lsit中有两个add,一个add(T t),直接加到末尾,另一个add(Int index,T t),加到指定位置 //某一元素在list中的index,不是固定不变的,而是可能随着某操作而改变 //交换 public static <E> void swap(List<E> a, int i, int j) { E tmp = a.get(i); a.set(i, a.get(j)); a.set(j, tmp); }
-
listIterator
-
说明:该接口继承与
Iterator
,并且额外添加了hasPrevious
and theprevious
方法 -
光标cursor(光标指的位置是两个元素之间
-
next
是返回调用next()方法后,其光标cursor之前的元素,而previous则是返回光标之后的元素 -
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jlc0lk0v-1602060161790)(E:\typora\image\image-20200812174955667.png)]
注意:元素的index与cursor的index不一样
-
用法
//注意,listIterator()方法,可以指定初始化光标的位置,如果没有指定,则cursor的index默认为0 //注意,如果用previous,则其光标的index应该为list.size,即指向list集合的末尾 for (ListIterator<Type> it = list.listIterator(list.size()); it.hasPrevious(); ) { Type t = it.previous(); ... }
-
-
rang-view
1.5 Map
interface
-
说明:
- 该接口表示一组键值对,并且其key值不可重复
- 定义的方法
- 基本:
put
,get
,remove
,containsKey
,containsValue
,size
, andempty
- 批操作:
putAll
andclear
- collection views:
keySet
,entrySet
, andvalues
- 基本:
- 实现类(general-porpuse):
HashMap
,TreeMap
, andLinkedHashMap
.
-
用法
// Group employees by department Map<Department, List<Employee>> byDept = employees.stream() .collect(Collectors.groupingBy(Employee::getDepartment)); // Compute sum of salaries by department Map<Department, Integer> totalByDept = employees.stream() .collect(Collectors.groupingBy(Employee::getDepartment, Collectors.summingInt(Employee::getSalary))); // Partition students into passing and failing Map<Boolean, List<Student>> passingFailing = students.stream() .collect(Collectors.partitioningBy(s -> s.getGrade()>= PASS_THRESHOLD)); // Classify Person objects by city Map<String, List<Person>> peopleByCity = personStream.collect(Collectors.groupingBy(Person::getCity)); // Cascade Collectors Map<String, Map<String, List<Person>>> peopleByStateAndCity = personStream.collect(Collectors.groupingBy(Person::getState, Collectors.groupingBy(Person::getCity)))
-
collection view
-
说明:这个概念可以帮助map某些数据映射成
Collection
(但这个应该不是general-porpuse 实现类),进而可以利用Collection
中定义的某些方法,也可以通过利用数论的理论来通过该方法帮助map快速筛选出我们想要得到的map集合 -
方法:
keySet
— theSet
of keys contained in theMap
.values
— TheCollection
of values contained in theMap
. ThisCollection
is not aSet
, because multiple keys can map to the same value.entrySet
— theSet
of key-value pairs contained in theMap
. TheMap
interface provides a small nested interface calledMap.Entry
, the type of the elements in thisSet
.
-
用法:
for (KeyType key : m.keySet()) System.out.println(key); // Filter a map based on some // property of its keys. for (Iterator<Type> it = m.keySet().iterator(); it.hasNext(); ) if (it.next().isBogus()) it.remove();
-