Java8 集合新增的API

By | 六月 5, 2016

1. Arrays类

1.1 parallelSort,并发排序

对于原始数值类型数组直接进行排序,输入一个数组,第二和第三个参数可选,用于指定数组的某一段。原始数值类型包括:byte, char, short, int, long, float, double。

int[] nums = {9, 3, 7, 1};
Arrays.parallelSort(nums);

char[] chars = {'z', 'f', 'a'};
Arrays.parallelSort(chars);

普通的对象数组,如果对象实现了Comparable接口,可以像上面那样使用parallelSort。如果对象元素没有实现comparable接口,则需要提供一个Comparator对象。

Session[] sessions = {new Session(5), new Session(2), new Session(4)};
Arrays.parallelSort(sessions, Comparator.comparing(Session::getId));
Arrays.parallelSort(sessions, 0, sessions.length, Comparator.comparing(Session::getId));

1.2 parallelPrefix,array[n] = f(array[n-1], array[n])

从第二个元素起,每个元素是由当前元素和前一个元素转换生成的。依次类推,直到最后一个元素。输入可以是int, long, double类型的数组,或者任意对象类型的数组。

int[] nums = {1, 2, 3, 4, 5};
Arrays.parallelPrefix(nums, (x, y) -> x + y);
// nums: [1, 3, 6, 10,15]

// Merge materials.
Material[] materials = ...;
Arrays.parallelPrefix(materials, Material::merge);
// Only the last element contains all the materials.

P.S. 另外两个Optional参数,fromIndex和toIndex用于指定数组的一段,对局部数组进行操作。

1.3 setAll, array[n] = f( n )

对数组的每个元素重新赋值,值由函数f( n )生成,n是该元素在数组中的索引。

// Key: session id; Value: Session
Map<Integer, Session> idToSessionMap = null;
// Session id array.
int[] ids = {4, 5, 9};

Arrays.setAll(ids, index -> {
  Session session = idToSessionMap.get(ids[index]);
  return session.lastModifyTime();
});
// The array (ids) stores each session's last modify time.

支持int, long, double,以及对象类型的数组。如果转换函数是可并发的,可以使用parallelSetAll,进行并发赋值。

2. List类

2.1 replaceAll, element = f(element)

对每一个元素,进行一个转换(执行一个函数),转换后的结果作为新元素。

List<String> strs = Lists.newArrayList("Spring", "Summer", "Autumn", "Winter");
strs.replaceAll(str -> str + ":" + str.length());
// [Spring:6,Summer:6,Autumn:6,Winter:6]

2.2 sort,排序

底层实现是:先转换成数组,对数组应用Arrays.sort()方法,再把排序后的元素依次填充给list。

List<String> strs = Lists.newArrayList("Spring", "Summer", "Autumn", "Winter");
strs.sort(Comparator.comparing(str -> str.charAt(0)));
// [Autumn, Spring, Summer, Winter]

3. Set类

没有新增的方法。

4. Map类

4.1 putIfAbsent(key, value)

仅当key不存在时,添加该键值对;如果key存在,不执行任何操作。返回Map中该key的最新value。

4.2 replace(key, oldValue, newValue)

将键值对<key, oldValue>中的oldValue替换成newValue。如果该键值对不存在,不执行任何操作。返回boolean,表示是否replace成功。

4.3 replace(key, value)

将map中key所对应的值,替换成当前给的value。如果key不存在,不执行任何操作。返回Map中该key的最新value。

4.4 replaceAll(BiFunction<key, value, value>)

替换所有键值对的Value,替换规则有输入的BiFunction指定。

4.5 merge(key, value, BiFunction)

如果Map中不存在该key,相当于Map.put(key, value);如果Map中存在该Key,则会执行BiFunction.apply(oldValue, value)方法,生成一个mergedValue。

Map<String, String> map = Maps.newHashMap();
map.putIfAbsent("China", "Beijing Hua");
map.replace("China", "Beijing Hua", "Shanghai Hua");
map.replace("China", "Mandarin");
map.replaceAll((k, v) -> v + " Language");
map.merge("China", "English", 
    (oldValue, newValue) -> newValue + " and " + oldValue);
//Output: <"China", "English and Mandarin Language">

4.6 compute(key, BiFunction)

BiFunction.apply(key, oldValue): newValue, 根据当前key及其value,计算一个新的value,然后加入Map中。不管key是否存在,只要BiFunction返回的值不为null,<key, newValue>都会被加入到Map中。Example, Map的key是水果名字,value是个数。

Map<String, Integer> map = Maps.newHashMap();
map.put("apple", 1);
map.compute("apple", (key, value) -> {
  if (map.containsKey(key)) {
    return value + 1;
  } else {
    return 1;
  }
});

4.7 computeIfAbsent和computeIfPresent

computeIfAbsent仅当Map不包含该key是执行,而computeIfPresent仅当Map包含该key时执行。上面code等价写法如下:

Map<String, Integer> map = Maps.newHashMap();
map.computeIfAbsent("apple", (key) -> 1);
map.computeIfPresent("apple", (key, value) -> value + 1);

4.8 getOrDefault(key, defaultValue)

当Map存在该Key时,返回改key的value;否则返回defaultValue。

4.9 forEach(BiConsumer)

遍历整个Map。Example:

Map<String, Integer> map = Maps.newHashMap();
map.put("apple", 2);
map.put("orange", 5);
Logger.getGlobal().info("Orange nummber: " 
    + map.getOrDefault("orange", 0));
map.forEach((key, value) -> {
  System.out.println("Key=" + key + ", value=" + value);
});