服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - 关于JAVA8的 Stream学习

关于JAVA8的 Stream学习

2021-12-18 14:57郜宇博 Java教程

这篇文章主要介绍了JAVA8 Stream学习方法的相关资料,需要的朋友可以参考下面文章内容

一、Stream的使用

1 创建

  • 通过Collection接口的实现类提供的 stream()方法,或
  • 通过Arrays中的静态方法 stream()获取
  • 通过Stream类中的静态方法 of()
  • 无限流(迭代/生成)
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
 * @Author: 郜宇博
 * @Date: 2021/9/1 23:28
 * 流操作
 */
public class StreamTests {
    @Test
    public void test(){
        //1.通过Collection接口的实现类提供的 stream()方法,或
        Collection<String> list = new ArrayList<>();
        list.stream();
        list.parallelStream();
        //2.通过Arrays中的静态方法 stream()获取
        Integer[] integers = new Integer[10];
        Arrays.stream(integers);
        //3.通过Stream类中的静态方法 of()
        Stream<String> stream = Stream.of("1","2");
        //4.无限流
        //迭代
        Stream<Integer> iterate = Stream.iterate(0, (x) -> x + 2);
        //生成
        Stream<Double> generate = Stream.generate(() -> Math.random());
    }
}
1.1.1并行流parallelStream

parallelStream提供了流的并行处理,它是Stream的另一重要特性,其底层使用Fork/Join框架实现。简单理解就是多线程异步任务的一种实现。

2 步骤

  • 创建Stream;
  • 转换Stream,每次转换原有Stream对象不改变,返回一个新的Stream对象(可以有多次转换);
  • 对Stream进行聚合(Reduce)操作,获取想要的结果;

关于JAVA8的 Stream学习

二、Stream的特性

惰性求值:

多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何处理!而是在终止操作时一次性全部处理,这种情况称为“惰性求值”。

三、中间操作

筛选与切片】

1 filter()

接受lambda表达式,从流中排除某些元素

?
1
2
3
4
5
6
7
8
9
10
11
@Test
public void test2(){
    //获取一个数组
    ArrayList<Integer> arrayList = new ArrayList<>();
    for (int i = 0; i <10; i++) {
        arrayList.add(i);
    }
    //流操作:获取大于5的
    arrayList.stream().filter((num)->num>5).forEach(System.out::println);
}
//结果:  6 7 8 9

2 limit()

截断流,使其元素个数不超过一定数量

满足limit的数量后,就短路,不在执行后续操作

?
1
2
3
4
5
6
7
8
9
10
11
12
13
@Test
public void test2(){
    //获取一个数组
    ArrayList<Integer> arrayList = new ArrayList<>();
    for (int i = 0; i <10; i++) {
        arrayList.add(i);
    }
    //流操作:获取大于5的
    arrayList.stream().filter((num)->num>5)
                    .limit(2)
                    .forEach(System.out::println);
}
//结果: 6 7

3 skip()

跳过元素,跳过前n个元素,执行后面的元素,如果不足n个则返回空流

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
@Test
public void test2(){
    //获取一个数组
    ArrayList<Integer> arrayList = new ArrayList<>();
    for (int i = 0; i <10; i++) {
        arrayList.add(i);
    }
    //流操作:获取大于5的
    arrayList.stream().filter((num)->num>5)
                    .skip(2)
                    .forEach(System.out::println);
}
//结果: 8 9
3.3 map()
映射,在方法中使用方法Function< T> 函数型接口 -----> R apply(T t);
 
@Test
public void  test4(){
    //获取一个list
    List<String> list = Arrays.asList("aaa","bbb","ccc");
    //使用流操作 转化大写
    list.stream().map((str)->str.toUpperCase())
            .forEach(System.out::println);
}
/*结果:AAA
  BBB
        CCC*/
@Test
public void test3(){
    //获取一个list
    List<String> list = Arrays.asList("aaa","bbb","ccc");
    //流操作: 将list中的元素取出
    //第一步使用map取出流,流里存放的还是流
    //因此需要二次foreach
    Stream<Stream<Character>> chs = list.stream().map(StreamTests::getUpper);
            chs.forEach((stream)->{
                stream.forEach(System.out::print);
            });
}
//将str返回为流对象
public static Stream<Character> getUpper(String str){
    List<Character> list = new ArrayList<>();
    for (Character character: str.toCharArray()){
        list.add(character);
    }
    return list.stream();
}
//结果:aaabbbccc

4 map()

映射,在方法中使用方法Function< T> 函数型接口 -----> R apply(T t);

?
1
2
3
4
5
6
7
8
9
10
11
@Test
public void  test4(){
    //获取一个list
    List<String> list = Arrays.asList("aaa","bbb","ccc");
    //使用流操作 转化大写
    list.stream().map((str)->str.toUpperCase())
            .forEach(System.out::println);
}
/*结果:AAA
  BBB
        CCC*/
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Test
public void test3(){
    //获取一个list
    List<String> list = Arrays.asList("aaa","bbb","ccc");
    //流操作: 将list中的元素取出
    //第一步使用map取出流,流里存放的还是流
    //因此需要二次foreach
    Stream<Stream<Character>> chs = list.stream().map(StreamTests::getUpper);
            chs.forEach((stream)->{
                stream.forEach(System.out::print);
            });
}
//将str返回为流对象
public static Stream<Character> getUpper(String str){
    List<Character> list = new ArrayList<>();
    for (Character character: str.toCharArray()){
        list.add(character);
    }
    return list.stream();
}
//结果:aaabbbccc

3.1 flatMap

相当于集合方法的 addAll

即:将流中的流内元素取出,放入一个流中,而不是流内套流

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Test
public void test3(){
    //获取一个list
    List<String> list = Arrays.asList("aaa","bbb","ccc");
    //流操作: 将list中的元素取出
    //第一步使用map取出流,流里存放的还是流
    //因此需要二次foreach
    Stream<Stream<Character>> chs = list.stream().map(StreamTests::getUpper);
            chs.forEach((stream)-> stream.forEach(System.out::print));
 
    System.out.println("\n=====");
    //方法二:
    //使用flatMap
    list.stream().flatMap(StreamTests::getUpper).forEach(System.out::print);
}

5 sorted

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@Test
public void test5(){
    List<String> list = Arrays.asList("aaa", "ccc", "bbbb", "eeeee");
    //自然排序
    list.stream()
            .sorted()
            .forEach(System.out::println);
    System.out.println("=============");
    //定制排序
    list.stream()
            .sorted((x,y)->{
                //如果长度一样,则按照字典排序
                if (x.length() == y.length()){
                    return x.compareTo(y);
                }
                //如果长度不一样则按照长度的降序排序
                else {
                    return y.length() - x.length();
                }
            })
            .forEach(System.out::println);
 
}
/*结果:
aaa
bbbb
ccc
eeeee
=============
eeeee
bbbb
aaa
ccc
*/

四、终止操作

查找与匹配

1 allMatch

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
Predicate<? super T> predicate
/**
 * @Author: 郜宇博
 * @Date: 2021/9/3 14:00
 * 终止操作
 */
public class FinalOperation {
    static ArrayList<Student> list;
    /**
     * allMath 检查是否全部元素符合
     */
    @BeforeEach
    public void before(){
        //准备集合
        Student student1 = new Student(10,"张三", Student.Status.Sad);
        Student student2 = new Student(20,"李四", Student.Status.Happy);
        Student student3 = new Student(30,"王五", Student.Status.Free);
        Student student4 = new Student(18,"田七", Student.Status.Free);
        Student student5 = new Student(140,"赵六", Student.Status.Tired);
        list = new ArrayList<>();
        list.add(student1);
        list.add(student2);
        list.add(student3);
        list.add(student4);
        list.add(student5);
    }
}
class Student{
    private int age;
    private String name;
    private Status status;
 
    public int getAge() {
        return age;
    }
 
    public String getName() {
        return name;
    }
 
    public Status getStatus() {
        return status;
    }
 
    /**
     * 枚举状态
     */
    public enum Status{
        Free,Tired,Happy,Sad;
    }
 
    public Student(int age, String name, Status status) {
        this.age = age;
        this.name = name;
        this.status = status;
    }
}
/**
     * 是否全部年龄都大于20
     */
    @Test
    public void test1(){
        boolean b = list.stream().allMatch((s) -> s.getAge() > 20);
        System.out.println(b);
    }
//结果: false

2 anyMatch

?
1
2
3
4
5
6
7
8
9
10
Predicate<? super T> predicate
/**
 * 是否存在年龄大于20的
 */
@Test
public void test2(){
    boolean b = list.stream().anyMatch((s) -> s.getAge() > 20);
    System.out.println(b);
}
//结果:true

3 noneMatch

?
1
2
3
4
5
6
7
8
9
10
11
Predicate<? super T> predicate
/**
 * 是否没有满足年龄大于20的
 *
 */
@Test
public void test3(){
    boolean b = list.stream().noneMatch((s) -> s.getAge() > 20);
    System.out.println(b);
}
//结果:false

4 findFirst()

返回第一元素,但结果可能为null, 因此使用Optional<T> 来接收,如果为null则可以替换。

?
1
2
3
4
5
6
7
8
9
10
11
/**
 * 返回第一元素
 */
@Test
public void test4(){
    Optional<Student> first = list.stream()
            .filter((e) -> e.getStatus().equals(Student.Status.Free))
            .findFirst();
    System.out.println(first);
}
//结果:Optional[Student{age=30, name='王五', status=Free}]

5 findAny()

返回任意一个

?
1
2
3
4
5
6
7
8
9
10
11
12
/**
 * 返回任意一个
 *
 */
@Test
public void test5(){
    Optional<Student> b = list.parallelStream()
            .filter((student -> student.getAge()<30))
            .findAny();
     System.out.println(b.get());
}
//结果: 任意一个年龄小于30的学生

6 count

?
1
2
3
4
5
6
7
8
9
/**
 * 获取数量count
 */
@Test
public void test6(){
    long count = list.stream().count();
    System.out.println(count);
}
//结果 : 5

7 max

?
1
2
3
4
5
6
7
8
9
10
11
12
/**
     * 获得最大值
     */
    @Test
    public void test7(){
        Optional<Integer> max = list.stream()
                .map(x->x.getAge())
                .max(Integer::compare);
        System.out.println(max.get());
 
    }
//结果: 140

8 min

?
1
2
3
4
5
6
7
8
9
10
/**
 * 获得最小值
 */
@Test
public void test7(){
    Optional<Integer> max = list.stream()
            .map(x->x.getAge())
            .min(Integer::compare);
    System.out.println(max.get());
}

9 forEach

?
1
2
3
4
5
6
7
8
9
10
11
12
13
@Test
public void test2(){
    //获取一个数组
    ArrayList<Integer> arrayList = new ArrayList<>();
    for (int i = 0; i <10; i++) {
        arrayList.add(i);
    }
    //流操作:获取大于5的
    arrayList.stream().filter((num)->num>5)
                    .limit(2)
                    .forEach(System.out::println);
}
//结果: 6 7

10 reduce

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
     * 归纳
     */
    @Test
    public void test8(){
        Integer reduce = list.stream()
                .map(Student::getAge)
                .reduce(0, (x, y) -> x + y);
        System.out.println(reduce);
        //方法二:
        //此方法有可能为null,因此封装为Optional对象
        Optional<Integer> reduce1 = list.stream()
                .map(Student::getAge)
                .reduce(Integer::sum);
        System.out.println(reduce1.get());
    }

11 collect

可以收集为集合类,

可以在收集后进行分组、多级分组、分片

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
 * 收集
 */
@Test
public void test9(){
    List<Student> collect = list.stream().collect(Collectors.toList());
    collect.forEach(System.out::println);
    //方式二:
    HashSet<Student> collect1 = list.stream().collect(Collectors.toCollection(HashSet::new));
    collect.forEach(System.out::println);
}
/*
结果:Student{age=10, name='张三', status=Sad}
Student{age=20, name='李四', status=Happy}
Student{age=30, name='王五', status=Free}
Student{age=18, name='田七', status=Free}
Student{age=140, name='赵六', status=Tired}
*/
/**
 * 使用收集可以计算最大值、最小值、平均值、等
 * 也可以进行分组
 */
@Test
public void test10(){
    Map<Student.Status, List<Student>> collect = list.stream().collect(Collectors.groupingBy((x) -> x.getStatus()));
    System.out.println(collect.size());
    System.out.println(collect);
}

到此这篇关于JAVA8 Stream学习的文章就介绍到这了,更多相关JAVA8 Stream内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://www.cnblogs.com/Gao-yubo/p/15223669.html

延伸 · 阅读

精彩推荐
  • Java教程Java编程实现的二维数组转置功能示例

    Java编程实现的二维数组转置功能示例

    这篇文章主要介绍了Java编程实现的二维数组转置功能,结合实例形式分析了Java二维数组的遍历、运算、赋值等实现转置的相关操作技巧,需要的朋友可以参考...

    fearlessMore9952021-03-28
  • Java教程JVM垃圾收集器详解

    JVM垃圾收集器详解

    本文主要介绍了JVM垃圾收集器的相关知识。具有很好的参考价值,下面跟着小编一起来看下吧...

    LSPZ5312020-08-11
  • Java教程Java编程简单应用

    Java编程简单应用

    本文主要介绍了三个简单Java小程序———1、HelloWorld(HelloWorld的来源);2、输出个人信息3、输出特殊图案。具有很好的参考价值,下面跟着小编一起来看下...

    疯狂的牛5442020-08-12
  • Java教程浅析Java类和数据结构中常用的方法

    浅析Java类和数据结构中常用的方法

    下面小编就为大家带来一篇浅析Java类和数据结构中常用的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    jingxian2002020-06-09
  • Java教程浅谈JAVA字符串匹配算法indexOf函数的实现方法

    浅谈JAVA字符串匹配算法indexOf函数的实现方法

    这篇文章主要介绍了浅谈字符串匹配算法indexOf函数的实现方法,indexOf函数我们可以查找一个字符串(模式串)是否在另一个字符串(主串)出现过。对此...

    黄林晴3472020-07-15
  • Java教程新闻列表的分页查询java代码实现

    新闻列表的分页查询java代码实现

    这篇文章主要为大家详细介绍了新闻列表的分页查询java代码实现,感兴趣的小伙伴们可以参考一下 ...

    梦牵绕了谁的灵魂2942020-06-04
  • Java教程一个比 Spring Boot 快 44 倍的 Java 框架

    一个比 Spring Boot 快 44 倍的 Java 框架

    light-java是内置了undertow http服务器的REST微服务轻量Java框架,它比Spring Boot内嵌Tomcat这样流行的微服务平台要快44倍,与Go语言fast-http性能接近。...

    开源最前线8962021-05-06
  • Java教程RestTemplate 401 获取错误信息的处理方案

    RestTemplate 401 获取错误信息的处理方案

    这篇文章主要介绍了RestTemplate 401 获取错误信息的处理方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...

    xyw1000011882021-11-24