栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

强大的Stream API总汇

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

强大的Stream API总汇

目录

Stream介绍

流(Stream)到底是什么

 Stream操作的步骤

创建流Stream的四种方式

Stream中间操作

筛选与切片

映射 

 排序

 Stream终止操作

查找与匹配 

 归约

  收集


Stream介绍

Stream是Java8中处理集合的关键抽象概念。

Stream API对集合数据进行操作,类似于使用SQL执行的数据库查询。也可以使用Stream API来并行执行操作。简而言之它提供了一种高效且易于使用处理数据的方式。

流(Stream)到底是什么

是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。

集合讲的是数据,流讲的是计算

注意:

        Stream不会自己存储元素。

        Stream不会改变源对象。相反,他们会返回一个持有结果的新Stream。

        Stream操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

 Stream操作的步骤

创建Stream:一个数据源,获取一个流。

中间操作:对数据源的数据进行处理。

终止操作:执行中间操作链并产生结果。

创建流Stream的四种方式
方式一: 通过Collection系列集合提供的Stream()或parallelStream()
 List list = new ArrayList<>();
        Stream stream1 = list.stream();
方式二:通过Arrays中的静态方法Stream()获取数组流
Employee[] emps = new Employee[20];
        Stream stream2 = Arrays.stream(emps);
方式三:  通过Stream类中的静态方法of()
Streamstream3 = Stream.of("aa","bb");
 方式四:   创建无限流:迭代/生成(迭代:一个数加三,限制数量10个
                                  生成:生成不限量随机数)
   Stream stream4 = Stream.iterate(0,(x)->x+3);
        stream4.limit(10).forEach(System.out::println);
//        创建无限流,生成
Stream.generate(()->Math.random())
       .forEach(System.out::println);

Stream中间操作

多个中间操作可以连接起来形成一个流水线,除非流水线触碰终止操作,否则中间操作不会做任何处理,而在终止操作时一次性全部处理,称为“惰性求值”。

中间操作主要涉及方面 

   筛选与切片 、映射、排序。

筛选与切片

主要方法:

filter - 接收lambda,从流中排除某些元素。

limit - 截断流,使其元素不超过给定的数量。

skip(n)- 跳过元素,返回一个扔掉了前n个元素的流,若流中的元素不足n个,则返回一个空流,与limit(n)互补。

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

示例1:

创建Employee(属性 name age salary)

public interface ShaiXuanYuQiePian {
    public static void main(String[] args) {
        List list = Arrays.asList(
                new Employee("张三",18,9999),
                new Employee("赵四",58,8888),
                new Employee("王五",26,7777),
                new Employee("赵六",36,5555),
                new Employee("田七",17,33333),
        new Employee("田七",17,33333 )

        );
//        内部迭代:迭代器由Stream API完成
//        排除<35岁的
        Stream s = list.stream()
                .filter((e)->e.getAge()>35);
//        终止操作
        s.forEach(System.out::println);
        System.out.println("-------------------------------");
//        外部迭代:按顺序迭代每一个元素
        Iterator it = list.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }
        System.out.println("------------------------------");
//        排除工资<5000的,并且只显示2个人的信息
        list.stream()
                .filter((e)->e.getSalary()>5000)
                .limit(2)
                .forEach(System.out::println);
        System.out.println("------------------------------");
//        排除工资<5000的并跳过前两个人的信息
        list.stream()
                .filter((e)->e.getSalary()>5000)
                .skip(2)
                .forEach(System.out::println);
        System.out.println("------------------------------");
//           排除工资<5000的并跳过前两个人的信息,并除去重复信息
        list.stream()
                .filter((e)->e.getSalary()>5000)
                .skip(2)
                .distinct()
                .forEach(System.out::println);

    }

}

映射 

主要方法

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

flatMap - 接受一个函数作为参数,将流中的每个值都换成另一个流,然后把所有的流连接成一个流。

示例2:

public class YingShe {
    public static void main(String[] args) {
        List list = Arrays.asList(
                new Employee("张三",18,9999),
                new Employee("赵四",58,8888),
                new Employee("王五",26,7777),
                new Employee("赵六",36,5555),
                new Employee("田七",17,33333)
        );
        List list1 = Arrays.asList("aaa","bbb","ccc","ddd","eee");
//       将流中灭个元素的小写都换为大写
        list1.stream()
                .map((str)->str.toUpperCase(Locale.ROOT))
                .forEach(System.out::println);
        System.out.println("--------------------------");
//获取所有姓名
        list.stream()
                .map(Employee::getName)
                .forEach(System.out::println);
        System.out.println("-------------------------");
     
//        获取流中字符串的每一元素
//map返回一个流1Stream,流中保存的事流2Stream{流1{流2a,a,a},{流2b,b,b}}
        Stream> stream =list1.stream()
                .map(YingShe::filterCharacter);
        stream.forEach((sm)->sm.forEach(System.out::print));
        System.out.println("------------------------");
        
//       方法二:代替上述map{a,a,a,b,b,b}
        Stream sm = list1.stream()
                .flatMap(YingShe::filterCharacter);
        sm.forEach(System.out::print);

    }

//    Character:对单个字符进行操作 Stream将字符串提取出来转换成流
    public static Stream filterCharacter(String str){
        Listlist = new ArrayList<>();
//        toCharArray() 方法将字符串转换为字符数组
        for(Character ch: str.toCharArray()){
            list.add(ch);
        }
        return list.stream();
    }
}

 排序

主要方法

sorted - 自然排序

sorted(Comparator com)-定制排序

示例3:

如果年龄相等就按照姓名排,否则按照年龄排

public class Paixu {
    public static void main(String[] args) {
        List list = Arrays.asList(
                new Employee("张三",18,9999),
                new Employee("赵四",58,8888),
                new Employee("王五",26,7777),
                new Employee("赵六",36,5555),
                new Employee("田七",17,33333),
                new Employee("田",17,33333 )

        );
        list.stream()
                .sorted((e1,e2)->{
                    if(e1.getAge()==e2.getAge()){
                        return  e1.getName().compareTo(e2.getName());
                    }else{
                        return new Integer (-e1.getAge()).compareTo(new Integer(e2.getAge())) ;
                    }
                }).forEach(System.out::println);
    }
}

 Stream终止操作

从流的流水线生成结果。其结果可以是任何不是流的值,例如:List、Integer

查找与匹配 

主要方法:

* allMatch-检查是否匹配所有元素
* anyMatch-检查是否pip一个元素
* noneMatch-检查是否没有匹配所有元素
* findFirst-返回第一个元素
* findAny-返回当前流中的任意元素
* count-返回流中元素的总个数
* max-返回流中最大值
* min-返回流中最小值

示例四:

 private Employees.Status Status;

    public Employees(String name, int age, int salary, Status Status) {
        this.name = name;
        this.age = age;
        this.salary = salary;
       this.Status  = Status;
    }

    public void setStatus(Employees.Status status) {
        Status = status;
    }

    public Employees.Status getStatus() {
        return Status;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + ''' +
                ", age=" + age +
                ", salary=" + salary +
                ", Status=" + Status +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }



    public Employees() {
    }

    public enum  Status{
        FREE,
        BUSY,
        VOCATION;


    }
}

 

public class Test {
    public static void main(String[] args) {
        List employee = Arrays.asList(
                new Employees("张三",18,9999, Employees.Status.FREE),
                new Employees("李四",58,8888, Employees.Status.BUSY),
        new Employees("王五",26,5555, Employees.Status.VOCATION),
        new Employees("赵六",36,6666, Employees.Status.FREE),
        new Employees("田七",12,3333, Employees.Status.BUSY)

        );
//        判断Employees.Status.BUSY状态是否所有元素
       boolean b1 = employee.stream()
                .allMatch(e->e.getStatus().equals(Employees.Status.BUSY));
        System.out.println(b1);

//判断Employees.Status.BUSY是否与集合中一个元素匹配
       boolean b2 =  employee.stream()
                .anyMatch(e->e.getStatus().equals(Employees.Status.BUSY));
        System.out.println(b2);

//      判断Employees.Status.BUSY 是否没有匹配集合的所有元素
       boolean b3= employee.stream()
                .noneMatch(e->e.getStatus().equals(Employees.Status.BUSY));
        System.out.println(b3);

//Optional是容器类,将对象封装到这个容器里,避免空指针异常
//        findFirst-返回第一个元素,如果第一个值有可能为空值就将对象封装到Optional
       Optional op = employee.stream()
                .sorted((e1,e2)->Double.compare(e1.getSalary(),e2.getSalary()))
                .findFirst();
        System.out.println(op.get());

//        filter 方法用于通过设置的条件过滤出元素
//        返回当前流中的任意元素
        Optional op2 =employee.stream()
                .filter((e)->e.getStatus().equals(Employees.Status.FREE))
                .findAny();
        System.out.println(op2.get());

//        返回流中元素的总个数
        Long count = employee.stream()
                 .count();
        System.out.println(count);

//        返回最大/小值
       Optional op3 = employee.stream()
                .max((e1,e2)->Double.compare(e1.getSalary(),e2.getSalary()));
        System.out.println(op3);
            Optional op4 = employee.stream()
                    .map(Employees::getSalary)
                    .min(Integer::compare);
        System.out.println(op4);

    }

}

 归约

reduce(T identity(起始值),BinayOperator(二元运算))/reduce(BinayOperator)-可以将流中元素反复结合起来

案例5:

public static void main(String[] args) {

    List employee = Arrays.asList(
            new Employees1("张三",18,9999, Employees1.Status.FREE),
            new Employees1("李四",58,8888, Employees1.Status.BUSY),
            new Employees1("王五",26,5555, Employees1.Status.VOCATION),
            new Employees1("赵六",36,6666, Employees1.Status.FREE),
            new Employees1("田七",12,3333, Employees1.Status.BUSY)

    );
            List list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
//数组个元素相加
    Integer sum = list.stream()
            .reduce(0,(x,y)->x+y);
    System.out.println(sum);
    System.out.println("------------------------- ");
//    上边函数不可能为空所以用Integer,下边函数可能为空所以返回Optional
//    map和reduce的链接通常称为map-reduce模式,如大数据搜索热词
//薪资相加
   Optional op = employee.stream()
            .map(Employees1::getSalary)
            .reduce(Integer::sum);
    System.out.println(op);
    System.out.println("--------------------");
}

 

  收集

收集:collect(Collector); collector叫做收集器是一个接口,作用是你想按照哪一个收集器的方式收集 collector是一个接口,意味着要传他的实例必须传他的对应实现类collectors 

 示例6:收集常用的方法代码中均有标注

public static void main(String[] args){
List list1= employee.stream()
            .map(Employees1::getName)
//            Collectors.toList() 将流中的所有元素收集到 List 中
            .collect(Collectors.toList());
    System.out.println(list1);
    System.out.println("----------------");

//   将流中所有有元素收集到set中
    Set set = employee.stream()
            .map(Employees1::getName)
            .collect(Collectors.toSet());
    System.out.println(set);
    System.out.println("--------------------------");
    
    HashSet hs =employee.stream()
            .map(Employees1::getName)
            .collect(Collectors.toCollection(HashSet::new ));
    hs.forEach(System.out::println);

//    人数总数
    Long count = employee.stream()
            .collect(Collectors.counting());
    System.out.println(count);

//    平均值
    Double avg = employee.stream()
            .collect(Collectors.averagingDouble(Employees1::getSalary));
    System.out.println(avg);

//    工资总和
   int sum1 = employee.stream()
            .collect(Collectors.summingInt(Employees1::getSalary));
    System.out.println(sum1);

//    最大值
   Optional op3 = employee.stream()
            .collect(Collectors.maxBy((e1,e2)->Integer.compare(e1.getSalary(), e2.getSalary())));
    System.out.println(op3);

//    最小值
    Optionalop4 = employee.stream()
            .collect(Collectors.minBy((e1,e2)->Integer.compare(e1.getSalary(), e2.getSalary())));
    System.out.println(op4);
    System.out.println("-------------------");

    分组
    Map> map = employee.stream()
            .collect(Collectors.groupingBy(Employees1::getStatus));
    System.out.println(map);
    System.out.println("-------------------");
//多及分组
   Map>> map1 = employee.stream()
            .collect(Collectors.groupingBy(Employees1::getStatus,Collectors.groupingBy((e)->
                    {
                        if(((Employees1)e).getAge()<=35){
                            return "青年";
                        }else{
                            return"老年";
                        }
                    }
                    ))) ;
    System.out.println(map1);
//    分区:分TRUE和FALSE的两个区,满足条件的一个区,不满足条件的一个区、
    Map> map2 = employee.stream()
            .collect(Collectors.partitioningBy((e)->e.getSalary()>8000));
    System.out.println(map2);
    System.out.println("------------------");
//    收集
    String str = employee.stream()
            .map(Employees1::getName)
            .collect(Collectors.joining(","));
    System.out.println(str);


}
}

 

暑期编程PK赛 得CSDN机械键盘等精美礼品!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1017264.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号