Tell you with a streamlined, optimized code the way

Relative to the previous Java8 Java-related operations is simply bad days to do, there Java8 streaming operations, but also to a large extent changed the developer impression of cumbersome operation of Java, from now on, but also to the functional Java programming on the road!

I believe that long-term use, will be able to streamline your code, write more smoothly, you will love it!

Creating a stream

Create a method 1.1 stream

Since the flow of the operation need to talk, then, above all, take a look at how to create a flow.

There are three ways to create flow, namely: Stream.of (), Stream.iterate (), Stream.generate (), then look at each statement of these three methods.

static <T> Stream<T> of(T... values)
static <T> Stream<T> iterate(T seed, UnaryOperator<T> f)
static <T> Stream<T> generate(Supplier<T> s)
复制代码
  • Stream.of(): Parameter It is simply a series of generic parameters.
  • Stream.iterate(): The first parameter is an initial value, the second parameter is an operation.
  • Stream.generate(): Parameter supply parameter is the type of a Supplier.

The method of Example 1.2 Create stream

/*
     * @Author 欧阳思海
     * @Description  创建流
     * @Date 11:05 2019/8/26
     * @Param []
     * @return void
     **/
    @Test
    public void testCreateStream() {
        //利用Stream.of方法创建流
        Stream<String> stream = Stream.of("hello", "world", "Java8");
        stream.forEach(System.out::println);
        System.out.println("##################");
        //利用Stream.iterate方法创建流
        Stream.iterate(10, n -> n + 1)
                .limit(5)
                .collect(Collectors.toList())
                .forEach(System.out::println);
        System.out.println("##################");
        //利用Stream.generate方法创建流
        Stream.generate(Math::random)
                .limit(5)
                .forEach(System.out::println);
        System.out.println("##################");
        //从现有的集合中创建流
        List<String> strings = Arrays.asList("hello", "world", "Java8");
        String string = strings.stream().collect(Collectors.joining(","));
        System.out.println(string);
    }
复制代码

In the above example, the parameter Stream.of () method is several strings, the first parameter Stream.iterate () method is an initial value of 10, the second parameter is based on 10 increments by 1 operation, Stream.generate () parameter is a random number generated by random methods.

1.3 Creating summary stream

There are three ways to create a flow, respectively Stream.of()、Stream.iterate()、Stream.generate(), these are static methods of the Stream class, so use very convenient.

2 the operation flow

In the previous section, we know how to create a flow, then, we take a look at what was possible convection, using the Stream after stream, whether it much more convenient than before Java8?

2.1 Packing stream

When processed streams, static methods can be used to convert a set of class Collectors, e.g., the stream is converted to a string List<String>, in this way there is no problem.

However, if you want to experience double flow converted to List, which is'll get an error.

DoubleStream.of(1.0, 2.0, 3.0)
             .collect(Collectors.toList());//错误的写法
复制代码

This way is wrong, the compiler is not passed.

Do not panic, for this problem, there are three better solution.

Using the boxed method

The method of using the boxed, DoubleStream may be converted to Stream<Double>, for example;

DoubleStream.of(1.0, 2.0, 3.0)
                .boxed()
                .collect(Collectors.toList());
复制代码

This would solve the above problems.

Using the method mapToObj

The method may also be implemented using mapToObj the above features, in addition, also provides mapToInt, mapToLong, mapToDouble convert a basic type or the like for the relevant type of packaging stream.

DoubleStream.of(1.0, 2.0, 3.0)
                .mapToObj(Double::valueOf)
                .collect(Collectors.toList());
复制代码

collect method

In general, when we use the method collect, for all data collected as a set of basic flow type , for example;

stream.collect(Collectors.toList())
复制代码

However, collect method in fact there is a more generalized form, as follows;

<R> R collect(Supplier<R> supplier,
                        ObjIntConsumer<R> accumulator,
                        BiCnsumer<R,R> combiner)
复制代码

This method of the above first parameter is a feeder, a container is equivalent to initialize, the second argument is the accumulator, which is equivalent to the initialization container assignment combiner third parameter is equivalent to all of these elements combined into one container .

Now, let's look at a simple example in the end is how to use!

List<Double> list = DoubleStream.of(1.0, 2.0, 3.0)
                .collect(ArrayList<Double>::new, ArrayList::add, ArrayList::addAll);
复制代码

The example above we can see that the first argument: using a static method to initialize a List container, the second argument: using a static method add, add elements, the third parameter: Use the static method addAll, for the union of all the element.

The return value from the last List<Double>, we can see, all combined into a set of List of initialization.

Conversion between the string and the flow 2.2

This section briefly explain convert between strings and streams flow into the String There are two methods, namely, java.lang.CharSequencethe default method interface definition charsand codePoints, while the circulation of a string is what we have already explained the method to collect.

/*
     * @Author 欧阳思海
     * @Description  字符串与流之间的转换
     * @Date 9:41 2019/9/2
     * @Param []
     * @return void
     **/
    @Test
    public void testString2Stream() {
        String s = "hello world Java8".codePoints()//转换成流
                .collect(StringBuffer::new,
                        StringBuffer::appendCodePoint,
                        StringBuffer::append)//将流转换为字符串
                .toString();

        String s1 = "hello world Java8".chars()//转换成流
                .collect(StringBuffer::new,
                        StringBuffer::appendCodePoint,
                        StringBuffer::append)//将流转换为字符串
                .toString();
    }
复制代码

In the above example, the first conversion method codePoints flow chars and then back again collect method is the use of a string.

FlatMap 2.3 of map with stream

Map stream is what this means, we have a first example of the prior Java8, one object field we often need to be taken out of a set, and then to another set of stored , this scenario we before we Java8 It will be achieved.

/*
     * @Author 欧阳思海
     * @Description  Java8之前的用法
     * @Date 19:31 2019/9/2
     * @Param []
     * @return void
     **/
    @Test
    public void testList() {
        List<Person> list = new ArrayList<>();
        List<Friend> friends = new ArrayList<>();
        friends.add(new Friend("Java5"));
        friends.add(new Friend("Java6"));
        friends.add(new Friend("Java7"));
        Person person = new Person();
        person.setFriends(friends);
        list.add(person);
        List<String> strings = new ArrayList<>();
        for(Person p : list){
            strings.add(p.getName());
        }
    }
复制代码

Is not this a lot of trouble, which is before everyone's been talking about a trick with Python, Java need to use tricks!

However, Java8 has changed this reality, we take a look at how to use map and flatMap.

First, we look at the statement and maybe has a method;

<R> Stream<R> map(Function<? super T,? extends R> mapper)

<R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper)
复制代码

Next, we use these two methods to rewrite the above way, take a look at the map method;

/*
     * @Author 欧阳思海
     * @Description  map、flatMap方法
     * @Date 9:50 2019/9/2
     * @Param []
     * @return void
     **/
    @Test
    public void testMapAndFlatMap() {
        List<Person> list = new ArrayList<>();
        List<Friend> friends = new ArrayList<>();
        friends.add(new Friend("Java5"));
        friends.add(new Friend("Java6"));
        friends.add(new Friend("Java7"));
        Person person = new Person();
        person.setFriends(friends);
        list.add(person);

        //映射出名字
        List<String> strings = list.stream().map(Person::getName).collect(Collectors.toList());
    }
复制代码

By using the map method, parameters given Person :: getName mapping out the name, and then collect the collection to a List, completed in charge of the operation above, it is not very comfortable.

However, if we want to use a map method map attribute friends, encountered a problem;

//映射出朋友
        List<List<Friend>> collect = list.stream().map(Person::getFriends).collect(Collectors.toList());
复制代码

We found that the return value is above List<List<Friend>>, this form of collection which also wrapped collection, handling a little trouble, but not there is another flatMap not to use it, this method just to be able to solve this problem.

List<Friend> collect1 = list.stream().flatMap(friend -> friend.getFriends().stream()).collect(Collectors.toList());
复制代码

Found that this method is the return value List<Friend>, as we have seen, the method flatMap able to "flatten" flow-wrapped, which is the difference between the map and flatMap.

Connecting flow 2.4

There are two ways connected to the flow, if it is connected to two streams, using Stream.concat method, if it is connected to three or more streams and three, use Stream.flatMap method.

/**
     * @return void
     * @Author 欧阳思海
     * @Description 流的连接
     * @Date 10:13 2019/9/2
     * @Param []
     **/
    @Test
    public void testConcatStream() {
        //两个流的连接
        Stream<String> first = Stream.of("sihai", "sihai2", "sihai3");
        Stream<String> second = Stream.of("sihai4", "sihai5", "sihai6");
        Stream<String> third = Stream.of("siha7", "sihai8", "sihai9");
        Stream<String> concat = Stream.concat(first, second);

        //多个流的连接
        Stream<String> stringStream = Stream.of(first, second, third).flatMap(Function.identity());

    }
复制代码

Reduction operation flow 3

Statute of the flow of the operation of several types, here to talk about.

Built-in operations Statute

Basic types stream has a built-in operation of the statute. Including average、count、max、min、sum、summaryStatisticsseveral methods previously believed Needless to say, summaryStatisticsthe method is a combination of several methods previously, let's look at how to use them.

/**
     * @return void
     * @Author 欧阳思海
     * @Description 内置规约操作
     * @Date 22:04 2019/9/1
     * @Param []
     **/
    @Test
    public void testReduce1() {
        String[] strings = {"hello", "sihai", "hello", "Java8"};
        long count = Arrays.stream(strings)
                .map(String::length)
                .count();
        System.out.println(count);

        System.out.println("##################");

        int sum = Arrays.stream(strings)
                .mapToInt(String::length)
                .sum();
        System.out.println(sum);

        System.out.println("##################");

        OptionalDouble average = Arrays.stream(strings)
                .mapToInt(String::length)
                .average();
        System.out.println(average);

        System.out.println("##################");

        OptionalInt max = Arrays.stream(strings)
                .mapToInt(String::length)
                .max();
        System.out.println(max);

        System.out.println("##################");

        OptionalInt min = Arrays.stream(strings)
                .mapToInt(String::length)
                .min();
        System.out.println(min);

        DoubleSummaryStatistics statistics = DoubleStream.generate(Math::random)
                .limit(1000)
                .summaryStatistics();
        System.out.println(statistics);
    }
复制代码

It's that simple!

The basic operation of the statute

The basic operation is the use of the statute reduce implemented method discussed before, IntStream interface defines three forms reduce overloading methods, as follows;

OptionalInt reduce(IntBinaryOperator op)

int reduce(int identity, IntBianryOperator op)

<U> U reduce(U identity,
      BiFunction<U,? super T,U> accumulator,
      BianryOperator<U> combiner)
复制代码

The above parameter is the identity of the mean value of the initialization, IntBianryOperatorthe type of operating parameter is, for example, a lambda expression; BianryOperator<U> combinera combiner in front spoken.

Let's use an example to explain.

/**
     * @return void
     * @Author 欧阳思海
     * @Description reduce规约操作
     * @Date 22:20 2019/9/1
     * @Param []
     **/
    @Test
    public void testReduce2() {
        int sum = IntStream.range(1, 20)
                .reduce((x, y) -> x + y)
                .orElse(0);
        System.out.println(sum);

        System.out.println("##################");

        int sum2 = IntStream.range(1, 20)
                .reduce(0, (x, y) -> x + 2 * y);
        System.out.println(sum2);

        System.out.println("##################");

        int sum3 = IntStream.range(1, 20)
                .reduce(0, Integer::sum);
        System.out.println(sum3);

    }
复制代码

The first example is a 1 to 20 accumulated operation, the second initial value is 0, then 2-fold accumulation, the third initial value is 0, accumulated.

Counting stream

Count the number of streams, there are two methods, namely Stream.count () method and Collectors.counting () method.

/**
     * @return void
     * @Author 欧阳思海
     * @Description 统计测试
     * @Date 23:29 2019/9/1
     * @Param []
     **/
    @Test
    public void testStatistics() {
        //统计数量
        String[] strings = {"hello", "sihai", "hello", "Java8"};
        long count = Arrays.stream(strings)
                .count();
        System.out.println(count);

        System.out.println("##################");

        Long count2 = Arrays.stream(strings)
                .collect(Collectors.counting());
        System.out.println(count2);

    }
复制代码

Find matching 4 stream

Find streams

Find streams Stream Interface provides two methods findFirst and findAny.

Optional findFirst method returns the first element of the stream, and the method returns Optional findAny an element stream.

We look at an example.

        String[] strings = {"hello", "sihai", "hello", "Java8"};
        Optional<String> first = Arrays.stream(strings)
                .findFirst();
        System.out.println(first.get());

        System.out.println("##################");

        Optional<String> any = Arrays.stream(strings).findAny();
        System.out.println(any.get());

        System.out.println("##################");
复制代码

Matching stream

Stream stream provides the interface to match the three methods, namely AnyMatch (any element match, return true), allMatch (all elements match, return true), noneMatch (without a matching element, returns true).

        boolean b = Stream.of(1, 2, 3, 4, 5, 10)
                .anyMatch(x -> x > 5);
        System.out.println(b);

        System.out.println("##################");

        boolean b2 = Stream.of(1, 2, 3, 4, 5, 10)
                .allMatch(x -> x > 5);
        System.out.println(b2);

        System.out.println("##################");

        boolean b3 = Stream.of(1, 2, 3, 4, 5, 10)
                .noneMatch(x -> x > 5);
        System.out.println(b3);  
复制代码

5 summarizes the flow of

This article explains some of the operations flow, including the following aspects.

Create a streaming method. Stream series of operations, including converting between packing stream, string flow, and the flow of map and flatMap, connection flow. Find and match the flow of the Statute of the operation flow

Guess you like

Origin juejin.im/post/5d8dae78518825157267eed3