Java8 Stream流常用方法(持续更新)

Stream流的应用

插入一个题外知识:Optional类

1、去重

1、按照对象的某个属性去重

1)借助工具类实现

//去重工具类
public class StreamEx {
    public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }
}
//实现,result类型为List>,后文同,不再复述
result = list.stream().filter(StreamEx.distinctByKey(x -> x.get("code"))).collect(Collectors.toList());

2)普通去重

result = list.stream().collect(
        Collectors.collectingAndThen(
                Collectors.toCollection(
                        () -> new TreeSet<>(
                                Comparator.comparing(e -> e.get("accountCount"))
                        )), ArrayList::new));

2、按照对象的多个属性去重

//根据list对象的ruleCode,和version去重
result = list.stream().collect(
        Collectors.collectingAndThen(
                Collectors.toCollection(
                        () -> new TreeSet<>(Comparator.comparing(e -> e.get("ruleCode")  + "#" + e.getString("version")))), ArrayList::new));

2、提取某个字段成为新的list

// 数据说明:data类型为List>
// 功能说明:提取data中的bizCode字段成为一个新的list,且避免了空指针问题
List<String> bizCodeList = Optional.ofNullable(data.getString("bizCode"))
        .map(bizCode -> Arrays.asList(bizCode.split(",")))
        .orElse(Collections.emptyList());

3、字段求和

// 数据说明:data类型为List>,bizCodeList为List
// 功能说明:去除esData集合中各条属性不包含于bizCodeList的数据,然后将剩下的数据取出transCnt字段进行累加求和,如果transCnt字段为空则赋值0
int totalTransCnt = data.stream()
        .filter(es -> bizCodeList.contains(es.getString("bizCode")))
        .mapToInt(es -> Optional.ofNullable(es.getInteger("transCnt")).orElse(0))
        .sum();

4、求最大/最长/最小/最短/符合条件个数

// 求list中最长的元素(最短把max换成min即可,下面相同)
List<String> list1 = Arrays.asList("tigger", "lion", "dog", "panda", "giraffe");
Optional<String> maxLength = list1.stream().max(Comparator.comparing(String::length));
System.out.println("list中最长的元素为:" + maxLength.get());
// 求list中最大的元素
List<Integer> list2 = Arrays.asList(1, 5, 10, 9, 102, 58);
Optional<Integer> max = list2.stream().max(Comparator.comparing(Integer::intValue));
System.out.println("list中最大的元素为:" + max.get());
// 求list中比5大的个数
long count = list2.stream().filter(e -> e > 5).count();
System.out.println("list比5大的元素个数有:" + count + "个");

5、求和、求乘积、求最值

// list类型List>
// 求和、求乘积、求最值
Optional<Integer> sum1 = list.stream().map(e -> e.getInteger("salary")).reduce((a, b) -> a + b);
Optional<Integer> sum2 = list.stream().map(e -> e.getInteger("salary")).reduce(Integer::sum);
Optional<Integer> product = list.stream().map(e -> e.getInteger("salary")).reduce((x, y) -> x * y);
Optional<Integer> max1 = list.stream().map(e -> e.getInteger("salary")).reduce(Integer::max);
Optional<Integer> max2 = list.stream().map(e -> e.getInteger("salary")).reduce((x, y) -> x > y ? x : y);

6、排序

//数据说明:data为List>,QueryData为Map
//升序
data.stream().sorted(Comparator.comparing(e -> e.getInteger("count"), Comparator.naturalOrder())).collect(Collectors.toList());
//降序
data.stream().sorted(Comparator.comparing(e -> e.getInteger("count"), Comparator.reverseOrder())).collect(Collectors.toList());

//多字段排序 如果无法推断e类型的情况下,需要手动指定类型,如下面的QueryData,否则会报错:无法解析 'Object' 中的方法 'getXXXXX'
queryData = queryData.stream().sorted(Comparator.comparing((QueryData e) -> e.getInteger("transNum")).reversed().thenComparing(e -> e.getString("createAt"), Comparator.reverseOrder())).collect(Collectors.toList());

你可能感兴趣的:(Java进阶自学笔记,java,jvm,servlet)