我是靠谱客的博主 体贴奇异果,这篇文章主要介绍【java集合一】根接口Collection、Map,现在分享给大家,希望可以做个参考。

       Java集合类是一种非常实用的工具类,主要用于保存、盛装其它数据(集合里只能保存对象),因此集合类也被成为容器类。所有的集合类都位于java.util包下,在java.util.concurrent下还提供了一些支持多线程的集合类。Java的集合类主要由两个接口派生而来:Collection和Map,这两个是Java集合框架的根接口。

一、Collection接口


        Collection派生出三个子接口,Set代表不可重复的无序集合、List代表可重复的有序集合、Queue是java提供的队列实现;Collection是最基本的集合接口,它提供了一些通用的方法,供子接口调用。

        Collection源码分析如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// 位于java.util包下 package java.util; import java.util.function.Predicate; // 函数式接口,广泛用在支持lambda表达式的API中 import java.util.stream.Stream; // 数据流接口,定义了众多Stream应该具有的行为 import java.util.stream.StreamSupport; //提供了底层的一些用于操作Stream的方法,如果不需要创建自己的Stream,一般不需要使用它。 // 继承于接口Iterable迭代器,即所有Collection集合体系中的集合类,都可以使用forEach进行循环遍历 public interface Collection<E> extends Iterable<E> { // 1.查询类操作 int size(); // 返回元素个数 boolean isEmpty(); // 判断集合是否为空 boolean contains(Object o); // 判断是否包含元素 o Iterator<E> iterator(); // 返回集合类的迭代器 Object[] toArray(); // 将集合转换为数组 <T> T[] toArray(T[] a); // 转换为具体某一类型的数组 // 2.修改类操作 boolean add(E e); // 往集合中添加元素 e boolean remove(Object o); // 删除元素 o // 3.批量操作 boolean containsAll(Collection<?> c); // 判断 c 是否包含在集合中 boolean addAll(Collection<? extends E> c); // 将 c 中所有元素添加到集合中 boolean removeAll(Collection<?> c); // 移除集合中所包含的 c 中的所有元素 boolean retainAll(Collection<?> c); //移除所有不包含在 c 中的所有元素,即只留下两个集合共有的元素 void clear(); // 清除集合中所有元素 // 删除满足 filter 条件的元素 default boolean removeIf(Predicate<? super E> filter) { Objects.requireNonNull(filter); boolean removed = false; final Iterator<E> each = iterator(); while (each.hasNext()) { if (filter.test(each.next())) { each.remove(); removed = true; } } return removed; } // 4.比较和散列 boolean equals(Object o); // 判断集合和对象 o 是否相等 int hashCode(); // 返回该集合的 hashcode 值 // 重写了 Iterable 接口的 Spliterator 方法 @Override default Spliterator<E> spliterator() { return Spliterators.spliterator(this, 0); } // 在这个集合上返回一个连续的代码流 default Stream<E> stream() { return StreamSupport.stream(spliterator(), false); } // 在这个集合上返回一个并行的代码流 default Stream<E> parallelStream() { return StreamSupport.stream(spliterator(), true); } }

二、Map接口


        Map实现类都用于保存具有映射关系的数据,它们保存的数据都是key-value对,如果要查找Map中的数据,总是根据key来获取,所以key是不可重复的,它用于标识集合里的每项数据。

        Map源码分析如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
// 位于java.util包下 package java.util; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Function; import java.io.Serializable; // 通过实现该接口以启用其序列化功能 // Map 接口, K 为键, V 为值 public interface Map<K,V> { // 1.查询操作 int size(); // 返回元素个数 boolean isEmpty(); // 判断是否为空 boolean containsKey(Object key); // 判断是否包含键 key boolean containsValue(Object value); // 判断是否包含值 value V get(Object key); //返回键 key 对应的值 // 2.修改操作 V put(K key, V value); // 添加元素, 元素为 (key,value) V remove(Object key); // 移除键为 key 的元素 // 3.批量操作 void putAll(Map<? extends K, ? extends V> m); // 将 m 中所有元素添加到集合中 void clear(); // 清空集合 // 4.集合视图 Set<K> keySet(); // 返回 key 的集合视图 Collection<V> values(); // 返回 value 的集合视图 Set<Map.Entry<K, V>> entrySet(); //返回元素 Entry<K,V> 的集合视图 // 集合实体,Map的内部集合,对应Map中的一个元素 interface Entry<K,V> { K getKey(); V getValue(); V setValue(V value); boolean equals(Object o); int hashCode(); public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey() { return (Comparator<Map.Entry<K, V>> & Serializable) (c1, c2) -> c1.getKey().compareTo(c2.getKey()); } public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> comparingByValue() { return (Comparator<Map.Entry<K, V>> & Serializable) (c1, c2) -> c1.getValue().compareTo(c2.getValue()); } public static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp) { Objects.requireNonNull(cmp); return (Comparator<Map.Entry<K, V>> & Serializable) (c1, c2) -> cmp.compare(c1.getKey(), c2.getKey()); } public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp) { Objects.requireNonNull(cmp); return (Comparator<Map.Entry<K, V>> & Serializable) (c1, c2) -> cmp.compare(c1.getValue(), c2.getValue()); } } // 5.比较和散列 boolean equals(Object o); // 判断集合和对象 o 是否相等 int hashCode(); // 返回该集合的 hashcode 值 // 6.JDK8出现的新方法 - default新特性 default V getOrDefault(Object key, V defaultValue) { V v; return (((v = get(key)) != null) || containsKey(key)) ? v : defaultValue; } default void forEach(BiConsumer<? super K, ? super V> action) { Objects.requireNonNull(action); for (Map.Entry<K, V> entry : entrySet()) { K k; V v; try { k = entry.getKey(); v = entry.getValue(); } catch(IllegalStateException ise) { // this usually means the entry is no longer in the map. throw new ConcurrentModificationException(ise); } action.accept(k, v); } } default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { Objects.requireNonNull(function); for (Map.Entry<K, V> entry : entrySet()) { K k; V v; try { k = entry.getKey(); v = entry.getValue(); } catch(IllegalStateException ise) { // this usually means the entry is no longer in the map. throw new ConcurrentModificationException(ise); } // ise thrown from function is not a cme. v = function.apply(k, v); try { entry.setValue(v); } catch(IllegalStateException ise) { // this usually means the entry is no longer in the map. throw new ConcurrentModificationException(ise); } } } default V putIfAbsent(K key, V value) { V v = get(key); if (v == null) { v = put(key, value); } return v; } default boolean remove(Object key, Object value) { Object curValue = get(key); if (!Objects.equals(curValue, value) || (curValue == null && !containsKey(key))) { return false; } remove(key); return true; } default boolean replace(K key, V oldValue, V newValue) { Object curValue = get(key); if (!Objects.equals(curValue, oldValue) || (curValue == null && !containsKey(key))) { return false; } put(key, newValue); return true; } default V replace(K key, V value) { V curValue; if (((curValue = get(key)) != null) || containsKey(key)) { curValue = put(key, value); } return curValue; } default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) { Objects.requireNonNull(mappingFunction); V v; if ((v = get(key)) == null) { V newValue; if ((newValue = mappingFunction.apply(key)) != null) { put(key, newValue); return newValue; } } return v; } default V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { Objects.requireNonNull(remappingFunction); V oldValue; if ((oldValue = get(key)) != null) { V newValue = remappingFunction.apply(key, oldValue); if (newValue != null) { put(key, newValue); return newValue; } else { remove(key); return null; } } else { return null; } } default V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { Objects.requireNonNull(remappingFunction); V oldValue = get(key); V newValue = remappingFunction.apply(key, oldValue); if (newValue == null) { // delete mapping if (oldValue != null || containsKey(key)) { // something to remove remove(key); return null; } else { // nothing to do. Leave things as they were. return null; } } else { // add or replace old mapping put(key, newValue); return newValue; } } default V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) { Objects.requireNonNull(remappingFunction); Objects.requireNonNull(value); V oldValue = get(key); V newValue = (oldValue == null) ? value : remappingFunction.apply(oldValue, value); if(newValue == null) { remove(key); } else { put(key, newValue); } return newValue; } }

三、defalut 扩展方法(JDK8新特性)

        与以前的集合类相比,JDK8的新特性之一就是提供了很多 default 方法,这些方法拥有具体的实现,子类可以直接调用这些方法的默认实现。defalut方法对Java集合API进行了优化升级,并且在JDK与Lambda表达式的结合中起到了至关重要的作用。

示例1:

        A 接口中定义了一个 hello() 方法,B 类实现 A 接口,则 B 默认实现了 A 中的 hello() 方法

复制代码
1
2
3
4
5
6
// A 接口中定义了一个用defalut修饰的 hello 方法 public interface A { default void hello(){ System.out.println("调用 A 接口的 hello() "); } }
复制代码
1
2
// B 类实现 A 接口 public class B implements A {}
复制代码
1
2
3
4
5
6
public class defaultTest { public static void main(String[] args) { B b = new B(); b.hello(); // B 类调用了 A 接口中 hello() 方法的默认实现 } }


示例2:

        A 接口中定义了一个 defaul 修饰的 hello() 方法,B 接口中也有一个 defaul 修饰的 hello() 方法,defaulTest 同时实现 A、B 接口,则 defaultTest中必须重写 hello() 方法,否则报错

复制代码
1
2
3
4
5
public interface A { default void hello(){ System.out.println("调用 A 接口的 hello() "); } }
复制代码
1
2
3
4
5
public interface B { default void hello(){ System.out.println("调用 B 接口的 hello() "); } }
复制代码
1
2
3
4
5
6
7
8
9
10
11
public class defaultTest implements A,B{ public void hello(){ System.out.println("调用 dafultTest 接口的 hello() "); // 调用自身hello方法 A.super.hello(); // A 接口的 hello 方法 B.super.hello(); // B 接口的 hello 方法 } public static void main(String[] args) { defaultTest test = new defaultTest(); test.hello(); } }
        接口一般没有方法的具体实现,而java又是一种单继承语言,JDK8中加入的这种新特性,不知道算不算在变相的实现多继承。。。

最后

以上就是体贴奇异果最近收集整理的关于【java集合一】根接口Collection、Map的全部内容,更多相关【java集合一】根接口Collection、Map内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(54)

评论列表共有 0 条评论

立即
投稿
返回
顶部