在Java8中使用多个布尔键对地图对象列表进行排序

时间:2019-08-01 14:38:16

标签: list sorting java-8 hashmap boolean

我正在尝试对看起来像这样的Map对象列表进行排序。

"list" : [ 
        {
            "up" : false,
            more fields ....
        }, 
        {
            "randomField" : "ABC",
            "someMoreRandomField" : "Retirement"
            more fields ....
        }, 
        {
            "up" : false,
            more fields ....
        },
        {
            "last" : true,
            "up" : false
            more fields ....
        }, 
        {
            "last" : true,
            "up" : true
            more fields ....
        },      
        {
            "up" : true
            more fields ....
        },
        {
            "up" : true
            more fields ....
        }, 
        {
            "up" : true
            more fields ....
        }

    ]

我希望根据这些条件对它们进行排序。 如果对象的键“ last”标记为true,则它们应在列表中位于最后。 如果键“ up”为真,则它们将首先出现在列表中。 如果键“ last”标记为true,则优先级,并且即使同一对象的“ up”标记为true,它也应出现在列表的底部。

排序列表:

"list" : [ 
        {
            "up" : true
            more fields ....
        },
        {
            "up" : true
            more fields ....
        }, 
        {
            "up" : true
            more fields ....
        },
        {
            "up" : false,
            more fields ....
        }, 
        {
            "randomField" : "ABC",
            "someMoreRandomField" : "Retirement"
            more fields ....
        }, 
        {
            "up" : false,
            more fields ....
        },
        {
            "last" : true,
            "up" : false
            more fields ....
        }, 
        {
            "last" : true,
            "up" : true
            more fields ....
        }
    ]

我能够使用Vanilla JS来实现这一点,尝试在Java 8中做到这一点。已经花了很长时间了,偶然发现了几个答案: https://stackoverflow.com/a/46717991/2114024

但尚未找到解决方案。

JS代码段:

list.sort(function(a,b)  {
     if(a.last === undefined) {a.last = false};
     if(b.last === undefined) {b.last = false};
     if(a.up === undefined) {a.up = false};
     if(b.up === undefined) {b.up = false};
     return Number(a.last) - Number(b.last) || Number(b.up) - Number(a.up);
});

任何建议都值得赞赏。

2 个答案:

答案 0 :(得分:1)

我已经尝试了与您申请Java脚本类似的逻辑。 您可以在Java 8中尝试以下代码:

public class ListMapSort {

    public static void main(String[] args) {
        List<Map<String, Object>> data = getData();

        data.sort(Comparator.comparing(m -> {
            int lastKey = (m.containsKey("last") && (boolean)m.get("last")) ? 1 : 0;
            int upKey = (m.containsKey("up") && (boolean)m.get("up")) ? 0 : 1;
            return lastKey*10 + upKey;
        }));

        System.out.println("Sorted data: " + data);
    }

    private static List<Map<String, Object>> getData() {
        List<Map<String, Object>> data = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        map.put("up", false);
        map.put("id", 1);
        data.add(map);
        map = new HashMap<>();
        map.put("up", false);
        map.put("id", 2);
        data.add(map);
        map = new HashMap<>();
        map.put("last", false);
        map.put("up", false);
        map.put("id", 3);
        data.add(map);
        map = new HashMap<>();
        map.put("last", true);
        map.put("up", true);
        map.put("id", 4);
        data.add(map);
        map = new HashMap<>();
        map.put("up", true);
        map.put("id", 5);
        data.add(map);
        map = new HashMap<>();
        map.put("last", false);
        map.put("id", 6);
        data.add(map);
        map = new HashMap<>();
        map.put("last", true);
        map.put("id", 7);
        data.add(map);
        map = new HashMap<>();
        map.put("last", false);
        map.put("up", true);
        map.put("id", 7);
        data.add(map);

        return data;
    }
}

正如您提到的另一篇文章中所述,也可以使用这种方式解决该问题,

data.sort(Comparator.comparing(
                (Map<String, Object> m) -> (boolean)m.getOrDefault("last", false))
                .thenComparing(m -> !(boolean)m.getOrDefault("up", false)));

答案 1 :(得分:1)

我能够使用@swapan的答案对它进行排序,但不得不撤消否定之词。

data.sort(Comparator.comparing(
            (Map<String, Object> m) -> !(boolean)m.getOrDefault("last", false))
            .thenComparing(m -> (boolean)m.getOrDefault("up", false)));