【问题标题】:How to order a HashMap by properties如何按属性对 HashMap 进行排序
【发布时间】:2020-10-01 04:08:30
【问题描述】:

您可能已经知道,当您将某些内容放入 HashMap 时,存储内容的顺序是随机的。我想使用 Comparable 订购我的 HashMap,但我无法让它正常工作。

这样我就有了地图:

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

这个map的key是多个id和name的构造(MyKeyObject),我想先根据id对key上的map进行排序,如果id相同则name。

这是我尝试过的:

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());
}

说实话,我什至不认为 compareTo 方法被击中,我在这里做错了什么?

更新:我知道有 TreeMap 之类的类型,但它对我不起作用。我刚刚在这里给出了一个非常简单的例子,我的真实代码非常复杂。是否可以像我在这里尝试过的那样使用 Comparable 进行这项工作?

【问题讨论】:

  • HashMap 没有定义的顺序,因此尝试订购它是不可能的。
  • 您是否尝试过使用LinkedHashMap 而不是哈希图?哈希图永远不会包含顺序。 LinkedHashMap 维护插入顺序。
  • @scigs a SortedMap like TreeMap 可能是更好的选择。
  • 正如 Andy 所说,HashMap 没有定义的顺序,但更进一步,Stream API 不是用于更改集合的工具。 myObjectMap.entrySet().stream().sorted(Map.Entry.comparingByKey()); 行无效,因为它缺少实际操作。

标签: java sorting hashmap comparable


【解决方案1】:

我认为您正在寻找的是 TreeMap 而不是 HashMap。

这里有一个简化的用例示例。

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);
        }

    }
}

输出是:

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

您可以将 MyKeyObject 设为 Comparable 或为 TreeMap 提供 Comparator。

【讨论】:

    猜你喜欢
    • 2017-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多