Java 8 新特性Stream流+lambda

一、什么是Stream

Stream(流)是一个来自数据源的元素队列并支持聚合操作

  • 元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
  • 数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。
  • 聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。

Stream流中几种经常使用的API:

1.1Filter

public class TestLambda {
    public static void main(String[] args) {
        List<String> strings = Arrays.asList("abc","","bc","efg","abd","");
        List<String> filtered = strings.stream().filter(string->!string.isEmpty()).collect(Collectors.toList());
        System.out.println("集合的大小"+filtered.size());
        for (String s : filtered) {
            System.out.print(s+" ");
        }
    }
}

 由上边的输出结果可以看到,filter的作用就是能够通过filter设置过滤条件去除掉List中的null值或者空值。

1.2Map

public class TestMap {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(3,2,2,3,7,9,5);
        //获取对应的平方数
        List<Integer> squaresList = numbers.stream().map(i->i*i).collect(Collectors.toList());
        for (Integer integer : squaresList) {
            System.out.println("平方后integer = " + integer);
        }
    }
}

map 方法用于映射每个元素到对应的结果,并按照相对应的顺序保存在新的集合中。

1.3limit

public class TestLimit {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(3,2,2,3,7,9,5);
        List<Integer> limitList = numbers.stream().limit(3).collect(Collectors.toList());
        System.out.println("使用过limit后的集合大小"+limitList.size());
    }
}

1.4Sorted

public class TestLimit {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(3,2,2,3,7,9,5);
        List<Integer> sortList = numbers.stream().sorted().collect(Collectors.toList());
        System.out.println("排序后的集合"+sortList);


       //在对象list集合中排序的时候,可以通过某一个属性排序
       List<Transaction> collect = transactions.stream().filter(s -> s.getYear() == 2011).sorted(Comparator.comparing(Transaction::getMount)).collect(Collectors.toList());
//得到的结果是升序排列
        Collections.reverse(collect);//将结果进行倒序排列
        System.out.println("collect = " + collect);
    }
}

 

 1.5Foreach

public class TestLimit {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(3,2,2,3,7,9,5);
        //遍历集合
        numbers.stream().forEach(System.out::println);
    }
}

 代码中的System.out::println,可以这样理解,::前边的是你定义的某个实体类,::后边的是你实体类的某个方法的名字。

1.6skip

public class SkipTest {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(3,2,2,3,7,9,5);
        List <Integer> list1 =  numbers.stream().skip(2).collect(Collectors.toList());//跳过集合元素原本的前两个
        System.out.println("list1 = " + list1);
    }
}

 


 1.7将集合合并

public class ConcatTest {
    public static void main(String[] args) {
        List<String> list1 = new ArrayList<>();
        list1.add("集合1");
        List<String> list2 = new ArrayList<>();
        list2.add("集合2");
        list2.add("集合2");
        //distinct()这个是为了去重
        List<String> collect = Stream.of(list1,list2).flatMap(Collection::stream).distinct().collect(Collectors.toList());
        System.out.println("两个相同类型的集合合并后collect = " + collect);

        //Stream流中的map就是简单的将数据映射,flatmap是将传入的所有流(这里的所有流在这里因为使 
        //用的字符串类型的,所以就是字符串中每一个字符都会变成一个单独的流),最终这些流汇集到一起 
        //再合并为一个流
        //Function.identity()这个是为了保证输入和输出流类型保持一致
        String[] arr = {"数组1"};
        List<String> collect2 =  Stream.of(list1.stream(), Arrays.stream(arr)).flatMap(Function.identity()).collect(Collectors.toList());
        System.out.println("两种不同类型的集合合并后collect2 = " + collect2);
    }
}

 

1.8针对double数据的处理计算平均值

list.stream().mapToDouble(User::getAge).sum()//和
list.stream().mapToDouble(User::getAge).max()//最大
list.stream().mapToDouble(User::getAge).min()//最小
list.stream().mapToDouble(User::getAge).average()//平均值

 在项目中使用的情景

 Stream<Double> doubleStream = worksheetDOS.stream().map(s -> Double.valueOf(s.getHandingTimes()));
//获取到workSheetDOS这个list集合对应的Double数据的stream流
                OptionalDouble average = doubleStream.mapToDouble(Double::doubleValue).average();//Double::doubleValue拿到流中的Double数据

二.项目中用到的Stream流

 TyTaskDO tyTaskDO = tyTaskDOS.stream().filter(t -> StringUtil.equals(t.getTaskStatus(), status)).findFirst().orElse(null);

2.1 findFirst

这个Api是说找到符合条件的集合中第一个元素并返回,如果没有就会使用orelse这个api来返回null

2.2 GroupBy

public class CollectorTest {
    public static void main(String[] args) {
        Product product3 = new Product("啤酒", "a");
        Product product2 = new Product("啤酒", "b");
        Product product = new Product("零食", "c");
        Product product1 = new Product("零食", "d");
        List<Product> productList = new ArrayList<Product>();
        productList.add(product);
        productList.add(product1);
        productList.add(product2);
        productList.add(product3);
        Map<String,List<Product>> proMap = productList.stream().collect(Collectors.groupingBy(Product::getId));
        System.out.println("按照id进行商品的分类");
        for (String s : proMap.keySet()) {
            System.out.println(proMap.get(s));
        }
    }
}

这个APi中的groupby就是按照id对集合中的数据进行分组,得到的一个以id为key的map集合,适用于电商项目中的分类 

三.高级用法

根据关键字去除集合中重复的元素

ArrayList<User> collect1 = users.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(a -> a.getName()))), ArrayList::new));

根据对象中某个最大值查询对应的对象

 User user = users.stream().collect(Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparing(User::getNum)), (Optional<User> us11) ->  us11.orElse(null)));

根据对象中某个最大值查询对应对象的某个属性

String name = users.stream().collect(Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparing(User::getNum)), (Optional<User> user6) -> user6.map(User::getName).orElse(null)));

计算集合中的平均值

users.stream().collect(Collectors.collectingAndThen(Collectors.averagingDouble(User::getNum),Double::doubleValue));

将集合对象的某个属性值以","隔开拼接成字符串

String name = users.stream().map(User::getName).collect(Collectors.joining(","));

判断两个list集合中不同元素有哪些

public static Collection getSameListByMap(Collection collmax, Collection collmin) {
        //使用LinkedList防止差异过大时,元素拷贝
        Collection csReturn = new LinkedList();
        Collection max = collmax;
        Collection min = collmin;
        //先比较大小,这样会减少后续map的if判断次数
        if (collmax.size() < collmin.size()) {
            max = collmin;
            min = collmax;
        }
        //直接指定大小,防止再散列
        Map<Object, Integer> map = new HashMap<Object, Integer>(max.size());
        for (Object object : max) {
            map.put(object, 1);
        }
        for (Object object : min) {
            if (map.get(object) != null) {
                csReturn.add(object);
            }
        }
        return csReturn;
    }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值