JDK8新特性(Stream流)

52 篇文章 0 订阅

一、Stream流的概念
Stream 是Java8中处理集合的关键抽象概念,它可以对集合进行非常复杂的查找、过滤、筛选等操作,在新版的JPA【连接数据库】中,也已经加入了Stream 。

二、为什么要使用Stream流?
        每当我们需要对集合中的元素进行操作的时候,总是需要进行循环、循环、再循环。这是理所当然的么?不是。循环 是做事情的方式,而不是目的。每个需求都要循环一次,还要搞一个新集合来装数据,如果希望再次遍历,只能再使 用另一个循环从头开始。Stream能给我们带来更加优雅的写法, Stream API给我们操作集合带来了强大的功用,同时Stream API操作简单,容易上手。 对集合的操作语法简洁:性能比传统快。

三、Stream流的原理
注意:Stream和IO流(InputStream/OutputStream)没有任何关系,请暂时忘记对传统IO流的固有印象!

Stream流式思想类似于工厂车间的“生产流水线”,Stream流不是一种==数据结构==,==不保存数据==,而是对数据进行==加工 处理==。Stream可以看作是流水线上的一个工序。在流水线上,通过多个工序让一个原材料加工成一个商品。

四、获取Stream流对象

 public static void main(String[] args) {
        //1.通过List集合对象调用stream
        List<String> list=new ArrayList<>();
        list.add("刘能");
        list.add("赵四");
        list.add("谢广坤");
        Stream<String> stream = list.stream();
        //2.通过数组类的stream方法
        int[] num ={1,2,3,4,5};
        IntStream stream1 = Arrays.stream(num);
        //3.通过stream类的of方法
        Stream<String> stringStream = Stream.of("张三", "李四", "王五", "赵六");
        //4.
        //上面都是获取的串行流。还可以获取并行流。如果流中的数据量足够大,并行流可以加快处速度。
        Stream<String> stringStream1 = list.parallelStream();
 
 
    }

 

五、 Stream流中常见的api
Stream有如下三个操作步骤:

一、创建Stream

从一个数据源,如集合、数组中获取流。

二、中间操作

一个操作的中间链,对数据源的数据进行操作。

中间操作api: 一个操作的中间链,对数据源的数据进行操作。而这种操作的返回类型还是一个Stream对象。

三、终止操作

一个终止操作,执行中间操作链,并产生结果。

终止操作api: 一个终止操作,执行中间操作链,并产生结果,返回类型不在是Stream流对象。
 

Stream中间操作
1.筛选,filter:接收Lambda,从流中排除某些操作;

 //创建流对象
        personList.stream()
                .filter(iteam->iteam.getAge()>20)//过滤掉年龄小于20岁,中间操作
                .forEach(System.out::println);//循环输出,终止操作


2.distinct: 筛选去重,通过流所生成元素的hashCode()和equals()去除重复元素。

//2.交易员都在哪些不同的城市工作过?
        transactions.stream().map(iteam->iteam.getTrader().getCity())
                .distinct()//去除重复
                .forEach(System.out::println);


3. 映射,map:接收Lambda,将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
 

//创建流对象
        personList.stream().map(iteam->{
            Map map=new HashMap();
            map.put("name", iteam.getName());
            map.put("age",  iteam.getAge());
            return map;
        }).forEach(System.out::println);

 

4.排序,sorted:

sorted()--自然排序(Comparable)

sorted(Comparator com)--定制排序(Comparator)

 personList.stream()
                .sorted(((o1, o2) -> o1.getAge()-o2.getAge()))//根据年龄排序
                .forEach(System.out::println);


 根据字符串首字母排序:

transactions.stream()
                .map(iteam->iteam.getTrader().getName())
                .sorted((o1, o2) -> o1.substring(0,1).compareTo(o2.substring(0,1)))//截取第一个字符进行比较
                .distinct()
                .forEach(System.out::println);

Stream终止操作
1.查找与排序:

allMatch--检查是否匹配所有元素

anyMatch--检查是否至少匹配一个元素

noneMatch--检查是否没有匹配所有元素

findFirst--返回第一个元素

findAny--返回当前流中的任意元素

count--返回流中元素的总个数

max--返回流中最大值

min--返回流中最小值


 

 //字符串长度最大的
Optional<Person> max = personList.stream().max(((o1, o2) -> o1.getName().length() - o2.getName().length()));
        System.out.println(max);
//第一个出现的
        Optional<Person> first = personList.stream()
                .filter(iteam -> iteam.getAge() > 20)
                .filter(iteam -> iteam.getSex() == 'F')
                .findFirst();
        System.out.println(first);

 match:

//5.有没有交易员是在米兰工作的?
        //allmatch:全部元素都与条件都匹配
        //anymatch:任意一个元素与条件匹配
        //notmatch:没有一个元素与我们的条件匹配
        boolean b = transactions.stream()
                .anyMatch(iteam -> iteam.getTrader().getCity().equals("Milan"));
        System.out.println("有没有交易员在米兰工作:"+b);

2.规约,reduce:Stream API的归约操作可以将流中元素反复结合起来,得到一个值

//求出所有年龄的和
        Optional<Integer> reduce = personList.stream()
                .map(iteam -> iteam.getAge())
                .reduce((a, b) -> a + b);
        System.out.println(reduce.get());

 3.收集,collect:将流转换为其他形式,接收一个Collector接口实现 ,用于给Stream中汇总的方法

//搜集collect match
        //年龄大于20且为F
        List<Person> collect = personList.stream()
                .filter(iteam -> iteam.getAge() > 20)
                .filter(iteam->iteam.getSex()=='F')
                .collect(Collectors.toList());
        System.out.println(collect);

练习题:

    //交易员类
    public static class Trader {
        private final String name;
        private final String city;
 
        public Trader(String name, String city) {
            this.name = name;
            this.city = city;
        }
 
        public String getName() {
            return name;
        }
 
        public String getCity() {
            return city;
        }
 
        @Override
        public String toString() {
            return "Trader{" +
                    "name='" + name + '\'' +
                    ", city='" + city + '\'' +
                    '}';
        }
    }
 //交易记录
    public static class Transaction {
        private final Trader trader;
        private final int year;
        private final int value;
        public Transaction(Trader trader, int year, int value){
            this.trader = trader;
            this.year = year;
            this.value = value;
        }
        public Trader getTrader(){
            return this.trader;
        }
        public int getYear(){
            return this.year;
        }
        public int getValue(){
            return this.value;
        }
        public String toString(){
            return "{" + this.trader + ", " +
                    "year: "+this.year+", " +
                    "value:" + this.value +"}";
        }
    }
Trader raoul = new  Trader("Raoul", "Cambridge");
        Trader mario = new Trader("Mario", "Milan");
        Trader alan = new Trader("Alan", "Cambridge");
        Trader brian = new Trader("Brian", "Cambridge");
        List<Transaction> transactions = Arrays.asList(
                new Transaction(brian, 2011, 300),
                new Transaction(raoul, 2012, 1000),
                new Transaction(raoul, 2011, 400),
                new Transaction(mario, 2012, 710),
                new Transaction(mario, 2012, 700),
                new Transaction(alan, 2012, 950)
        );

(1) 找出2011年发生的所有交易,并按交易额排序(从低到高)。
(2) 交易员都在哪些不同的城市工作过?
(3) 查找所有来自于剑桥的交易员,并按姓名排序。
(4) 返回所有交易员的姓名字符串,按字母顺序排序。
(5) 有没有交易员是在米兰工作的?
(6) 打印生活在剑桥的交易员的所有交易额。
(7) 所有交易中,最高的交易额是多少?
(8) 找到交易额最小的交易。

答案:

//1.找出2011发生的所有交易,交易额从低到高排序
        transactions.stream()
                .filter(iteam->iteam.getYear()==2011)
                .sorted((o1, o2) -> o1.getValue()-o2.getValue())
                .forEach(System.out::println);
        //2.交易员都在哪些不同的城市工作过?
        transactions.stream().map(iteam->iteam.getTrader().getCity())
                .distinct()//去除重复
                .forEach(System.out::println);
        //3.查找所有来自于剑桥的交易员,并按姓名排序。
        transactions.stream()
                .filter(iteam->iteam.getTrader().getCity().equals("Cambridge"))
                .sorted((o1, o2) -> o1.getTrader().getName().length()-o2.getTrader().getName().length())
                .forEach(System.out::println);
        //4.返回所有交易员的姓名字符串,按字母顺序排序  //compareTo
        transactions.stream()
                .map(iteam->iteam.getTrader().getName())
                .sorted((o1, o2) -> o1.substring(0,1).compareTo(o2.substring(0,1)))//截取第一个字符进行比较
                .distinct()
                .forEach(System.out::println);
        //5.有没有交易员是在米兰工作的?
        //allmatch:全部元素都与条件都匹配
        //anymatch:任意一个元素与条件匹配
        //notmatch:没有一个元素与我们的条件匹配
        boolean b = transactions.stream()
                .anyMatch(iteam -> iteam.getTrader().getCity().equals("Milan"));
        System.out.println("有没有交易员在米兰工作:"+b);
        //6.打印生活在剑桥的交易员的所有交易额
        Optional<Integer> milan = transactions.stream()
                .filter(iteam -> iteam.getTrader().getCity().equals("Cambridge"))
                .map(iteam -> iteam.getValue())
                .reduce((a, c) -> a + c);
        System.out.println("生活在剑桥的交易员的所有交易额"+milan.get());
        //7.所有交易中,最高的交易额是多少?
        Optional<Integer> max = transactions.stream()
                .map(iteam->iteam.getValue())
                .max((o1, o2) ->o1-o2);
        System.out.println("最高的交易额为:"+max.get());
        //8.找到交易额最小的交易
        Optional<Transaction> min = transactions.stream()
                .min((o1, o2) -> o1.getValue() - o2.getValue());
        System.out.println("交易额最小的交易为:"+min.get());


————————————————
版权声明:本文为CSDN博主「Have_MonkeyG」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Have_MonkeyG/article/details/125906861

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值