Scott の 博客 Scott の 博客
首页
  • Data Structure and Algorithm
  • Java
  • 面试
  • Drafts
  • C++
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Scott

恋爱中
首页
  • Data Structure and Algorithm
  • Java
  • 面试
  • Drafts
  • C++
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Data Structure and Algorithm

  • Java

    • Java基础知识&面试题总结
    • Java
    • Control Flow
    • Clean Coding
    • Debugging and Deployment
    • Untitled
    • Refactor towards OOSD
    • Inheritance
    • Untitled
    • Exceptions
    • Generics
    • Collections
    • Lambda-Expression
    • Streams
      • Imperative VS Functional Programming
      • Creating a Stream
      • Mapping Elements
      • Filtering Elements
      • Slicing Streams
      • Sorting Streams
      • Getting Unique Elements
      • Peeking Elements
      • Simple Reducers
      • Reducing a Stream
      • Collectors
      • Grouping Elements
      • Partitioning Elements
      • Primitive Type Streams
    • Concurrency and Multi-threading
    • The Executive Framework
    • 4
    • 1
  • c++

  • 面试

  • Bilibili_Java

  • Python

  • All kinds of Drafts

  • High Integrity Information System

  • 左神算法课

  • 个人笔记
  • Java
Scott
2022-06-14
目录

Streams

  1. Imperative VS Functional Programming
  2. Creating a Stream
  3. Mapping Elements
  4. Filtering Elements
  5. Slicing Streams
  6. Sorting Streams
  7. Getting Unique Elements
  8. Peeking Elements
  9. Simple Reducers
  10. Reducing a Stream
  11. Collectors
  12. Grouping Elements
  13. Partitioning Elements
  14. Primitive Type Streams

# Imperative VS Functional Programming

image-20220124094339569

  • Imperative: specify how something should be done

  • Declarative: express logic in terms of what needs to be done (SQL)

  • Functional programming is a special type of declarative programming

  • Streaming allow us to process a collection of data in a declarative/functional way

  • stream() returns a sequence of object

    • It doesn't store data
    • It is just a way to get data out of the collection
    • e.g. get water out of water tank

image-20220124094836759

public class Movie implements Comparable<Movie> {
    private String title;
    private int likes;
}

public class StreamsDemo {
    public static void show() {
        List<Movie> movies = List.of(
            new Movie("a", 10),
            new Movie("b", 15),
            new Movie("c", 20),
        );
        
        // imperative programming (a programming paradigm or a style of programming)
        // 	there are statements that specify how something should be done
        int count = 0; 
        for (var movie : movies) {
            if (movie.getLikes() > 10)
                count++;
        }
        
        // declarative programming (more functional because there are many functions) 
        var count2 = movies.stream()
              .filter(movie -> movie.getLikes() > 10);
        	  .count();
    }
}
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

# Creating a Stream

  • From
    • Collections
    • arrays
    • An arbitrary number of objects
    • Infinite/finite streams
public class CreatingStreamsDemo {
  public static void show() {
    // From a collection
    List<Integer> list = new ArrayList<>();
    list.stream()
        .forEach(n -> System.out.println(n));

    // From an array
    int[] array = { 1, 2, 3 };
    Arrays.stream(array)
          .forEach(n -> System.out.println(n));

    // From an arbitrary number of objects
    Stream.of(1, 2, 3)
          .forEach(n -> System.out.println(n));

    // Generate from scratch; infinite stream, not gonna crash
      // Math.random() is called everytime
    Stream.generate(() -> Math.random())
          .limit(3) // if not limited, it will run forever
          .forEach(n -> System.out.println(n));

    // Generate from scratch
    Stream.iterate(1, n -> n + 1) // start with 1, increment
          .limit(10)
          .forEach(n -> System.out.println(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

# Mapping Elements

public class StreamsDemo {
    public static void show() {
        var movies = List.of(
            new Movie("a", 10),
            new Movie("b", 15),
            new Movie("c", 20),
        );
        
        movies.stream()
              .map(movie -> movie.getTitle())
              .forEach(name -> System.out.println(name)); // apply to every movie
        
        // Stream<List<x>> -> Stream<x>
        var stream = Stream.of(List.of(1,2,3), List.of(4,5,6));
        stream.flatMap(list -> list.stream())
              .forEach(n -> System.out.println(name))
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# Filtering Elements

public class StreamsDemo {
    public static void show() {
        var movies = List.of(
            new Movie("a", 10),
            new Movie("b", 15),
            new Movie("c", 20),
        );
        
        var filtered = movies.stream()
              .filter(movie -> movie.getLikes() > 10)
              .forEach(System.out.println(moive.getTitle));
        
        Predicate<Movie> isPopular = m -> m.getLikes() > 10;
        var filtered = movies.stream()
              .filter(isPopular)
              .forEach(System.out.println(moive.getTitle));
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  • Two types of operation of stream methods
    • Intermediate
      • map
      • filter
      • They return a new stream, so that data can be continuously transferred
    • Terminal
      • forEach
      • Consume a stream
      • If not called, nothing is done
      • So it is very important to include terminal operation to the stream methods

# Slicing Streams

  • limit(n) limit the number of elements in a stream
  • skip(n) skip a number of elements in a stream
  • takeWhile(predicate)as long as the predicate is true, keep taking the elements
    • filter(predicate)will loop over the the entire stream
  • dropWhile(predicate)
public class StreamsDemo {
    public static void show() {
        var movies = List.of(
            new Movie("a", 10),
            new Movie("b", 15),
            new Movie("c", 20),
        );
       	
        // pagination for third page
        movies.stream()
              .skip(20) // skip the 20 items in the first two page
              .limit(10) // show 10 items in the third page
              .forEach(m - Sout(m));
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# Sorting Streams

public class StreamsDemo {
    public static void show() {
        var movies = List.of(
            new Movie("a", 10),
            new Movie("c", 15),
            new Movie("b", 20),
        );
       	
        movies.stream()
              .sorted((a, b) -> a.getTitle().compareTo(b.getTitle()));
        	  .forEach(m -> System.out.println(m.getTitle()));
        
        // simplify 
        movies.stream()
              .sorted(Comparator.comparing(m -> m.getTitle()));
        	  .forEach(m -> System.out.println(m.getTitle()));
        
        // simplify 
        movies.stream()
              .sorted(Comparator.comparing(Movie :: getTitle));
        	  .forEach(m -> System.out.println(m.getTitle()));
        
        // descending order
        movies.stream()
              .sorted(Comparator.comparing(Movie :: getTitle).reversed());
        	  .forEach(m -> System.out.println(m.getTitle()));
    }
}
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

# Getting Unique Elements

public class StreamsDemo {
    public static void show() {
        var movies = List.of(
            new Movie("a", 10),
            new Movie("a", 10),
            new Movie("c", 15),
            new Movie("b", 20),

        );
       	
        movies.stream()
              .map(Movie::getLikes)
              .distinct()   // return distinct values 
              .forEach(System.out::println);
        
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# Peeking Elements

  • Add more messages
  • Good for troubleshooting problems
public class StreamsDemo {
    public static void show() {
        var movies = List.of(
            new Movie("a", 10),
            new Movie("c", 15),
            new Movie("b", 20),

        );
       	
        movies.stream()
              .filte(m -> m.getLikes() > 10)
              .peek(m -> System.out.println("filtered: " + m.getTitle())) // intermediate operation 
              .map(Movie::getTitle) // matching each movie to its title
              .peek(t -> System.out.println("mapped: " + t))
              .forEach(System.out::println); // terminal operation and returns void
        		// cannot call other operations after `forEach`
        
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# Simple Reducers

  • Reducers are a group of operations that reduces a stream of objects to a single object
  • They are terminal operations
    • They produce a result
    • We cannot call any other operations after that
  • e.g.
    • count()
      • It counts the number of elements in a stream
      • It reduces a stream to the number of elements in that stream
    • anyMatch(predicate)
    • allMatch(predicate)
    • noneMatch(predicate)
      • See if any or all elements in a stream satisfy the condition
    • findFirst()
    • findAny()
    • max(comparator)
    • min(comparator)
      • Find the maximum or minimum element based on a comparator
public class StreamsDemo {
    public static void show() {
        var movies = List.of(
            new Movie("a", 10),
            new Movie("c", 15),
            new Movie("b", 20),

        );
       	
        movies.stream()
              .count();
        var result = movies.steram()
              .anyMatch(m -> m.getLikes() > 20); // returns a boolean 
        
        movies.stream()
              .findFirst()
              .get();
        
        movies.stream()
              .max(Comparator.comparing(Movie::getLikes)) // maximum likes
              .get(); 
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# Reducing a Stream

public class StreamsDemo {
    public static void show() {
        var movies = List.of(
            new Movie("a", 10),
            new Movie("c", 15),
            new Movie("b", 20),

        );
       	
        // [10, 20, 30]
        // [30, 30]
        // [60]
        // optional may have value or may not (when the stream is empty)
        Optional<Integer> sum = movies.stream()
              .map(Movie::getLikes)
              .reduce((a, b) -> a + b);

        System.out.println(sum.orElse(0)); // may have value or return the default 0 value
        
        
        Integer sum = movies.stream()
              .map(Movie::getLikes)
              .reduce(0, Integer::sum);

        System.out.println(sum); // may have value or return the default 0 value
    }
}
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

# Collectors

  • We want to collect the result of a stream into a data structure like a list, a set or a map
public class StreamsDemo {
    public static void show() {
        var movies = List.of(
            new Movie("a", 10),
            new Movie("c", 15),
            new Movie("b", 20),

        );
       	
        var result = movies.stream()
              .filter(m -> m.getLikes() > 10)
              .collect(Collectors.toList()); // return a stream into a list 
              .collect(Collectors.toSet());
              .collect(Collectors.toMap(Movie::getTitle(), Movie::getLikes())); // key-value pair
        	  .collect(Collectors.toMap(Movie::getTitle(), Function.identity())); // value is the movie object 
        	  .collect(Collectors.summingInt(Movie::getLikes)); // sum up the number of likes of all movies
        	  .collect(Collectors.summingDouble(Movie::getLikes));
        
        var result = movies.stream()
              .filter(m -> m.getLikes() > 10)
              .map(Movie::getTitle)
              .collect(Collectors.joining(", ")) // return: b, c
            
    }
}
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

# Grouping Elements

package com.codewithmosh.streams;

public enum Genre {
    COMEDY,
    ACTION,
    THRILLER
}

public class Movie implements Comparable<Movie> {
    private String title;
    private int likes;


    private Genre genre;

    public Movie(String title, int likes, Genre genre) {
        this.title = title;
        this.likes = likes;
        this.genre = genre;
    }
    
    public Genre getGenre() {
        return genre;
    }
}

public class StreamsDemo {
    public static void show() {
        var movies = List.of(
            new Movie("a", 10, Genre.THRILLER),
            new Movie("c", 15, Genre.ACTION),
            new Movie("b", 20, Genre.ACTION),
        );
        
        var result = movies.stream()
            .collect(Collectors.groupingBy(Movie::getGenre, Collectors.toSet()));
        // or
        	.collect(Collectors.groupingBy(Movie::getGenre, Collectors.counting()));
        // or 
        	.collect(Collectors.groupingBy(
                Movie::getGenre,
                Collectors.mapping(
                    Movie::getTitle, 
                    Collectors.joining())));
        	 
    }
}
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

# Partitioning Elements

public class StreamsDemo {
    public static void show() {
        var movies = List.of(
            new Movie("a", 10, Genre.THRILLER),
            new Movie("c", 15, Genre.ACTION),
            new Movie("b", 20, Genre.ACTION),
        );
        
        var result = movies.stream()
        	.collect(Collectors.partitioningBy(
                m -> m.getLikes() > 20,
                Collectors.mapping(
                    Movie::getTitle, 
                    Collectors.joining(",  "))));
        // result = {false=a, b, true=c}
        	 
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# Primitive Type Streams

image-20220217145222379

public class StreamsDemo {
    public static void show() {
        IntStream.rangeClosed(1,5)
            .forEach(System.out::println); // print 1 to 4
    }
}
1
2
3
4
5
6
上次更新: 2022/12/04, 16:55:22
Lambda-Expression
Concurrency and Multi-threading

← Lambda-Expression Concurrency and Multi-threading→

最近更新
01
day01-Java基础语法
08-31
02
1
08-29
03
路线
08-01
更多文章>
Theme by Vdoing | Copyright © 2019-2022 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×