stream流对象的认识与使用&stream流中方法精简总结


Java8的两个重大改变,一个是Lambda表达式,另一个就是本节要讲的Stream API表达式。

一、Stream 流对象的作用

Stream 是Java8中处理集合的关键抽象概念,它可以对集合进行非常复杂的查找、过滤、筛选等操作。

Stream(流) 类用于来简化集合类的使用,Stream 本质上是个接口,接口中定义了很多对 Stream 对象的操作;

二、Stream的操作步骤

1、创建Stream
从一个数据源,如集合、数组中获取流。
2、中间操作
一个操作的中间链,对数据源的数据进行操作。
3、终止操作
一个终止操作,执行中间操作链,并产生结果。

要注意的是,对流的操作完成后需要进行关闭操作(或者用JAVA7的try-with-resources)。(流的关闭就是在操作体外执行的操作)

三、特征

  1. 单次处理,一次处理结束后,当前stream就关闭了
  2. 支持并行操作

四、举个简单的例子

假设有一个Person类和一个Person列表,现在有两个需求:1)找到年龄大于18岁的人并输出;2)找出所有中国人的数量。

@Data
class Person {
    private String name;
    private Integer age;
    private String country;
    private char sex;

    public Person(String name, Integer age, String country, char sex) {
        this.name = name;
        this.age = age;
        this.country = country;
        this.sex = sex;
    }
}
List<Person> personList = new ArrayList<>();
personList.add(new Person("欧阳雪",18,"中国",'F'));
personList.add(new Person("Tom",24,"美国",'M'));
personList.add(new Person("Harley",22,"英国",'F'));
personList.add(new Person("向天笑",20,"中国",'M'));
personList.add(new Person("李康",22,"中国",'M'));
personList.add(new Person("小梅",20,"中国",'F'));
personList.add(new Person("何雪",21,"中国",'F'));
personList.add(new Person("李康",22,"中国",'M'));

在JDK8以前,我们可以通过遍历列表来完成。但是在有了Stream API后,可以这样来实现:

public static void main(String[] args) {

    // 1)找到年龄大于18岁的人并输出;
    personList.stream().filter((p) -> p.getAge() > 18).forEach(System.out::println);

    System.out.println("-------------------------------------------");

    // 2)找出所有中国人的数量
    long chinaPersonNum = personList.stream().filter((p) -> p.getCountry().equals("中国")).count();
    
    System.out.println("中国人有:" + chinaPersonNum + "个");
}

输出结果:

Person(name=Tom, age=24, country=美国, sex=M)
Person(name=Harley, age=22, country=英国, sex=F)
Person(name=向天笑, age=20, country=中国, sex=M)
Person(name=李康, age=22, country=中国, sex=M)
Person(name=小梅, age=20, country=中国, sex=F)
Person(name=何雪, age=21, country=中国, sex=F)
Person(name=李康, age=22, country=中国, sex=M)
-------------------------------------------
中国人有:6

在这个例子中,personList.stream()是创建流,filter()属于中间操作,forEach、count()是终止操作。

五、stream流中方法精简总结

方法名简介
allMatch检查 Stream 中的所有元素,全部都通过检测则返回 true
anyMatch检查 Stream 中的所有元素,全部都通过检测则返回 true
noneMatch当流中每个元素都不符合该断言时才返回true
count返回流中元素的总个数
max返回stream中的最大值
min返回stream中的最小值
sort对stream中的元素排序
filter过滤 Stream中的元素
map将流中的一个值转换成一个新的值
collect接收一个Collector实例,将流中元素收集成另外一个数据结构
collect(toList())通过 Stream 生成一个列表
flatMap将多个 Stream 连接成一个 Stream
reduce从一组值中生成一个新的值
of返回包含参数中单个指定元素的顺序Stream
distinct去重
findFirst返回流中第一个元素
findAny返回流中的任意元素

六、操作方法的使用详解

stream流结合lambda表达式使用起来非常方便。
可以学习一下lambda表达式的使用,有空我会在CSDN上总结

1. allMatch和anyMatch

allMatch:检查 Stream 中的所有元素,全部都通过检测则返回 true,否则 false

anyMatch:检查 Stream 中的所有元素,至少有一个通过检测则返回 true,否则 false

    //allMatch
    System.out.println("----->"+list.stream().allMatch(n->n.getClass() == Integer.class));
    //anyMatch
    System.out.println("----->"+list.stream().anyMatch(n->n>1));
2. max,min和sort

max:返回stream中的最大值

min:返回stream中的最小值

sort:对stream中的元素排序

        //遍历
        list.stream().forEach(a -> System.out.println(a));
        //max
        System.out.println("----->"+list.stream().max((a,b)->a-b).get());
        //min
        System.out.println("----->"+list.stream().min((a,b)->a-b).get());
        //sort
        list.stream().sorted((a,b)->a-b).forEach(a->System.out.println(a));

3. filter和map

filter:筛选 Stream 元素,符合条件的留下并组成一个新的 Stream 。

map:依次对 Stream 中的元素进行指定的函数操作,并将按顺序将函数操作的返回值组合到一个新的 Stream 中。

        //筛选filter
        list.stream().filter(n->n>6).forEach(n->System.out.println(n));
        //map
        list.stream().map(n->n+1).forEach(n->System.out.println(n));
4. of
用法: static Stream of(T t)
参数: 此方法接受强制参数t,该参数是Stream中的单个元素。
返回值: Stream of(T t)返回包含单个指定元素的顺序Stream。

// Java code for Stream of(T t) 
// to get a sequential Stream 
// containing a single element. 
  
import java.util.*; 
import java.util.stream.Stream; 
  
class GFG { 
  
    // Driver code 
    public static void main(String[] args) 
    { 
        // Creating an Stream having single element only 
        Stream stream = Stream.of("Geeks"); 
  
        // Displaying the Stream having single element 
        stream.forEach(System.out::println); 
    } 
}

输出:Geeks
5. distinct和collect

distinct:去重

collect:可以做collectors中的一些操作,如:连接,转list,分组等

        //collect
        Stream.of("1","2","3").collect(Collectors.toList()).forEach(n->System.out.println(n));
        //去重distinct
        Stream.of("2","2","2").distinct().forEach(n->System.out.println(n));

其中,.collect(Collectors.toList()) 方法将操作后返回的 Stream 生成一个 List。

6. collect(toList()) & filter

collect(toList()) 的作用是通过一个 Stream 对象生成 List 对象,案例:

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> result = list.stream().filter((value) -> value > 2).collect(toList());
result.forEach((value) -> System.out.print(value));

解析:创建了一个 List 对象并初始化,然后筛选出大于 2 的值,输出。

filter 方法的作用是过滤 Stream 中的元素,filter 方法是一个高阶函数,
接收一个函数接口作为参数,此高阶函数返回一个 boolean 值,返回 true 的元素会保留下来;

collect(toList()) 方法将 filter 操作返回的 Stream 生成一个 List。

高阶函数:接收或返回一个函数接口的函数称为高阶函数。
函数接口:只包含一个函数的接口成为函数接口。

7. map

map 函数的作用是将流中的一个值转换成一个新的值,举个例子,我们要将一个 List 转换成 List ,那么就可以使用 map 方法,案例:

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<String> result = list.stream().map(value -> String.format("String:%s", value)).collect(toList());
result.forEach(System.out::print);

解析:map 方法将 Integer 元素转换成 String 并使用 collect(toList()) 方法生成一个新的 List。

System.out::print 是 (value) -> System.out.print(value) 的简化版写法。

8. flatMap

将多个 Stream 连接成一个 Stream。案例:

List<String> list = Arrays.asList("abc", "def", "ghi");
List<Character> result = list.stream().flatMap(value -> {
    char[] chars = value.toCharArray();
    Character[] characters = new Character[chars.length];
    for(int i = 0; i < characters.length; i++){
        characters[i] = chars[i];
    }
    return Stream.of(characters);
}).collect(toList());
result.forEach(System.out::println);

解析:首先定义一个 List 对象,将这个对象中的每一个 String 都分割成一个字母并生成一个新的 List 对象。

上面代码先遍历 list ,通过 flatMap 函数将每个 String 元素都生成一个新的 Stream 并将这些 Stream 连接成一个新的 Stream。
9. reduce

从一组值中生成一个新的值

List<Integer> list = Arrays.asList(0, 1, 2, 3);
int count = list.stream().reduce(0, (acc, item) -> acc + item).intValue();
System.out.println(count);

reduce 函数的一个参数为循环的初始值,这里计算累加时初始值为 0,acc 代表已经计算的结果,item 表示循环的每个元素。
10. 收集操作

collect:接收一个Collector实例,将流中元素收集成另外一个数据结构。

  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: axi-stream和axi-lite是两种不同的传输协议,它们在数据传输的方式和控制信号上有所不同。在将axi-stream转换为axi-lite时,需要进行一些改变和调整。 首先,axi-stream是一种式传输协议,它主要用于高速数据传输,没有固定的地址和控制信号。而axi-lite是一种基于地址和控制信号的传输协议,适用于低速数据传输和对外部设备的读写控制。 要将axi-stream转换为axi-lite,需要定义一个寄存器(或寄存器组),用于接收从axi-stream传输过来的数据。通过定义该寄存器的地址和控制信号,可以对其进行读写操作,并将数据传输到外部设备。 其次,需要根据具体的应用场景,对数据的格式和处理进行调整。axi-stream一般通过数据的方式传输,而axi-lite传输的数据需要按照特定的格式进行打包和解包。因此,在进行转换时,需要对数据进行格式转换和处理,以满足axi-lite的传输要求。 最后,需要修改相应的控制逻辑和状态机来适应axi-lite的读写操作。axi-stream主要通过数据传输,而axi-lite需要定义读写控制信号和状态机来实现读写操作。因此,在进行转换时,需要对控制逻辑和状态机进行修改,以实现axi-lite的读写功能。 总结起来,将axi-stream转换为axi-lite需要进行以下几个步骤:定义一个寄存器用于接收数据、调整数据的格式和处理、修改控制逻辑和状态机来适应axi-lite的读写操作。通过这些步骤,我们可以完成axi-stream到axi-lite的转换。 ### 回答2: 要将Axi-Stream转换为Axi-Lite,需要进行一系列的处理和转换。 首先,需要了解Axi-Stream和Axi-Lite之间的区别。Axi-Stream是一种高速数据传输协议,用于在数据传输应用中实现高速数据传输。相比之下,Axi-Lite则是一种更简化、精简的协议,适用于低速、延迟敏感的访问要求。 要将Axi-Stream转换为Axi-Lite,需要将数据转变为离散的数据包。可以通过添加一些额外的逻辑和寄存器来实现数据的提取和转换。 首先,需要添加一个接收缓冲区,用于接收Axi-Stream传输的数据。可以使用一个FIFO(First-In, First-Out)缓冲区来实现。将Axi-Stream输入端口连接到该缓冲区,并配置缓冲区的大小以适应数据传输的需求。 然后,可以使用状态机和控制逻辑从接收缓冲区中提取数据。根据Axi-Lite协议的要求,需要提取合适的数据字段,并将其放入适当的寄存器中。可以使用状态机来控制数据的提取和转换过程。 最后,在提取和转换数据后,可以使用Axi-Lite的地址端口和数据端口,将数据传输到Axi-Lite总线上。根据Axi-Lite协议的要求,需要设置地址、数据和控制信号,以完成对寄存器的读写操作。 总体而言,将Axi-Stream转换为Axi-Lite需要添加接收缓冲区、状态机和控制逻辑,并通过Axi-Lite协议完成数据的提取和转换。这样可以实现从高速数据传输到低速数据访问的转换。 ### 回答3: Axi-stream和Axi-lite是两种不同的通信协议,将Axi-stream转换为Axi-lite可以通过添加适当的逻辑和转换器来实现。下面是一种将Axi-stream转换为Axi-lite的方法: 1. 首先,需要添加一个转换器模块,该模块将负责将Axi-stream信号转换为Axi-lite信号。该转换器模块可以使用FIFO(First-In-First-Out)缓冲区来处理数据,并将其转换为连续的数据列。 2. 转换器模块接收来自Axi-stream的有效数据包,并根据Axi-lite协议的要求生成对应的Axi-lite数据包。转换过程包括将Axi-stream的数据包拆分为Axi-lite的数据包,并提取有效数据和其他控制信息。 3. 转换器模块还需要处理Axi-stream信号的速。由于Axi-stream的数据是连续动的,而Axi-lite的数据包需要在时钟边沿进行传输,因此需要添加适当的时序逻辑来处理数据速的差异。 4. 转换器模块还应该能够处理Axi-lite协议中的写入和读取操作。写入操作将由Axi-stream转换成Axi-lite写入操作,读取操作将由Axi-stream转换成Axi-lite读取操作。 5. 最后,通过适当的连接操作将转换器模块与Axi-lite总线连接起来,以实现从Axi-stream到Axi-lite的转换。 总结来说,将Axi-stream转换为Axi-lite需要添加一个转换器模块,该模块负责处理Axi-stream数据的数据包和速,并将其转换为符合Axi-lite协议的信号。这样可以实现从Axi-stream到Axi-lite的数据通信转换。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值