重点知识学习--[Java 8 之 Stream流]

Posted 小智RE0

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了重点知识学习--[Java 8 之 Stream流]相关的知识,希望对你有一定的参考价值。

注意: java8 中的 stream 流与 InputStream 和 OutputStream 对文件操作的流 不是一样的;

  • 使用Stream流的;就能以声明式的方式处理数据集合,可看作是遍历数据集的高级迭代器;

  • stream 与 lambda 表达式结合后编码效率大大提高,且可读性更强。

  • Stream擅长于对数据的操作.

例如这个案例

这里先定义一个Person类;

/**
 * @author by 信计1801 李智青 学号:1809064012
 */
public class Person 
    private Integer port;
    private String account;
    private String nick;

    public Person() 
    

    public Person(Integer port, String account, String nick) 
        this.port = port;
        this.account = account;
        this.nick = nick;
    

    public Integer getPort() 
        return port;
    

    public void setPort(Integer port) 
        this.port = port;
    

    public String getAccount() 
        return account;
    

    public void setAccount(String account) 
        this.account = account;
    

    public String getNick() 
        return nick;
    

    public void setNick(String nick) 
        this.nick = nick;
    
    
    @Override
    public String toString() 
        return "Person" +
                "port=" + port +
                ", account='" + account + '\\'' +
                ", nick='" + nick + '\\'' +
                '';
    

在集合中存入几个对象;需要快速找到指定的用户;
可使用stream流进行快速操作;调用过滤方法,配合Lambda表达式;

/**
 * @author by 信计1801 李智青 学号:1809064012
 */
public class Test 
    public static void main(String[] args) 
        List<Person> list = new ArrayList<>();
        list.add(new Person(8025,"杰西","杰西25号"));
        list.add(new Person(8081,"jiexi1","杰西1号"));
        list.add(new Person(8016,"jiexi16","杰西16号"));
        list.add(new Person(8085,"jiexi5","杰西5号"));
        list.add(new Person(8088,"jiexi8","杰西8号"));

        //筛选出杰西16号;
        List<Person> collect = list.stream()
                .filter(a -> 
                    return a.getNick().equals("杰西16号");
                )
                .collect(Collectors.toList());
        collect.forEach(System.out::println);
    

刚才的案例就是用了stream流;
其实就主要是三步走;
首先:获取流,然后进行中间操作(排序/过滤/分页/去重/跳过…),然后就是最后的结果转换处理;

获取流

  • 使用 Collection 接口下的 stream()方法,集合转为流
  • 使用 Arrays 中的stream(数组) 方法,将数组转成流
  • 使用 Stream 中的静态方法:of(数据源)
  • 使用 BufferedReader.lines()方法,将每行内容转成流

BufferedReader reader=new BufferedReader(new FileReader(“stream.txt”));
Stream lineStream = reader.lines();

中间操作

  • filter:过滤流中的某些元素, sorted(): 自然排序,流中元素需实现 Comparable 接口
  • distinct: 去除重复元素
  • limit(n): 获取 n 个元素
  • skip(n): 跳过 n 元素,配合 limit(n)可实现分页
  • map(): 将其映射成一个新的元素

终端操作

  • forEach: 遍历流中的元素
  • toArray:将流中的元素倒入一个数组
  • Min:返回流中元素最小值
  • Max:返回流中元素最大值
  • count:返回流中元素的总个数
  • Reduce:所有元素求和
  • anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足条件则返回 true,否则返回 false
  • allMatch:接收一个 Predicate 函数,当流中每个元素都符合条件时才返回 true,否则返回 false
  • findFirst:返回流中第一个元素
  • collect:将流中的元素倒入一个集合,Collection(List/Set) 或 Map

这里分别来试试几个案例

案例(1)排序,去重,过滤,遍历操作

/**
 * @author by 信计1801 李智青 学号:1809064012
 */
public class Demo 
    public static void main(String[] args) 
        List<Integer> list = new ArrayList<>();
        list.add(6);
        list.add(2);
        list.add(6);
        list.add(1);
        list.add(8);
        
        //排序,然后去重,过滤处理(仅保留大于2的数);
        list.stream()
                .sorted()
                .distinct()
                .filter((a) -> 
                    return a > 2;
                )
                .forEach(a -> System.out.print(a + "->"));
    
       

最终结果,得到6和8两个元素

6->8->

案例(2)过滤,计数操作

//过滤处理;仅保留大于13的数字;计算总个数
long res = Stream.of(14, 13, 12, 15, 16, 10)
                 .filter(q-> return q>13;)
                 .count();
System.out.println("总个数为->"+res);
//总个数为->3

案例(3)跳过元素,分页操作

//skip 跳过0个元素; limit 分页显示2个元素;
Stream.of(14, 13, 12, 15, 16, 10)
      .skip(0)
      .limit(2)
      .forEach(a-> System.out.print(a+"->"));

结果

14->13->

案例(4)跳过元素,分页操作

//skip 跳过2个元素; limit 分页显示2个元素;
Stream.of(14, 13, 12, 15, 16, 10)
      .skip(2)
      .limit(3)
      .forEach(a-> System.out.print(a+"->"));

结果

12->15->16->

案例(5)求和操作

//reduce求和
Integer sum =Stream.of(14,13,12,15)
                   .reduce(Integer::sum).get();
System.out.println("和为:"+sum);

结果

和为:54

案例(6)计算最大值操作

//max,计算最大值
Integer integer= Stream.of(10,8,29,27,53)
                       .max(Integer::compareTo).get();
System.out.println("最大值"+integer);

结果

最大值53

案例(7)anyMatch判断操作

//anyMatch处理    这组数据中只要有一个大于8,则返回true;
boolean result = Stream.of(10,7,8,1,2,4)
                       .anyMatch(a->return a>8;);
System.out.println(result);

结果

true

案例(8)allMatch判断操作

//allMatch处理    这组数据需要全部大于8;才能返回true;
boolean result = Stream.of(10,7,8,1,2,4)
                       .allMatch(a->return a>8;);
System.out.println(result);

结果

false

案例(9)map操作1

/**
 * @author by 信计1801 李智青 学号:1809064012
 */
public class Demo 
    public static void main(String[] args) 
        List<Person> list = new ArrayList<>();
        list.add(new Person(8080,"jiexi25","杰西25号"));
        list.add(new Person(5066,"jiexi1","杰西1号"));
        list.add(new Person(3306,"jiexi16","杰西16号"));
        list.add(new Person(5277,"jiexi5","杰西5号"));
        list.add(new Person(8888,"jiexi8","杰西8号"));
        //对这几位用户的昵称直接进行map映射操作
        list.stream().map(Person::getNick).forEach(System.out::println);
     
      

结果

杰西25号
杰西1号
杰西16号
杰西5号
杰西8

案例(10)排序处理;map( )操作转为List集合

/**
 * @author by 信计1801 李智青 学号:1809064012
 */
public class Demo 
    public static void main(String[] args) 
        List<Person> list = new ArrayList<>();
        list.add(new Person(8080,"jiexi25","杰西25号"));
        list.add(new Person(5066,"jiexi1","杰西1号"));
        list.add(new Person(3306,"jiexi16","杰西16号"));
        list.add(new Person(5277,"jiexi5","杰西5号"));
        list.add(new Person(8888,"jiexi8","杰西8号"));

        list.stream()
            .sorted((a,b)-> return a.getPort()-b.getPort();)
            .collect(Collectors.toList()).forEach(System.out::println);
  
                

结果

Personport=3306, account='jiexi16', nick='杰西16号'
Personport=5066, account='jiexi1', nick='杰西1号'
Personport=5277, account='jiexi5', nick='杰西5号'
Personport=8080, account='jiexi25', nick='杰西25号'
Personport=8888, account='jiexi8', nick='杰西8号'

案例(11)过滤操作,map()操作转为set集合

/**
 * @author by 信计1801 李智青 学号:1809064012
 */
public class Demo 
    public static void main(String[] args) 
        List<Person> list = new ArrayList<>();
        list.add(new Person(8080,"jiexi25","杰西25号"));
        list.add(new Person(5066,"jiexi1","杰西1号"));
        list.add(new Person(3306,"jiexi16","杰西16号"));
        list.add(new Person(5277,"jiexi5","杰西5号"));
        list.add(new Person(8888,"jiexi8","杰西8号"));
        //
        Set<Person> collect = list.stream()
                .filter(a -> 
                    return a.getPort() > 8079;
                )
                .collect(Collectors.toSet());
        System.out.println(collect);
        
        

结果

[Personport=8888, account='jiexi8', nick='杰西8号', Personport=8080, account='jiexi25', nick='杰西25号']

案例(12)map()操作,再转为Map集合

/**
 * @author by 信计1801 李智青 学号:1809064012
 */
public class Demo 
    public static void main(String[] args) 
        List<Person> list = new ArrayList<>();
        list.add(new Person(8080,"jiexi25","杰西25号"));
        list.add(new Person(5066,"jiexi1","杰西1号"));
        list.add(new Person(3306,"jiexi16","杰西16号"));
        list.add(new Person(5277,"jiexi5","杰西5号"));
        list.add(new Person(8888,"jiexi8","杰西8号"));
        
        Map<String, Integer> collect1 = list.stream().collect(Collectors.toMap(Person::getAccount, Person::getPort));
        collect1.entrySet().forEach(System.out::println);
    

结果

jiexi25=8080
jiexi1=5066
jiexi16=3306
jiexi5=5277
jiexi8=8888

以上是关于重点知识学习--[Java 8 之 Stream流]的主要内容,如果未能解决你的问题,请参考以下文章

Java基础之Stream流(JDK1.8新特性)

java8-Stream之数值流

高效 告别996,开启java高效编程之门 3-5 Stream流概念解析

Java函数式编程之Stream流编程

java8-Stream流API

Java高阶进阶之Java函数式编程-Stream流-Lambda表达式