Java8和Guava处理集合排序

Guava

Guava简单的操作

 private static void baseTest() {
        //natural() 对可排序类型做自然排序,如数字按大小,日期按先后排序
        //usingToString()   按对象的字符串形式做字典排序[lexicographical ordering]
        //from(Comparator)  把给定的Comparator转化为排序器
        //reverse() 获取语义相反的排序器
        //nullsFirst()  使用当前排序器,但额外把null值排到最前面。
        //nullsLast()   使用当前排序器,但额外把null值排到最后面。

        List<Integer> numbers = Lists.newArrayList(30, 20, 60, 80, 10);
        List<Integer> result = Lists.newArrayList();

        result = Ordering.natural().sortedCopy(numbers);
        System.out.println(result);
        // 10,20,30,60,80
        result = Ordering.natural().sortedCopy(numbers);
        System.out.println(result);

        result = Ordering.natural().reverse().sortedCopy(numbers);
        // 80,60,30,20,10

        Integer min = Ordering.natural().min(numbers);
        // 10

        Integer max = Ordering.natural().max(numbers);
        // 80

        Lists.newArrayList(30, 20, 60, 80, null, 10);

        Ordering.natural().nullsLast().sortedCopy(numbers);
        // 10,20,30,60,80,null

        Ordering.natural().nullsFirst().sortedCopy(numbers);
        // null,10,20,30,60,80
    }

Java8 排序

package com.gb.mq;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: wgs
 * @Date 2021/8/26 08:50
 * @Classname Student
 * @Description
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private Integer id;
    private Integer age;
    private String name;

    public static void main(String[] args) {
        Student student1 = new Student(10, 18, "哈哈");
        Student student2 = new Student(10, 11, "嘿嘿");
        Student student3 = new Student(19, 22, "哒哒");
        Student student4 = new Student(6, 54, "喔喔");
        Student student5 = new Student(25, 25, "嘻嘻");

        List<Student> studentList = Lists.newArrayList(student1, student2, student3, student4, student5);
        List<Student> students = studentList;

        System.out.println("排序前");
        studentList.forEach(e -> System.out.println(JSONObject.toJSONString(e)));

        // 正序
        studentList = studentList.stream().sorted(Comparator.comparing(Student::getId)).collect(Collectors.toList());
        System.out.println("-------");
        studentList.forEach(e -> System.out.println(JSONObject.toJSONString(e)));
        // 倒序
        studentList = studentList.stream().sorted(Comparator.comparing(Student::getId).reversed()).collect(Collectors.toList());

        System.out.println("~~~~~~");
        studentList.forEach(e -> System.out.println(JSONObject.toJSONString(e)));

        // 根据id倒序排,id相同根据年龄正序排
        System.out.println("========排序输出前========");
        students.forEach(e -> System.out.println(JSONObject.toJSONString(e)));

        List<Student> studentsSortAge = students
                .stream()
                .sorted(Comparator.comparing(Student::getId)
                        .reversed()
                        .thenComparing(Student::getAge))
                .collect(Collectors.toList());

        System.out.println("========排序输出后========");

        studentsSortAge.forEach(e -> System.out.println(JSONObject.toJSONString(e)));
    }
}

四中方式实现根据第一个集合对第二个排序

/**
     * 默认的排序器
     * natural() 对可排序类型做自然排序,如数字按大小,日期按先后排序
     * reverse() 对当前的比较器进行反转
     * 自然排序,不能将汉字按首字母的顺序排序。
     */
    private static void naturalTest() {
        List<String> list = Lists.newArrayList("12", "2", "3", "33", "4", "44", "5", "55", "测试", "基线", "有钱");

        Ordering<Comparable> natural = Ordering.natural();
        list.sort(natural);
        System.out.println(list.toString());
        //反转
        list.sort(natural.reverse());
        System.out.println(list.toString());

        List<Integer> ints = Lists.newArrayList(12, 2, 3, 33, 4, 44, 5, 55);
        ints.sort(natural);
        System.out.println(ints.toString());
        ints.sort(natural.reverse());
        System.out.println(ints.toString());
    }

    /**
     * 根据指定顺序排序
     */
    private static void javaSpecifyTest() {
        List<String> orders = Stream.of("东部", "南部", "A", "西部", "北部", "中部").
                collect(Collectors.toList());
        List<String> source = Stream.of("北部", "南部", "西部", "东部", "中部", "A").
                collect(Collectors.toList());

        Collections.reverse(orders);
        source.sort((o1, o2) -> Integer.compare(orders.indexOf(o2), orders.indexOf(o1)));
        System.out.println(source);

        Map<Integer, String> tree = new TreeMap<Integer, String>();
        for (String code : source) {
            if (orders.contains(code)) {
                tree.put(orders.indexOf(code), code);
            } else {
                tree.put(source.size(), code);
            }
        }
    }

    /**
     * 原理,就是获取了字符在排序集合中的位置,然后借助TreeMap实现排序。
     */
    private static void javaSpecifyTreeTest() {
        List<String> orders = Stream.of("东部", "南部", "A", "西部", "北部", "中部").
                collect(Collectors.toList());
        List<String> source = Stream.of("北部", "南部", "西部", "东部", "中部", "A").
                collect(Collectors.toList());

        Map<Integer, String> tree = new TreeMap<Integer, String>();
        for (String code : source) {
            if (orders.contains(code)) {
                tree.put(orders.indexOf(code), code);
            } else {
                tree.put(source.size(), code);
            }
        }

        System.out.println(source);
    }

    private static void guavaSpecifyTest() {
        List<String> orders = Stream.of("东部", "南部", "A", "西部", "北部", "中部").
                collect(Collectors.toList());
        List<String> source = Stream.of("北部", "南部", "西部", "东部", "中部", "A").
                collect(Collectors.toList());

        Ordering ordering = Ordering.explicit(orders);
        source.sort((o1, o2) -> {
            if (orders.contains(o1) && orders.contains(o2)) {
                return ordering.compare(o1, o2);
            }
            return 0;
        });

        System.out.println(source);
    }

    /**
     * 不仅只是指定顺序,还可以设置指定缺少的字符 的排序。
     */
    private static void guavaSpecifyComparatorTest() {
        List<String> orders = Stream.of("东部", "南部", "A", "西部", "北部", "中部").
                collect(Collectors.toList());
        List<String> source = Stream.of("北部", "南部", "西部", "东部", "中部", "A").
                collect(Collectors.toList());
        FixedOrderComparator<String> fixedOrderComparator = new FixedOrderComparator<String>(orders);
        fixedOrderComparator.setUnknownObjectBehavior(FixedOrderComparator.UnknownObjectBehavior.AFTER);
        source.sort(fixedOrderComparator);

        System.out.println(source);
    }

对象操作

    public static void guavaSort(){
        List<String> keys = ImmutableList.of("A", "Z", "D", "E", "B", "H", "C");

        List<Map<String, String>> items = ImmutableList.of(
                ImmutableMap.of("id", "D", "num", "5"),
                ImmutableMap.of("id", "A", "num", "5"),
                ImmutableMap.of("id", "C", "num", "3"),
                ImmutableMap.of("id", "Z", "num", "3")
        );

        Ordering<Map<String, String>> numOrdering =
                Ordering.natural().reverse().onResultOf(item -> item.get("num"));
        System.out.println(JSONObject.toJSONString(numOrdering.sortedCopy(items)));

        Ordering<Map<String, String>> idOrdering = Ordering.explicit(keys).onResultOf(item -> item.get("id"));


        Ordering<Map<String, String>> compoundOrdering = numOrdering.compound(idOrdering);
        System.out.println(JSONObject.toJSONString(compoundOrdering.sortedCopy(items)));

        List<Map<String, String>> result = compoundOrdering.sortedCopy(items);

        System.out.println(result);
    }

两个集合根据规则排序

package com.gb.mq;

import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
 * @Author: wgs
 * @Date 2021/8/26 08:50
 * @Classname Student
 * @Description
 * https://stackoverflow.com/questions/45349293/sorting-list-based-on-another-lists-order
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class StudentS {
    private Integer id;
    private Integer age;
    private String name;

    public static void main(String[] args) {
        StudentS student1 = new StudentS(10, 18, "哈哈");
        StudentS student2 = new StudentS(10, 11, "嘿嘿");
        StudentS student3 = new StudentS(19, 22, "哒哒");
        StudentS student4 = new StudentS(6, 54, "喔喔");
        StudentS student5 = new StudentS(25, 25, "嘻嘻");

        List<StudentS> studentList = Lists.newArrayList(student1, student2, student3, student4, student5);
        List<StudentS> students =  Lists.newArrayList(student5, student1, student3, student4, student2);
        List<Integer> ids = Lists.newArrayList(11, 18, 25, 22, 54);

        Ordering<StudentS> studentSOrdering = Ordering.natural().reverse().onResultOf(StudentS::getAge);


        Ordering<StudentS> ageOrdering = Ordering.explicit(ids).onResultOf(StudentS::getAge);

       List<StudentS> compoundOrdering = ageOrdering.sortedCopy(studentList);

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

        // 方式二
//        FixedOrderComparator<StudentS> fixedOrderComparator = new FixedOrderComparator<StudentS>(students);
//
//
//        fixedOrderComparator.setUnknownObjectBehavior(FixedOrderComparator.UnknownObjectBehavior.AFTER);
//        studentList.sort(fixedOrderComparator);
//
//        students.forEach(e -> System.out.println(JSONObject.toJSONString(e)));
//        System.out.println("---------");
//        studentList.forEach(e -> System.out.println(JSONObject.toJSONString(e)));
//

}
    }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容