Java8 Stream流的理解与认识

总结

原地址: https://blog.csdn.net/mu_wind/article/details/109516995
原作者:@云深i不知处

1、获取当前方法名

Thread.currentThread().getStackTrace()[1].getMethodName()   

2、Map.containsKey/Value ()

Map.containsKey (object.getxxx())
Map.containsValue (object.getxxx())
返回值是Boolean类型  判断参数中有没有与map中相同的键/值 相等的 如果有 返回true 反之 返回false
========================================================================
     @Test
    public void test1(){
        HashMap<String, Object> hashMap = new HashMap();
        hashMap.put("a",1);
        hashMap.put("b",2);
        if (hashMap.containsKey("c")){
            System.out.println("有这个key");
        }else {
            System.out.println("没有这个key");
        }
        if (hashMap.containsValue(1)){
            System.out.println("有这个value");
        }else {
            System.out.println("没有这个value");
        }
    }

===========================================================================
    输出结果
==============================================================================    
没有这个key
有这个value

3、箭头函数与lambda表达式

// 1. 不需要参数,返回值为 5  
() -> 5  
  
// 2. 接收一个参数(数字类型),返回其2倍的值  
x -> 2 * x  
  
// 3. 接受2个参数(数字),并返回他们的差值  
(x, y) -> x – y  
  
// 4. 接收2个int型整数,返回他们的和  
(int x, int y) -> x + y  
  
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)  
(String s) -> System.out.print(s)
    
===================================================================
      @Test
    public void test1(){
        String[] atp = {"Rafael Nadal",
                "Novak Djokovic",
                "Stanislas Wawrinka",
                "David Ferrer",
                "Roger Federer",
                "Andy Murray",
                "Tomas Berdych",
                "Juan Martin Del Potro"};
        List<String> players =  Arrays.asList(atp);
      //最原始的方法
       for (String player : players) {
            System.out.println(player);
        }

       //使用java8 lambda表达式 双冒号操作符
        players.forEach(System.out::println);

       // 使用 lambda 表达式以及函数操作(functional operation)  
        players.forEach((player)-> System.out.println(player+""));
}
   
=========================================================================
双冒号操作符
    
通常的情况下:
把 x -> System.out.println(x) 简化为 System.out::println 的过程称之为 eta-conversion
把 System.out::println 简化为 x -> System.out.println(x) 的过程称之为 eta-expansion
    
范式:
	类名::方法名
注意:
	方法后面并没有()
	懒加载方法是否调用要看调用方使用情况
=================================================================================
 实例
 	() -> new ArrayList<>();  可以替换为      ArrayList::new
        
 	person -> person.getAge()  替换为     Person::getAge
        

4、Optional类

Optional类完美解决了空指针异常的问题,它允许值为null  并且Stream流操作中默认就是Optional

5、使用Stream流来处理集合

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hsxvzdci-1633765105327)(E:/Typroa图片/image-20211008160739227.png)]

5.1、遍历/匹配(foreach/find/match)

    List<Integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1);

    // 遍历输出符合条件的元素
    list.stream().filter(x -> x > 6).forEach(System.out::println);
    // 匹配第一个
    Optional<Integer> findFirst = list.stream().filter(x -> x > 6).findFirst();
    // 匹配任意(适用于并行流)
    Optional<Integer> findAny = list.parallelStream().filter(x -> x > 6).findAny();
    // 是否包含符合特定条件的元素
    boolean anyMatch = list.stream().anyMatch(x -> x < 6);

	//foreach遍历
	List<Person> personList = new ArrayList<Person>();
    personList.add(new Person("Tom", 8900, 23, "male", "New York"));
    personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
    personList.add(new Person("killBee", 7800, 21, "female", "Washington"));
    personList.add(new Person("Currey", 8200, 24, "female", "New York"));
	personList.forEach(x-> System.out.println(x));
	或者
    personList.forEach(System.out::println);    

5.2、筛选(filter)

 public void filter(){
    List<Person> personList = new ArrayList<Person>();
    personList.add(new Person("Tom", 8900, 23, "male", "New York"));
    personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
    personList.add(new Person("Lily", 7800, 21, "female", "Washington"));
    personList.add(new Person("Anni", 8200, 24, "female", "New York"));
    personList.add(new Person("Owen", 9500, 25, "male", "New York"));
    personList.add(new Person("Alisa", 7900, 26, "female", "New York"));
    System.out.println(personList.stream()
                       .filter(x -> x.getSalary() >8000)
                       .map(Person::getName)
                       .collect(Collectors.toList()));
     
 ============================================================
[Tom, Anni, Owen]

5.3、聚合(max/min/count)

    public void max_min_count(){
    List<String> list = Arrays.asList("adnm", "admmt", "pot", "xbangd", "weoujgsd");
    //求最长的字符串  Comparator.comparing(类名::属性名) 升序 然后通过max 查询最大值
    Optional<String> max = list.stream().max(Comparator.comparing(String::length));
    System.out.println(max.get());
}
===================================================================
    weoujgsd
===============================================================
    public void max_min_count(){
    List<Integer> list = Arrays.asList(1,2,3,4,5);
    //求最长的字符串  Comparator.comparing(类名::属性名) 升序 然后通过max 查询最大值
    Optional<Integer> max = list.stream().min(Integer::compareTo);
    System.out.println(max.get());
}
============================================================
    1    Max和min用法一样 
=====================================================
    public void max_min_count(){
    List<Person> personList = new ArrayList<Person>();
    personList.add(new Person("Tom", 8900, 23, "male", "New York"));
    personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
    personList.add(new Person("Lily", 7800, 21, "female", "Washington"));
    personList.add(new Person("Anni", 8200, 24, "female", "New York"));
    personList.add(new Person("Owen", 9500, 25, "male", "New York"));
    personList.add(new Person("Alisa", 7900, 26, "female", "New York"));

    long l = personList.stream().filter(x -> x.getSalary() > 8000).map(Person::getName).collect(Collectors.toList()).stream().count();
    System.out.println(l);
}
=======================================================
  3
====================================================    
    count方法放在代码最后面执行 逻辑计算完成 进行计数
    max/min 方法 放在流之后 逻辑计算之前 并使用()将逻辑计算包括

5.4、收集(collect)

从字面上理解就是 将处理好的流收集起来 最终形成一个值或者新的集合

基本上格式就是collect (Collectors.相应方法接口)

5.4.1、归集(toList/toSet/toMap)

将处理好的流数据整合成List、Set、Map类型的数据

 List<Integer> list = Arrays.asList(1, 6, 3, 4, 7, 6, 9, 6, 20,1,6);
 List<Integer> collect = list.stream().filter(x->x>3).collect(Collectors.toList());
 Set<Integer> collect1 = list.stream().filter(x->x>3).collect(Collectors.toSet());
=====================================================
	list:  [6, 4, 7, 6, 9, 6, 20, 6]
     set: [4, 20, 6, 7, 9]
=======================================================
     List<Person> personList = new ArrayList<Person>();
		personList.add(new Person("Tom", 8900, 23, "male", "New York"));
		personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
		personList.add(new Person("Lily", 7800, 21, "female", "Washington"));
		personList.add(new Person("Anni", 8200, 24, "female", "New York"));
    Map<String, Integer> map = personList.stream()
        .filter(x -> x.getSalary() > 5000)
        .collect(Collectors.toMap(Person::getName, Person::getSalary));
   //使用iterator循环遍历map 
Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator();
    while(iterator.hasNext()){
        Map.Entry<String, Integer> next = iterator.next();
        System.out.println("key:"+next.getKey()+"value:"+next.getValue());
    }    
====================================================================
   将查询结果转换为map并使用iterator循环遍历map
key:Tomvalue:8900
key:Annivalue:8200
key:Jackvalue:7000
key:Lilyvalue:7800
如果像这种类型
    entPubList.stream().collect(Collectors.toMap(TblEntPub::getEntOrgCode, a->a));  
value值 a代表的是TblEntPub整个实体对象对应的数据
5.4.2、统计(count/averaging)

计数count
平均值averagingInt、averagingLong、averagingDouble
最值maxBy、minBy
求和summingInt、summingLong、summingDouble
统计以上所有summarizingInt、summarizingLong、summarizingDouble

    public void count_averaging(){    List<Person> personList = new ArrayList<Person>();    personList.add(new Person("Tom", 8900, 23, "male", "New York"));    personList.add(new Person("Jack", 7000, 25, "male", "Washington"));    personList.add(new Person("Lily", 7800, 21, "female", "Washington"));    personList.add(new Person("Anni", 8200, 24, "female", "New York"));    //员工总和    Long count = personList.stream().collect(Collectors.counting());    System.out.println(count);    //工资平均数    Double AvgSalary = personList.stream().collect(Collectors.averagingDouble(Person::getSalary));    System.out.println(AvgSalary);    //工资最大数    Optional<Integer> MaxSalary = personList.stream().map(Person::getSalary).collect(Collectors.maxBy(Integer::compareTo));    System.out.println(MaxSalary);    //工资总和    Integer SumSalary = personList.stream().collect(Collectors.summingInt(Person::getSalary));    System.out.println(SumSalary);    //所有信息    DoubleSummaryStatistics statistics = personList.stream().collect(Collectors.summarizingDouble(Person::getSalary));    System.out.println(statistics);}==================================================================count;4average:7975.0max:Optional[8900]sum:31900所有信息:    DoubleSummaryStatistics{    count=4, sum=31900.000000, min=7000.000000, average=7975.000000, max=8900.000000	}
5.4.3、分组与分区(partitioningBy/groupingBy)
  • 分区:将stream按条件分为两个Map,比如员工按薪资是否高于8000分为两部分。
  • 分组:将集合分为多个Map,比如员工按性别分组。有单级分组和多级分组。
  List<Person> personList = new ArrayList<Person>();    personList.add(new Person("Tom", 8900, 23, "male", "New York"));    personList.add(new Person("Jack", 7000, 25, "male", "Washington"));    personList.add(new Person("Lily", 7800, 21, "female", "Washington"));    personList.add(new Person("Anni", 8200, 24, "female", "New York"));    //将所有人按工资是否大于8000分为两个区    Map<Boolean, List<Person>> map = 	//personList.stream().collect(Collectors.partitioningBy(x -> x.getSalary() > 8000));     //名字长度大于5的进行分组       Map<Boolean, List<Person>> map = personList.stream()        									.collect(Collectors                 							.groupingBy(x -> x.getName()                             				.length() > 4));    Iterator<Map.Entry<Boolean, List<Person>>> iterator = map.entrySet().iterator();    while (iterator.hasNext()){        Map.Entry<Boolean, List<Person>> next = iterator.next();        System.out.println(next.getValue());    }========================================================== 分区操作 按工资是否大于8000进行分区    [Person{name='Jack', salary=7000, age=25, sex='male', area='Washington'}, Person{name='Lily', salary=7800, age=21, sex='female', area='Washington'}]    [Person{name='Tom', salary=8900, age=23, sex='male', area='New York'}, Person{name='Anni', salary=8200, age=24, sex='female', area='New York'}]  名字长度大于5的进行分组 [Person{name='Tom', salary=8900, age=23, sex='male', area='New York'}, Person{name='Jack', salary=7000, age=25, sex='male', area='Washington'}]    [Person{name='killBee', salary=7800, age=21, sex='female', area='Washington'}, Person{name='Currey', salary=8200, age=24, sex='female', area='New York'}]

6、排序(sorted)

sorted,中间操作。有两种排序: 如果是数字 就比大小 是字符 就比较Ascll码值

  • sorted():自然排序,流中元素需实现Comparable接口
  • sorted(Comparator com):Comparator排序器自定义排序
@Test    public void sort(){    List<Person> personList = new ArrayList<Person>();    personList.add(new Person("Tom", 8900, 23, "male", "New York"));    personList.add(new Person("Jack", 7000, 25, "male", "Washington"));    personList.add(new Person("killBee", 7800, 21, "female", "Washington"));    personList.add(new Person("Currey", 8200, 24, "female", "New York"));          //按工资排序 默认升序     List<String> list = personList.stream().sorted(Comparator.comparing(Person::getSalary))  		.map(person -> person.getName()+":"+person.getSalary())        .collect(Collectors.toList());             //按工资排序    reversed() 降序    List<String> list1 = personList.stream().sorted(Comparator.comparing(Person::getSalary)         .reversed()).map(person ->person.getName()+":"+person.getSalary())          .collect(Collectors.toList());            //自定义排序 先按工资升序 如果工资相等 再按年龄降序       List<String> list2 = personList.stream().sorted(Comparator.comparing(Person::getSalary)            .thenComparing(Person::getAge))     .map(person -> person.getName()+":"+person.getSalary()+"==>"+person.getAge())            .collect(Collectors.toList());  list.forEach(x-> System.out.println(x));    System.out.println("================================");    list1.forEach(x-> System.out.println(x));    System.out.println("================================");    list2.forEach(x-> System.out.println(x));}}====================================================================升序Jack:7000killBee:7800Currey:8200Tom:8900================================降序Tom:8900Currey:8200killBee:7800Jack:7000================================Jack:7000==>25killBee:7800==>21Currey:8200==>24Tom:8900==>23

java8还提供了其他的排序方法 可以不使用stream流

    personList.sort((o1, o2) -> o1.getSalary()-o2.getSalary());    personList.forEach(x-> System.out.println(x));=====================================================Person{name='Jack', salary=7000, age=3, sex='male', area='Washington'}Person{name='killBee', salary=7800, age=4, sex='female', area='Washington'}Person{name='Currey', salary=8200, age=2, sex='female', area='New York'}Person{name='Tom', salary=8900, age=1, sex='male', area='New York'}其中 o1.getSalary()、o2.getSalary() 是获取比较的元素 中间用-隔开

中文状态下 按照拼音排序

personList.sort(Comparator.comparing(Person::getName, (a,b) ->{//第一顺序:按字段拼音return Collator.getInstance(Locale.CHINESE).compare(a, b);}).thenComparing(Person::getAge, (a, b) ->{//第二顺序:按数字大小return a<b?-1:1;//按类型大小排序,再加反转}).thenComparingLong(Person::getAge).reversed());简化  personList.sort((a, b) ->{       return Collator.getInstance(Locale.CHINESE).compare(a.getName(), b.getName());   });==========================================================Person{name='阿姐', salary=7000, age=1, sex='male', area='a'}Person{name='阿张', salary=8900, age=1, sex='male', area='New York'}Person{name='梨花', salary=8200, age=2, sex='female', area='New York'}Person{name='徐福', salary=7800, age=4, sex='female', area='Washington'}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值