简洁高效的数组&集合操作
List & Array
列表初始化
常规方法,一个一个添加,行数比较多
1 | List<String> list = new ArrayList<String>(); |
变种方法,双括号赋值,行数并没减少
第一个大括号是创建了匿名类,第二个大括号是变量初始化块
1 | List<String> list = new ArrayList<String>{{ |
利用Arrays。注意返回的是一个视图,源码上看是返回了ArrayList,但是这并不是集合包内的ArrayList,而是一个内部自定义的类。
因为是视图,本质上还是数组,所以并不能增删,只可原地修改。 这种方法比较适合初始化常量列表。
1 | List<String> list = Arrays.asList("foo","bar"); |
比较变通的方法是再包一层构造函数,创建新的列表
Java7
语法支持菱形符号,可以不指定泛型类型
1 | List<String> list = new ArrayList<>(Arrays.asList("foo","bar")); |
Guava
提供更好的方案,可以直接初始化,同样可以不指定泛型类型
1 | List<String> list = Lists.newArrayList("foo","bar"); |
列表获取第一个
常规方法
1 | if(!list.isEmpty()){ |
Java8
1 | Optional<Object> firstElement = list.stream().findFirst(); |
Guava
1 | String firstElement = Iterables.getFirst(strings, null); |
计数
commons-collections
1 | List<String> list = Arrays.asList('foo','bar','bar','foo','bar'); |
Guava
利用Multiset重复计数功能
1 | Multiset<String> countMap = HashMultiset.create(list); |
数组连接
直接实现需要两步,开辟合并后空间,数组拷贝
1 | String[] result = Arrays.copyOf(first, first.length + second.length); |
Java8
1 | String[] both = Stream.concat(Arrays.stream(a), Arrays.stream(b)) |
Guava
1 | String[] both = ObjectArrays.concat(first, second, String.class); |
数组包含
常规方法,循环判断
1 | for(String s : array) { |
可以转List,再判断
1 | Arrays.asList(array).contains("foo"); |
Java8
可以转Stream
1 | Stream.of(array).anyMatch(x -> x.equals("foo")); |
commons-lang3
的ArrayUtils提供了各种数据类型数组的contains
方法
无需转换额外的结构,直接在原始数组上进行,本质是基于内部indexOf
方法,就是循环判断
1 | ArrayUtils.contains(array, "foo"); |
列表转数组
目标是对象类型数组,可以利用泛型
1 | List<Integer> list = Arrays.asList(1, 2, 3); |
目标是原生类型数组, 无法利用泛型,可以用stream先转换成原生类型
1 | List<Integer> list = Arrays.asList(1, 2, 3); |
Collection
非null添加
常规方法,先判断再添加
1 | if(value != null) { |
commons-collections
1 | CollectionUtils.addIgnoreNull(set, value); |
最值
Java8
1 | Collections.max(map.entrySet(), Map.Entry.comparingByKey()); |
Map
没有时插入
常规方法,先判断有没有,没有再插
1 | if(!map.contains("foo")){ |
Java8
不光解决key不存在的问题,value是null时也会插入
1 | map.putIfAbsent("foo","bar"); |
putIfAbsent
方法适合新值已经现有的情况,如果新值需要根据key计算才能获得,那么如果最后发现不需要,新值计算就浪费了
Java8
还提供compute方法,发现没有再计算
1 | map.computeIfAbsent("foo", k -> "bar"); |
没有时返回默认
常规方法,三元判断
1 | map.contains("foo") ? map.get("foo") : 0; |
Java8
1 | map.getOrDefault("foo", 0); |
新旧值合并
常规方法,先取出旧值再重新插入新值
1 | map.put("foo", map.get("foo") + 1); |
Java8
直接merge还可以额外解决初始值问题
1 | map.merge("foo", 1, Integer::sum); |
版权声明
This site by Linest is licensed under a Creative Commons BY-NC-ND 4.0 International License.
由Linest创作并维护的博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证。
本文永久链接:http://linest.github.io/2017/11/04/java-syntactic-sugar-collection/