Java8 Stream链式表达式:去重+排序

前言:

list是开发过程中使用比较频繁的,今天记一篇List使用中的三种形式,并区分之。

要求:

           合并两个list中的元素(均为整数),返回一个不重复且非降序的list;

           输入:list_1=[1,2,3,4,-1,2,2],list_2=[-1,1,2,3,4,5]

           输出:result=[-1,1,2,3,4,5]

HashSet:

可以去重,但不能排序

TreeSet:

既可去重,又可以排序(默认为升序)

Stream:

既可去重,又可以排序(代码简洁且高效)

代码示例:

package com.tensquare.recruit.service;

import com.google.common.collect.Lists;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author Adam
 * @description 合并两个List去重并排升序
 * @date 2020/11/18
 */
public class ListTest {
    public static void main(String[] args) {
        //java中可以使用Arrays.asList()方法进行插入List元素
        //Integer[] arr1 = {1, 2, 3, 4, -1, 2, -2};
        //ArrayList list_1 = new ArrayList<>(Arrays.asList(arr1));
        //Integer[] arr2 = {6, 4, 2, 1, 5};
        //ArrayList list_2 = new ArrayList<>(Arrays.asList(arr2));

        //google封装的Lists可以直接插入List元素 下面的方式,代码更简洁
        List<Integer> list_1 = Lists.newArrayList(1, 2,-3,3, 4, -1, 2, -2);
        List<Integer> list_2 = Lists.newArrayList(6, 5, 2, 1, -5);

        //hashSet合并两个list
        methodByHashSet(list_1, list_2, "HashSet方式:");

        //TreeSet合并两个list
        methodByTreeSet(list_1, list_2, "TreeSet方式:");

        //调用merge方法使用java8stream流进行合并去重排序
        methodByStream(list_1, list_2,"Stream流方式:");
    }

    /**
     * 调用merge方法使用java8stream流进行合并去重排序
     * @param list_1
     * @param list_2
     * @param s
     */
    private static void methodByStream(List list_1, List list_2,String s) {
        List<Integer> result3 = new ArrayList<>(streamMerge(list_1, list_2));
        System.out.println(s + result3);
    }

    /**
     * //TreeSet合并两个list
     * @param list_1
     * @param list_2
     * @param s
     */
    private static void methodByTreeSet(List list_1, List list_2, String s) {
        //使用TreeSet进行去重后排序
        Set<Integer> treeSet = treeSetMerge(list_1, list_2);
        List<Integer> result2 = new ArrayList<>(treeSet);
        System.out.println(s + result2);
    }

    /**
     * 使用TreeSet进行去重后排序
     * @param list_1
     * @param list_2
     * @return
     */
    private static Set<Integer> treeSetMerge(List list_1, List list_2) {
        Set<Integer> treeSet = new TreeSet<>(list_1);
        treeSet.addAll(list_2);
        return treeSet;
    }

    /**
     * hashSet合并两个list
     * @param list_1
     * @param list_2
     * @param s
     */
    private static void methodByHashSet(List list_1, List list_2, String s) {
        //使用HashSet进行去重
        Set<Integer> hashSet = hashSetMerge(list_1, list_2);
        List<Integer> result1 = new ArrayList<>(hashSet);
        System.out.println(s + result1);
    }

    /**
     * 使用HashSet进行去重
     * @param list_1
     * @param list_2
     * @return
     */
    private static Set<Integer> hashSetMerge(List list_1, List list_2) {
        Set<Integer> hashSet = new HashSet<>(list_1);
        hashSet.addAll(list_2);
        return hashSet;
    }

    /**
     * stream去重排序转list
     * @param list_1
     * @param list_2
     * @return
     */
    public static List<Integer> streamMerge(List<Integer> list_1, List<Integer> list_2) {
        List<Integer> result = Stream.of(list_1, list_2)
                .flatMap(Collection::stream)
                .distinct()//去重
                .sorted()//排序
                .collect(Collectors.toList());//转List
        return result;
    }
}

输出结果:

总结:

1.虽然HashSet输出的结果看起来也是有序的,但是深入源码发现HashSet并没有给list进行排序

故使用Collections.sort()方法进行排序;

2.TreeSet中的通过源码我们可以发现,存入元素的时候,它创建了一个树,第一个元素就是树的根节点,后面的元素依次从树的根节点开始向后比较(创建比较器,利用comparator()方法进行比较),小的就往左边放,大的就往右边放,而相同的就不放进去(实现了唯一性)。取出元素的时候,它采用前序遍历的方法(根节点 左子树 右子树)遍历整个树,达到有序。

当然,我们也可以定制排序规则,如果需要定制排序,比如降序排列,可通过Comparator接口的帮助。需要重写compare()方法。

3.三种方式的执行效率又如何呢?

当元素很少的时候:Stream<TreeSet<HashSet(元素小于100)

当元素很多的时候:TreeSet<Stream<HashSet(元素小于10000000)

猜你喜欢

转载自blog.csdn.net/l_mloveforever/article/details/109788006
今日推荐