流的使用

筛选与切片


import java.util.Arrays;
import java.util.List;

/**
 * 筛选与切片
 */
public class FilterDemo {
    public static void main(String[] args){
        List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);

        numbers.stream()
                .filter(i->i%2==0) //使用谓词筛选
                .distinct() //去重
                .forEach(System.out::println);

        numbers.stream()
                .limit(3)//截断流
                .forEach(System.out::println);

        //跳过元素,limit(n)和skip(n)是互补的
        // skip(n)方法,返回一个扔掉了前n个元素的流,如果流中元素不足n个,则返回一 个空流
        numbers.stream()
                .skip(3)
                .forEach(System.out::println);


    }
}

映射


import java.util.Arrays;
import java.util.List;


import static java.util.stream.Collectors.toList;

/**
 * 映射
 */
public class MapDemo {
    public static void main(String[] args){
        List<Apple> appleList = Arrays.asList(new Apple("red",12),new Apple("yellow",15),new Apple("green",10),new Apple("red",10));
        List<Integer> weigths = appleList.stream()
                .map(Apple::getWeight)
                .collect(toList());
//        System.out.println(weigths);
        List<Integer> colorNameLengths = appleList.stream()
                .map(Apple::getColor)//获取每个苹果的颜色
                .map(String::length)//然后获取苹果颜色内容的长度
                .collect(toList());
//        System.out.println(colorNameLengths);

        //流的扁平化
        String[] words = {"Hello","World"};
        List<String> collect = Arrays.stream(words)
                .map(w -> w.split(""))//将每个单词转换为由其字母构成的数组
                .flatMap(Arrays::stream)//将各个生成流扁平化为单个流
                .distinct()
                .collect(toList());
        System.out.println(collect);
    }
}


import java.util.Arrays;
import java.util.List;

import static java.util.stream.Collectors.toList;

/**
 * 映射 练习
 */
public class MapDemo2 {
    public static void main(String[] args){
        //给定一个数字列表,如何返回一个由每个数的平方构成的列表呢?
        // 例如,给定[1, 2, 3, 4,5],应该返回[1, 4, 9, 16, 25]
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        List<Integer> squares = numbers.stream().map(i -> i * i).collect(toList());
        System.out.println(squares);

        //给定列表[1, 2, 3]和列表[3, 4],应 该返回[(1, 3), (1, 4), (2, 3), (2, 4), (3, 3), (3, 4)]
        List<Integer> numbers1 = Arrays.asList(1, 2, 3);
        List<Integer> numbers2 = Arrays.asList(3, 4);

        //使用两个map来迭代这两个列表,并生成数对。但这样会返回一个Stream-
        //<Stream<Integer[]>>。你需要让生成的流扁平化,以得到一个Stream<Integer[]>
        List<int[]> pairs = numbers1.stream()
                .flatMap(i -> numbers2.stream()
                        .map(j -> new int[]{i, j}))
                .collect(toList());

    }
}

查找和匹配


import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * 查找和匹配
 * anyMatch、allMatch和noneMatch这三个操作都用到了我们所谓的短路
 * 不管表达式有多长,你只需找到一个表达式为false,就可以推断整个表达式 将返回false,所以用不着计算整个表达式。这就是短路
 */
public class MatchDemo {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);

        //检查谓词是否至少匹配一个元素
        if (numbers.stream().anyMatch(i->i%2==0)){
            System.out.println("包含偶数");
        }
        //检查谓词是否匹配所有元素
        if (numbers.stream().allMatch(i->i%2==0)){
            System.out.println("全是偶数");
        }

        if (numbers.stream().noneMatch(i->i%2==0)){
            System.out.println("没有偶数");
        }

        //查找元素
        //Optional<T>类(java.util.Optional)是一个容器类,代表一个值存在或不存在
        // - isPresent()将在Optional包含值的时候返回true, 否则返回false。
        // - ifPresent(Consumer<T> block)会在值存在的时候执行给定的代码块。Consumer函数式接口;它让你传递一个接收T类型参数,并返回void的Lambda表达式。
        // - T get()会在值存在时返回值,否则抛出一个NoSuchElement异常。
        // - T orElse(T other)会在值存在时返回值,否则返回一个默认值。
        Optional<Integer> number = numbers.stream()
                .filter(i -> i % 2 == 0)
                .findAny();
        System.out.println(number.get());//T get()会在值存在时返回值

        numbers.stream()
                .filter(i -> i % 2 == 0)
                .findAny()
                .ifPresent(System.out::println);//如果包含一个 值就打印它,否则什么都不做

        //查找第一个元素
        System.out.println(numbers.stream()
                .filter(i -> i % 2 != 0)
                .findFirst()
                .orElse(-1));

    }
}

归约(折叠)


import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
* 归约(折叠)
* 将流中所有元素反复结合起来,得到一个值
*/
public class FoldDemo {
   public static void main(String[] args) {
       //元素求和
       List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
       int sum = 0;
       for (Integer x : numbers) {
           sum += x;
       }
       System.out.println(sum);

       //    T reduce(T identity, BinaryOperator<T> accumulator);
       // reduce接受两个参数:
       //  一个初始值,这里是0;
       //  一个BinaryOperator<T>来将两个元素结合起来产生一个新值,这里我们用的是 lambda (a, b) -> a + b
       // reduce操作是如何作用于一个流的:Lambda反复结合每个元素,直到流被归约成一个值
       int sum2 = numbers.stream().reduce(0, (a, b) -> a + b);
       int sum3 = numbers.stream().reduce(0, Integer::sum);
       System.out.println(sum3);
       // 无初始值
       // reduce操作无法返回其和,因为它没有初始值
       Optional<Integer> sumOp = numbers.stream().reduce(Integer::sum);
       System.out.println(sumOp.get());

       //最大值和最小值
       System.out.println(numbers.stream().reduce((x, y) -> x > y ? x : y).get());
       System.out.println(numbers.stream().reduce(Integer::max).get());

       //计算流中元素的个数
       System.out.println(numbers.stream().map(d -> 1)
               .reduce(Integer::sum).get());
       //内置count方法可用来计算流中元素的个数
       System.out.println(numbers.stream().count());
   }
}

posted @ 2020-04-06 16:28  fly_bk  阅读(200)  评论(0编辑  收藏  举报