简体   繁体   English

如何按属性订购 HashMap

[英]How to order a HashMap by properties

As you probably know already, when you put something into a HashMap, the order in which things are stored is random.您可能已经知道,当您将内容放入 HashMap 时,内容的存储顺序是随机的。 I want to order my HashMap using Comparable, but I can't get it to work properly.我想使用 Comparable 订购我的 HashMap,但我无法让它正常工作。

This so I have a map:这样我就有了一个 map:

Map<MyKeyObject, List<MyValueObject>> myObjectMap = new HashMap<>();

The key of this map is a construction of multiple an id and a name (MyKeyObject), and I want to sort the map on the keys based on the id first, and if the id is identical then name.这个map的key是多个id和name(MyKeyObject)的构造,我想先根据id对keys上的map进行排序,id相同则name。

Here is what I've tried:这是我尝试过的:

public class MyKeyObject implements Comparable<MyKeyObject> {
  private Long id;
  private String name;

  public MyKeyObject(Long id, String name) {
        this.id = id;
        this.name = name;
    }

  public boolean equals(Long id, String name) {
        return this.id.equals(id) && this.name.equals(name)
    }

  @Override
  public int compareTo(MyKeyObject myKeyObject) {       
      if (this.id myKeyObject.getId() != 0) {
          return (this.Id - myKeyObject.getId() == 1) ? 1 : -1;
      } else {
          return (this.name().compareTo(myKeyObject.name()) == 1) ? 1 : -1;
      }
  }

  @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        MyKeyObject that = (MyKeyObject) o;
        return id.equals(that.id) &&
                name == that.name;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }
}
public class MyKeyObject implements Comparable<MyKeyObject> {
  Map<MyKeyObject, List<MyValueObject>> myObjectMap = new HashMap<>();

  //Here I have a lot of code that populates the HashMap

  myObjectMap.entrySet().stream().sorted(Map.Entry.comparingByKey());
}

To be honest I don't even think the compareTo method is hit, what am I doing wrong here?老实说,我什至不认为 compareTo 方法被命中,我在这里做错了什么?

Update: I know that there are types such as TreeMap, but it doesn't work for me.更新:我知道有诸如 TreeMap 之类的类型,但它对我不起作用。 I've just given a very simple example here, my real code is much mode complex.我刚刚在这里给出了一个非常简单的例子,我的真实代码非常复杂。 Is it possible to make this work with Comparable like I've tried here?是否可以像我在这里尝试的那样使用 Comparable 进行这项工作?

I think what you are looking for is TreeMap instead of HashMap.我认为您正在寻找的是TreeMap而不是 HashMap。

Here you have a simplified example of your use case.这里有一个用例的简化示例。

import java.util.Comparator;
import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;

public class TreeMapExample {
    public static void main(String[] args) {
        Map<MyKeyObject, Object> myTreeMap = new TreeMap<>();

        myTreeMap.put(new MyKeyObject(5L, "Jay"), null);
        myTreeMap.put(new MyKeyObject(5L, "Bob"), null);
        myTreeMap.put(new MyKeyObject(1L, "Alison"), null);
        myTreeMap.put(new MyKeyObject(3L, "Frey"), null);

        myTreeMap.entrySet()
                .forEach(myKeyObjectObjectEntry ->
                        System.out.println(String.format(
                                "Id= %s, Name=%s",
                                myKeyObjectObjectEntry.getKey().id,
                                myKeyObjectObjectEntry.getKey().name )));
    }

    public static class MyKeyObject implements Comparable<MyKeyObject> {
        private Long id;
        private String name;

        public MyKeyObject(Long id, String name) {
            this.id = id;
            this.name = name;
        }

        @Override
        public int compareTo(MyKeyObject myKeyObject) {
            return Comparator.comparing((MyKeyObject keyObject)->keyObject.id)
                    .thenComparing(keyObject->keyObject.name)
                    .compare(this, myKeyObject);
        }

    }
}

The output is: output 是:

Id=1, Name=Alison
Id=3, Name=Frey
Id=5, Name=Bob
Id=5, Name=Jay

You can make MyKeyObject Comparable or provider a Comparator to the TreeMap.您可以使MyKeyObject Comparable 或为 TreeMap 提供比较器。

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

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