Stream实战用例1

发布时间 2023-11-04 14:35:03作者: 又一个蛇佬腔

Java8 Stream 代码少,功能强大,实乃效率利器。这里我列举自己常用的Stream使用示例。

一.流式赋值

1. 从一个List转到另一个List

参考

objectList = objectList .stream().map(object -> {
             Object objectNew = new Object();
             BeanUtils.copyProperties(object, objectNew);
             objectNew.setVar("Value");
             return objectNew;
             }).collect(Collectors.toList());

2. 简单赋值

// 单个
objectList.forEach(object -> object.setVar("Value"));
// 多个
objectList.forEach(object -> {
    object.setVar("Value");
    object.setVar2("dfsfsd");
});

二.统计计算

参考

// BigDecimal求和
public static void main(String[] args) {

        List<Invoice> invoices = Arrays.asList(
                new Invoice("I1001", BigDecimal.valueOf(9.99), BigDecimal.valueOf(1)),
                new Invoice("I1002", BigDecimal.valueOf(19.99), BigDecimal.valueOf(1.5)),
                new Invoice("I1003", BigDecimal.valueOf(4.888), BigDecimal.valueOf(2)),
                new Invoice("I1004", BigDecimal.valueOf(4.99), BigDecimal.valueOf(5)),
                new Invoice("I1005", BigDecimal.valueOf(.5), BigDecimal.valueOf(2.3))
        );

        //增加非空校验
        BigDecimal sum = invoices.stream()
                .map(x -> x.getQty().multiply(x.getPrice()))    // map
                .filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);      // reduce
        	
        System.out.println(sum);    // 75.851
        System.out.println(sum.setScale(2, RoundingMode.HALF_UP));  // 75.85

}


// 计数
long count = ls.stream().filter(s -> s.length() == 3).count();

3. 自定义Predicate进行复杂逻辑filter

复杂的逻辑过滤,可以写一个谓语判断
 Predicate<TestObject> showIndicatorPre = adjustByCityUtil -> {
            boolean isShow = false;
            BigDecimal score = adjustByCityUtil.getScore();
            BigDecimal benchmarkScore = adjustByCityUtil.getBenchmarkScore();
            String scoreAdjustReason = adjustByCityUtil.getScoreAdjustReason();

            if( score != null) {
                if (benchmarkScore != null) {
                    isShow = !(benchmarkScore.compareTo(score) == 0);
                } else if (StringUtils.isNotBlank(scoreAdjustReason)) {
                    isShow = true;
                }
            }
            return isShow;
        };


        List<TestObject> adjustByCityUtils = entry.getValue();
        if(CollectionUtils.isNotEmpty(adjustByCityUtils)) {
            List<TestObject> collect = adjustByCityUtils.stream().filter(showIndicatorPre).collect(Collectors.toList());
            entry.setValue(collect);
        }
      ...

4.List转Map

@Data
public class Person {

    private Integer idNum;

    private String name;

    private Integer age;
}
List<Person> personList = Arrays.asList(
                new Person(1, "Jack", 3),
                new Person(2, "Mary", 4),
                new Person(3, "Harry", 6),
                new Person(4, "Ali", 6)
        );

// 4.0 只需要List中的两个元素,一个作key,一个为value
Map<Integer,String> testMap = personList .stream()
                .collect(Collectors.toMap(Person::getIdNum, Person::getName));

// List每个元素的key不相同,value是一个列表中的一个元素
Map<String, Person> testMap2 = personList .stream()
.collect(Collectors.toMap(Person::getName, a -> a, (k1, k2) -> k1));

// List中的 key有相同的,value是一个List,将 同Key的进行分组

// 1. 不保持查询顺序的分组
Map<Integer, List<Person>> personSameAgeMap = personList .stream()
.collect(Collectors.groupingBy(Person::getAge));

// 2. 保持查询顺序的分组
使用LinkedHashMap来保证Map中的Key的先后顺序与在List中的先后顺序保持一致
LinkedHashMap<String, List<Person>> personSameAgeMap2= personList.stream()
          .collect(Collectors.groupingBy(Person::getAge, LinkedHashMap::new, Collectors.toList()));

BTW:
List转Map主要是为了搜索匹配方便,从n的复杂度变成1的复杂度。
组织形式变了,但是里面元素还是没变,因此对Map中任何一个元素的值的修改,
都会永久的修改,无论是List,还是在Map中。

5.遍历搜索查看列表中是否有任何一个符合的数据

● filter 搭配 findAny(findFirst) 搭配 isPresent()

    /**
     * 判断每列表中是否有大于6岁的人
     * @param indicatorCityScoreList
     * @return
     */
    private boolean validateAllPersonAgeIsLargerThanTwo(List<Person> personList) {
        Optional<Person> any = personList.stream()
                .filter(i -> (i.getAge() > 6)).findAny();
        if(any.isPresent()) {
            return false;
        }
        return true;
    }

未完待续。。。