Java8-12-stream use stream

This series of articles comes from the

original CSDN address:

https://blog.csdn.net/ryo1060732496/article/details/88806298

Many operations supported by StreamAPI allow you to quickly complete complex data queries, such as filtering, slicing, mapping, searching, matching, and reduction.

Slicing and screening

1. Use predicate filter (filter)
Streams interface supports filter method. The operation receives a predicate (a function that returns a boolean) as a parameter and returns a stream that includes all elements that match the predicate.

List<Dish> vegetarianDishes = menu.stream()
                        //方法引用检查菜肴是否适合素食者
                        .filter(Dish::isVegetarian)
                        .collect(toList());

2. Filter different elements (distinct)

List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);
numbers.stream()
        .filter(i -> i % 2 == 0)
        .distinct()
        .forEach(System.out::println);

3. The limit
stream supports the limit(n) method, which returns a stream that does not exceed a given length.

// 选出热量超过300卡路里的头三道菜
List<Dish> dishes = menu.stream()
                .filter(d -> d.getCalories() > 300)
                .limit(3)
                .collect(toList());

4. The skip element (skip)
stream also supports the skip(n) method, which returns a stream with the first n elements discarded. If there are less than n elements in the stream, an empty stream is returned. Please note that limit(n) and skip(n) are complementary!

// 跳过超过300卡路里的头两道菜,并返回剩下的
List<Dish> dishes = menu.stream()
                .filter(d -> d.getCalories() > 300)
                // 跳过前两个
                .skip(2)
                .collect(toList());
dishes.forEach(dish -> System.out.println(dish.getName()));

Mapping

A very common data processing routine is to select information from certain objects. For example, in SQL, you can select a column from the table. The Stream API also provides similar tools through the map and flatMap methods.

1. Apply a function (map) to each element in the
stream. The stream supports the map method, which accepts a function as a parameter. This function will be applied to each element and map it to a new element (the term mapping is used because it is similar to conversion, but the subtle difference is that it is "create a new version" instead of going "modify").

// 获取菜名
List<String> dishNames = menu.stream()
                .map(Dish::getName)
                .collect(toList());
System.out.println(dishNames);

// 获取菜名长度
List<Integer> len = menu.stream()
                .map(dish -> dish.getName().length())
                .collect(toList());
System.out.println(len);

2. Stream flatmap (flatMap)
For a word list, how to return a list with different characters in it? For example, given a list of words ["Hello","World"], you want to return the list ["H","e","l", "o","W","r","d"]

List<String> words = Arrays.asList("Hello", "World");
List<String[]> wordList = words.stream()
        .map(word -> word.split(""))
        .distinct()
        .collect(Collectors.toList());
wordList.forEach(wordArray -> {
    
    
    for (String s : wordArray) {
    
    
        System.out.print(s);
    }
    System.out.println();
});

Results of the

Hello
World

After the execution, it was wrong. Think about it carefully: We divide the two words ["Hello", "World"] into character arrays, ["H", "e", "l", "l", "o"], ["W","o","r","l","d"]. Then use this character array to determine whether it is repeated, not whether a character is repeated, but whether this character array is repeated. So, the printout is Hello World.

flatMap introduced

We need a character stream, not an array stream. There is a method called Arrays.stream() that can receive an array and produce a stream.

String[] arrayOfWords = {
    
    "Hello", "World"};
Stream<String> streamOfwords = Arrays.stream(arrayOfWords);

stream.forEach(System.out::println);

result:

Hello
World

Using map and Arrays.stream() is obviously not enough. This is because what you get now is a list of streams (streams more precisely). Indeed, you first convert each word into an array of letters, and then turn each array into an independent stream.

Use flatMap
String[] arrayOfWords = {
    
    "Hello", "World"};
        // 将数组转化为流,此时应该是两个字符串数组流:["Hello","World"]
        List<String> uniqueCharacters = Arrays.stream(arrayOfWords)
                // 拆分为字符数组流,此时应该是两个字符数组流:["H","e","l","l","o"],["W","o","r","l","d"]
                .map(w -> w.split(""))
                // 把两个字符数组流扁平化为一个流:["H","e","l","l","o","W","o","r","l","d"]
                .flatMap(Arrays::stream)
                // 去重
                .distinct()
                // 终端操作
                .collect(Collectors.toList());
        // HeloWrd
        uniqueCharacters.forEach(System.out::print);

The effect of using the flatMap method is that each array is not mapped into a stream, but is mapped into the content of the stream. All the single streams generated when using map(s -> split("")) are combined, that is, flattened into one stream.
In a nutshell, the flatMap method allows you to replace every value in one stream with another stream, and then connect all the streams into one stream.

Matching element

Another common data processing routine is to see if certain elements in the data set match a given attribute. StreamAPI provides such tools through allMatch, anyMatch, noneMatch, findFirst, and findAny methods.

1. Check whether the predicate matches at least one element (anyMatch) The
anyMatch method can answer "whether there is an element in the stream that matches the given predicate".

// 菜单里面是否有素食可选择
if(menu.stream().anyMatch(Dish::isVegetarian)){
    
    
    System.out.println("有素菜,不用担心!");
}

The anyMatch method returns a boolean, so it is a terminal operation.

2. Check whether the predicate matches all elements (allMatch) The
allMatch method can answer whether the elements in the stream can match the given predicate.

// 菜品是否有利健康(即所有菜的热量都低于1000卡路里)
boolean isHealthy = menu.stream().allMatch(d -> d.getCalories() < 1000);

3. Ensure that there is no matching element in the stream (noneMatch) The
noneMatch method ensures that no element in the stream matches the given predicate.

boolean isHealthy = menu.stream().noneMatch(d -> d.getCalories() >= 1000);

The three operations anyMatch, allMatch, and noneMatch all use what we call short-circuit, which is the familiar version of the && and || operator short-circuit in the stream in Java.

Find element

1. Any element in the current stream

Optional<Dish> dish = menu.stream()
                .filter(Dish::isVegetarian)
                .findAny();

What is returned is an Optional. The Optional class (java.util.Optional) is a container class that represents the presence or absence of a value.

2. Find the first element

// 给定一个数字列表,下面的代码能找出第一个平方能被3整除的数
List<Integer> someNumbers = Arrays.asList(1, 2, 3, 4, 5, 6);
Optional<Integer> firstSquareDivisibleByThree =
        someNumbers.stream()
                .map(x -> x * x)
                .filter(x -> x % 3 == 0)
                // 9
                .findFirst();

Reduce

1. Element summation
You can sum all the elements in the stream as follows:

List<Integer> numbers = Arrays.asList(3, 4, 5, 1, 2);
int sum = numbers.stream().reduce(0, (a, b) -> a + b);
// 15
System.out.println(sum);

// 元素相乘
numbers.stream().reduce(1, (a, b) -> a * b);

2. Combine with method references

int sum2 = numbers.stream().reduce(0, Integer::sum);

3.
There is an overloaded variant of reduce without initial value . It does not accept an initial value, but returns an Optional object.

Optional<Integer> sum = numbers.stream().reduce((a, b) -> (a + b));

Consider the case where there are no elements in the stream. The reduce operation cannot return its sum because it has no initial value. This is why the result is wrapped in an Optional object to indicate that the sum may not exist.

4. Maximum and minimum

// 最大值
Optional<Integer> max = numbers.stream().reduce(Integer::max);

// 最小值
Optional<Integer> min = numbers.stream().reduce(Integer::min);

The reduce operation will consider the new value and the next element in the stream, and produce a new maximum value until the entire stream is consumed!

Guess you like

Origin blog.csdn.net/weixin_43298913/article/details/106121476