集合API改进
java8的Collection API中添加了一些新方法:
Iterator default method forEachRemaining(Consumer action)
为每个元素执行给定操作,直到所有元素都已处理或操作引发异常。
源码
default void forEachRemaining(Consumer<? super E> action) {
//传入一个非空消费者
Objects.requireNonNull(action);
//遍历执行消费者函数
while (hasNext())
action.accept(next());
}
示例代码
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
Iterator<Integer> iterator = list.iterator();
//创建一个消费者
Consumer<Integer> consumer = i -> System.out.println("consumer print " + i);
//iterator的forEachRemaining将集合中的每个元素消费
iterator.forEachRemaining(consumer);
输出结果:
consumer print 1
consumer print 2
consumer print 3
Collection default method removeIf(Predicate 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;
}
示例代码
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
Predicate<Integer> predicate = i -> i > 1;
list.removeIf(predicate);
System.out.println("remove if left items : " + list);
控制台输出:
//2,3,4满足条件被删除了
remove if left items : [1]
Collection spliterator()
返回Spliterator实例的方法,该实例可用于顺序或并行遍历元素。
源码
//该方法是接口默认方法
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, Spliterator.ORDERED);
}
示例代码
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
Spliterator<Integer> spliterator = list.spliterator();
//创建顺序流
Stream<Integer> stream = StreamSupport.stream(spliterator, false);
//创建并行流
Stream<Integer> parallelStream = StreamSupport.stream(spliterator, true);
Map replaceAll(), compute(), merge() methods
replaceAll()
替换Map中所有Entry的value值,这个值由旧的key和value计算得出,接收参数 (K, V) -> V
源码
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
Node<K,V>[] tab;
if (function == null)
throw new NullPointerException();
if (size > 0 && (tab = table) != null) {
int mc = modCount;
for (int i = 0; i < tab.length; ++i) {
for (Node<K,V> e = tab[i]; e != null; e = e.next) {
//使用给定的函数替换原来的value值,key不变
e.value = function.apply(e.key, e.value);
}
}
if (modCount != mc)
throw new ConcurrentModificationException();
}
}
示例代码
Map<String, String> map = new HashMap<>();
map.put("1", "A");
map.put("2", "B");
map.put("3", "C");
map.put("4", "D");
map.put("5", "E");
//replaceAll方法
map.replaceAll((s, s2) -> s + s2);
System.out.println(map);
输出结果:
//原来的value由key + value替换掉了
{1=1A, 2=2B, 3=3C, 4=4D, 5=5E}
compute()
compute方法是computeIfPresent
和computeIfAbsent
方法的组合体
- computeIfPresent:如果指定的key不存在,则通过指定的K -> V计算出新的值设置为key的值。
- computeIfPresent:如果指定的key存在,则根据旧的key和value计算新的值newValue, 如果newValue不为null,则设置key新的值为newValue, 如果newValue为null, 则删除该key的值。
示例代码
Map<String, String> map = new HashMap<>();
map.put("1", "A");
map.put("2", "B");
map.put("3", "C");
map.put("4", "D");
map.put("5", "E");
//key存在,根据旧的key和value计算新的值newValue
map.compute("1", (k, v) -> v + " computed");
System.out.println("key存在" + map.get("1"));
//key不存在,通过指定的K -> V计算出新的值设置为key的值
map.compute("6", (k, v) -> "F");
System.out.println("key不存在" + map.get("6"));
//key存在,如果newValue为null, 则删除该key的值
map.compute("1", (k, v) -> null);
System.out.println("key存在,设置为null " + map.get("1"));
输出结果:
key存在A computed
key不存在F
key存在,设置为null null
merge()
如果指定的key不存在,则设置指定的value值,否则根据key的旧的值oldvalue,value计算出新的值newValue, 如果newValue为null, 则删除该key,否则设置key的新值newValue。
示例代码
Map<String, String> map = new HashMap<>();
map.put("1", "A");
map.put("2", "B");
map.put("3", "C");
map.put("4", "D");
map.put("5", "E");
//存在key为1,输出 Amerge
System.out.println(map.merge("1", "merge", (k, v) -> k + v));
//新值为null,删除key,输出 null
System.out.println(map.merge("1", "merge", (k, v) -> null));
//不存在key为6,输出 "merge"
System.out.println(map.merge("6", "merge", (k, v) -> k + v));
输出结果:
Amerge
null
merge