繁体   English   中英

如何按键和值对地图排序,而Val本身就是一个地图/列表

[英]How to sort a Map by Key and Value, whereas the Val is a Map/List itself

我很难理解正确的语法来对Map进行排序,这些值不仅是一种类型,而且可以再次嵌套。 我会在这里尝试提出一个合适的例子:

首先让我们为它创建一个随机类:

class NestedFoo{
int valA;
int valB;
String textA;

public NestedFoo(int a, int b, String t){
  this.valA = a;
  this.valB = b;
  this.textA = t;
  }
}

好吧,那是我们的班级。 清单如下:

HashMap<Integer, ArrayList<NestedFoo>> sortmePlz = new HashMap<>();

首先创建3个条目,它们应该已经显示了排序工作。

ArrayList<NestedFoo> l1 = new ArrayList<>();
n1 = new NestedFoo(3,2,"a");
n2 = new NestedFoo(2,2,"a");
n3 = new NestedFoo(1,4,"c");
l1.add(n1);
l1.add(n2);
l1.add(n3);

ArrayList<NestedFoo> l2 = new ArrayList<>();
n1 = new NestedFoo(3,2,"a");
n2 = new NestedFoo(2,2,"a");
n3 = new NestedFoo(2,2,"b");
n4 = new NestedFoo(1,4,"c");
l2.add(n1);
l2.add(n2);
l2.add(n3);
l2.add(n4);

ArrayList<NestedFoo> l3 = new ArrayList<>();
n1 = new NestedFoo(3,2,"a");
n2 = new NestedFoo(2,3,"b");
n3 = new NestedFoo(2,2,"b");
n4 = new NestedFoo(5,4,"c");
l3.add(n1);
l3.add(n2);
l3.add(n3);
l3.add(n4);

甜蜜的,现在将它们放入我们的地图。

sortmePlz.put(5,l1);
sortmePlz.put(2,l2);
sortmePlz.put(1,l3);

我现在想要的是首先按其键对整个地图进行排序,因此顺序应为l3 l2 l1。 然后,我希望每个键中的列表按以下顺序排序:intA,intB,text(全部升序)

我不知道该怎么做。 尤其是自从Java 8包含所有这些lambda以来,我没有试着阅读这个主题,但是对那里的代码不知所措。

提前致谢! 我希望代码没有语法错误,我可以随时进行修改

您可以使用TreeSet而不是常规的HashMap并且您的值将通过key自动排序:

Map<Integer, ArrayList<NestedFoo>> sortmePlz = new TreeMap<>();

第二步,我有点困惑。

按以下顺序排序:intA,intB,text(全部升序)

我想您想通过首先比较intA值对列表进行排序,然后如果它们相等,则通过intB进行比较,依此类推。 如果我理解正确的话,你可以使用ComparatorcomparingthenComparing

sortmePlz.values().forEach(list -> list
            .sort(Comparator.comparing(NestedFoo::getValA)
                            .thenComparing(NestedFoo::getValB)
                            .thenComparing(NestedFoo::getTextA)));

我敢肯定有办法用lambda做到这一点,但实际上并不是必需的 请参阅Schidu Luca的答案以获取类似lambda的解决方案。

如果您想要“旧式解决方案”,请继续阅读。

您无法对地图进行排序。 这是没有道理的,因为在地图中没有顺序的概念。 现在,有一些地图对象以排序的方式存储键(例如TreeMap )。

您可以订购列表。 在您的情况下,使NestedFoo具有可比性( https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html )。 然后,您可以在列表上调用方法Collections.sorthttps://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#sort-java.util.List- )。

使用TreeMap代替HashMap,它解决了第一个问题:按键对条目进行排序。

从地图中获得所需的列表后,可以按valA,valB和文本对ArrayList进行排序:

l1.sort(
                Comparator.comparing(NestedFoo::getValA).thenComparing(NestedFoo::getValB).thenComparing(NestedFoo::getTextA)
        );

并按以下方式更改NestedFoo类定义:

class NestedFoo {
        int valA;
        int valB;
        String textA;

        public NestedFoo(int a, int b, String t) {
            this.valA = a;
            this.valB = b;
            this.textA = t;
        }

        public int getValA() {
            return valA;
        }

        public void setValA(int valA) {
            this.valA = valA;
        }

        public int getValB() {
            return valB;
        }

        public void setValB(int valB) {
            this.valB = valB;
        }

        public String getTextA() {
            return textA;
        }

        public void setTextA(String textA) {
            this.textA = textA;
        }
    }

使用树图进行排序时,请记住,树图使用compareTo而不是等于进行排序和查找重复项。 当为任何将用作键的对象实现时,compareTo应该与equals和hashcode结合在一起。 您可以在此链接上查找详细的示例https://codingninjaonline.com/2017/09/29/unexpected-results-for-treemap-with-inconsistent-compareto-and-equals/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM