记录一下使用Java Stream流解决部分问题的过程。
- 获取实体类的name属性在nameList集合中的第一个实体类对象。
// 目标nameList
List<String> nameList = new ArrayList<>();
nameList.add("dames");
nameList.add("dames1");
List<TestEntity> list = new ArrayList<>();
list.add(TestEntity.builder().name("dames").build());
list.add(TestEntity.builder().name("dames1").build());
list.add(TestEntity.builder().name("dames2").build());
list.add(TestEntity.builder().name("dames3").build());
// 对象需要用Optional容器接收
Optional<TestEntity> first = list.stream().filter(item -> nameList.contains(item.getName())).findFirst();
- 筛选出map集合中第一个key对应的value,这个key需要满足的是某字符串以它开头。
// 保存k-v映射关系的map
Map<String, String> map = new HashMap<>();
map.put("omada.iot", "iot");
map.put("test", "value2");
map.put("omada", "omada");
// 目标字符串
String prefix = "omada.iot";
// 找到一个符合目标字符串以key开头的对应的value
String firstMatch = map.entrySet().stream()
.filter(entry -> prefix.startsWith(entry.getKey())).findFirst()
// Map.Entry映射为String
.map(Map.Entry::getValue).orElse(null);
- 数据累加。 reduce()方法可以将流元素聚合为单个结果。它接受一个BinaryOperator参数作为累加器。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> sum = numbers.stream().reduce(Integer::sum);
- 判断某集合中是否存在某值,该值满足的是某字符串以它开头。
List<String> list1 = new ArrayList<>();
list1.add("omada");
list1.add("iot");
list1.add("test");
String str = "omada.iot";
boolean anyMatch = list1.stream().anyMatch(str::startsWith);
- 分组操作。Collectors.groupingBy,它接受一个分类器函数,根据该函数的结果将元素进行分组,返回一个Map类型的结果,其中键是分类器函数的结果,值是分组的元素集合。
List<String> fruits = Arrays.asList("apple", "banana", "orange", "grape");
Map<Character, List<String>> groupedFruits = fruits.stream()
.collect(Collectors.groupingBy(s -> s.charAt(0)));
// {a=[apple], b=[banana], g=[grape], o=[orange]}
- 分区操作。Collectors.partitioningBy,将流中的元素根据指定的条件进行分区,分区的结果是一个
Map<Boolean, List<T>>
,其中true
对应满足条件的元素集合,false
对应不满足条件的元素集合。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Map<Boolean, List<Integer>> partitionedNumbers = numbers.stream()
.collect(Collectors.partitioningBy(n -> n % 2 == 0));
// {false=[1, 3, 5, 7, 9], true=[2, 4, 6, 8, 10]}
- 使用流更新多层Map;比如要实现给多层Map中最里层的每个元素都实现+1的操作。
public class Test111 {
@Test
void Test1() {
Map<String, Map<String, Map<String, BigDecimal>>> testMap = new HashMap<>();
Map<String, BigDecimal> map1 = new HashMap<>();
map1.put("test", new BigDecimal(1));
map1.put("test2", new BigDecimal(2));
map1.put("test3", new BigDecimal(2));
Map<String, BigDecimal> map2 = new HashMap<>();
map2.put("test", new BigDecimal(1));
map2.put("test2", new BigDecimal(2));
map2.put("test3", new BigDecimal(2));
Map<String, BigDecimal> map3 = new HashMap<>();
map3.put("test", new BigDecimal(1));
map3.put("test2", new BigDecimal(2));
map3.put("test3", new BigDecimal(2));
Map<String, Map<String, BigDecimal>> mapHashMap = new HashMap<>();
mapHashMap.put("11", map1);
mapHashMap.put("22", map2);
mapHashMap.put("33", map3);
testMap.put("test", mapHashMap);
System.out.println(testMap);
// {test={11={test2=2, test3=2, test=1}, 22={test2=2, test3=2, test=1}, 33={test2=2, test3=2, test=1}}}
updateMapValues(testMap);
// 打印更新后的testMap
System.out.println(testMap);
// {test={11={test2=3, test3=3, test=2}, 22={test2=3, test3=3, test=2}, 33={test2=3, test3=3, test=2}}}
}
private void updateMapValues(Map<String, Map<String, Map<String, BigDecimal>>> map) {
map.forEach((outerKey, outerValue) ->
outerValue.forEach((middleKey, middleValue) ->
middleValue.replaceAll((innerKey, innerValue) -> innerValue.add(BigDecimal.ONE))));
}
}