每日JAVA--day03(2020.01.03)

浪子不回头ぞ 提交于 2020-01-28 11:46:47

每日JAVA–day03

JAVA8 Stream

Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。Stream API 借助于同样新出现的 Lambda 表达式,极大的提高编程效率和程序可读性。
同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用 fork/join 并行方式来拆分任务和加速处理过程。通常编写并行代码很难而且容易出错, 但使用 Stream API 无需编写一行多线程的代码,就可以很方便地写出高性能的并发程序。

  1. 聚合操作:
    对一个数据集合的数进行处理,如分类,取最值,去重等操作
  2. Stream类似迭代器,进行遍历对数据进行操作,不同的是Stream可以并行化的执行操作(Fork/Join 框架),Stream 的另外一大特点是,数据源本身可以是无限的。

Stream三种操作

1,Intermediate(相当于添加遍历时的操作)

map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered

  • 一个流可以后面跟随零个或多个 intermediate 操作。其目的主要是打开流,做出某种程度的数据映射/过滤,然后返回一个新的流,交给下一个操作使用。这类操作都是惰性化的(lazy),就是说,仅仅调用到这类方法,并没有真正开始流的遍历。

2,Terminal(相当于根据操作进行遍历,遍历后流消失)

forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator

  • 一个流只能有一个 terminal 操作,当这个操作执行后,流就被使用“光”了,无法再被操作。所以这必定是流的最后一个操作。Terminal 操作的执行,才会真正开始流的遍历,并且会生成一个结果,或者一个 side effect。

3,short-circuiting(操作无限大的数据源时使用)

anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 limit

  • 对于一个 intermediate 操作,如果它接受的是一个无限大(infinite/unbounded)的 Stream,但返回一个有限的新 Stream。
  • 对于一个 terminal 操作,如果它接受的是一个无限大的 Stream,但能在有限的时间计算出结果。

1,获取流,流转换

public class StreamTest {
    public static void main(String[] args) {

// 1. Individual values
        Stream<String> stream = Stream.of("a", "b", "c");
// 2. Arrays
        String[] strArray = new String[] {"a", "b", "c"};
        stream = Stream.of(strArray);
        stream = Arrays.stream(strArray);
// 3. Collections
        List<String> list = Arrays.asList(strArray);
        stream = list.stream();
// 4. IntStream、LongStream、DoubleStream
        int[] arrInt = new int[]{1,4,34,5};
        //IntStream.of(arrInt).forEach(System.out::print);
        //返回1234567
        IntStream.range(1, 8).forEach(System.out::print);
// 5.流转换为集合等其他数据结构(每个流只能使用一次)
        String[] strArray1 = (String[]) stream.toArray(String[]::new);
        stream = list.stream();
        List<String> list1 = (List<String>) stream.collect(Collectors.toList());
        stream = list.stream();
        List<String> list2 = (List<String>) stream.collect(Collectors.toCollection(ArrayList::new));
        stream = list.stream();
        Set set1 = (Set) stream.collect(Collectors.toSet());
        stream = list.stream();
        Stack stack1 = (Stack) stream.collect(Collectors.toCollection(Stack::new));
    }
}

2,遍历集合(Terminal)

forEach之后流不可以再被使用

public class StreamTest {
    public static void main(String[] args) {
        String[] arr = {"cde","bcd","abc","efg","fgh", "def"};
        List<String> list = Arrays.asList(arr);
        //获取流
        Stream<String> stringStream = list.stream();
        //遍历输出
        stringStream.forEach(System.out::println);
    }
}

3,map的使用(Intermediate)

它的作用就是把 input Stream 的每一个元素,映射成 output Stream 的另外一个元素

public class StreamTest {
    public static void main(String[] args) {
        //map的使用
        String[] arr = {"cde","bcd","abc","efg","fgh", "def"};
        List<String> list = Arrays.asList(arr);
        //获取流
        Stream<String> stringStream = list.stream();
        //转换大小写,输出
        stringStream.map(String::toUpperCase).forEach(System.out::println);
    }
}

4,flatMap的使用(Intermediate)

一对多的使用,flatMap 把 input Stream 中的层级结构扁平化,就是将最底层元素抽出来放到一起,最终 output 的新 Stream 里面已经没有 List 了,都是直接的数字。

public class StreamTest {
    public static void main(String[] args) {
        //map的使用
        String[] arr = {"cde","bcd","abc","efg","fgh", "def"};
        String[] arr2 = {"xxx","yyy","zzz"};
        List<String> list = Arrays.asList(arr);
        List<String> list2 = Arrays.asList(arr2);
        //获取流
        Stream<List<String>> inputStream = Stream.of(list,list2);
        inputStream.flatMap((childList) -> childList.stream()).forEach(System.out::println);
    }
}

5,filter(Intermediate)

过滤数据

public class StreamTest {
    public static void main(String[] args) {
        //map的使用
        String[] arr = {"cde","bdcd","abc","cfg","fgh", "def"};
        String[] arr2 = {"aaa","bcdd","abcd"};
        List<String> list = Arrays.asList(arr);
        //获取流
        Stream<String[]> inputStream = Stream.of(arr, arr2);
        inputStream.flatMap(childList -> Arrays.stream(childList))
                //取长度大于3的字符串
                .filter(string -> string.length() > 3)
                .forEach(System.out::println);
    }
}

6,peek (Intermediate)

对每一个元素执行操作后返回新的流,forEach之后流就不可以使用了

public class StreamTest {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(new Integer[]{1,2,3,4,5});
        list = list.stream().filter(num -> num>3)
                .peek(num ->
                        System.out.println("获取到了"+num)
                ).peek(num ->
                        System.out.println("获取到了"+num)
                )
                .collect(Collectors.toList());
        System.out.println(list);
    }
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!