Java 如何将两个贴图合并为一个,并保持重复值

Java 如何将两个贴图合并为一个,并保持重复值,java,list,arraylist,merge,hashmap,Java,List,Arraylist,Merge,Hashmap,我有两个hashmaps“map0和map1”,它们都持有Point类型的键和Double类型的值,如下所示 我确信键永远不会重复,但值可以重复,我想将“map0和map1”添加到一个Hashmap中,以便 我不会丢失重复值“我想保留重复值”。在我检查了这个网站上的一些问题后,我在代码中使用了如下所示的。putAll()方法,但问题是,当我将两个地图“map0,map1”组合成一个组合地图时,我丢失了结果中所示的重复值,因为map0的值为20,而map1的值也为20 请让我知道如何在不丢失重复值

我有两个hashmaps“
map0和map1
”,它们都持有
Point
类型的键和
Double
类型的值,如下所示

我确信键永远不会重复,但值可以重复,我想将“
map0和map1
”添加到一个
Hashmap
中,以便 我不会丢失重复值“我想保留重复值”。在我检查了这个网站上的一些问题后,我在代码中使用了如下所示的。
putAll()
方法,但问题是,当我将两个地图“map0,map1”组合成一个组合地图时,我丢失了结果中所示的重复值,因为map0的值为20,而map1的值也为20

请让我知道如何在不丢失重复值的情况下将两个贴图合并为一个

代码

public static void main(String[] args) {

    HashMap<Point, Double> map0 = new HashMap<Point, Double>();
    HashMap<Point, Double> map1 = new HashMap<Point, Double>();

    map0.put(new Point(32,59), (double) 56);
    map0.put(new Point(398,3), (double) 20);
    map0.put(new Point(3,3), (double) 209);

    map1.put(new Point(32,596), (double) 561);
    map1.put(new Point(396,311), (double) 20);
    map1.put(new Point(35,34), (double) 2099);

    System.out.println("map0.size:"+map0.size());
    System.out.println("map1.size:"+map1.size());

    HashMap<Point, Double> combine = new HashMap<Point, Double>();

    combine.putAll(map0);
    combine.putAll(map1);
    ValueComparator vc = new ValueComparator(combine);
    TreeMap<Point, Double> tree= new TreeMap<Point, Double>(vc);

    tree.putAll(combine);
    System.out.println("tree.size:"+tree.size());
    System.out.println("tree_sorted:"+tree);

}

static class ValueComparator implements Comparator<Point> {

    private HashMap<Point, Double> map = null;

    public ValueComparator(HashMap<Point, Double> map) {
        // TODO Auto-generated constructor stub
        this.map = map;
    }

    public int compare(Point arg0, Point arg1) {
        // TODO Auto-generated method stub

        return Double.compare(this.map.get(arg0), this.map.get(arg1));
        /*
        if (this.map.get(arg0) >= this.map.get(arg1)) {
            return 1;
        } else {
            return -1;
        }
        */
    }
}
map0.size:3
map1.size:3
tree.size:5
tree_sorted:{{398.0, 3.0}=20.0, {32.0, 59.0}=56.0, {3.0, 3.0}=209.0, {32.0, 596.0}=561.0, {35.0, 34.0}=2099.0}

您将键的比较标准(
)定义为相关值(
),因此值为20的两个点与比较器相同


如果要保留重复项,请更改比较器(即您对相等的定义)或使用不同的数据结构,因为映射不允许重复键。

从给定比较器的角度来看,树映射中不能有两个“相等”的对象。在以下文件中明确规定:

这是因为映射接口是根据equals操作定义的,但排序映射使用其compareTo(或compare)方法执行所有键比较,因此从排序映射的角度来看,此方法认为相等的两个键是相等的

问题中没有说明您对分类收集的进一步使用,因此我认为分类的
列表对您来说已经足够了。我还建议扩展
类以将值与之关联。它更适合这种用途

此外,比较器的实现方式也不正确。它不应该有外部映射引用

请考虑下面的代码:

public class Example {

public static class ValuedPoint extends Point {
  private double value;

  public ValuedPoint(double x, double y, double value) {
    super(x, y);
    this.value = value;
  }

  public double getValue() {
    return value;
  }

  public String toString() {
    return "{" + x + ", " + y + ", " + value + "}";
  }
}

private static class ValueComparator implements Comparator<ValuedPoint> {

  public int compare(ValuedPoint arg0, ValuedPoint arg1) {
    return Double.compare(arg0.getValue(), arg1.getValue());
   }
 }

public static void main(String[] args) {

  Set<ValuedPoint> set0 = new HashSet<ValuedPoint>();
  Set<ValuedPoint> set1 = new HashSet<ValuedPoint>();

  set0.add(new ValuedPoint(32, 59, 56));
  set0.add(new ValuedPoint(398, 3, 20));
  set0.add(new ValuedPoint(3, 3, 209));

  set1.add(new ValuedPoint(32, 596, 561));
  set1.add(new ValuedPoint(396, 311, 20));
  set1.add(new ValuedPoint(35, 34, 2099));

  System.out.println("set0.size:" + set0.size());
  System.out.println("set1.size:" + set1.size());

  Set<ValuedPoint> combined = new HashSet<ValuedPoint>();

  combined.addAll(set0);
  combined.addAll(set1);
  System.out.println("combined size:" + combined.size());

  ValueComparator comparator = new ValueComparator();

  List<ValuedPoint> sortedList = new ArrayList<ValuedPoint>(combined);
  Collections.sort(sortedList, comparator);

  System.out.println("list size:" + sortedList.size());
  System.out.println("sortedList:" + sortedList);
  }
}

您需要切换到
Map
,是吗?@bmarglies您的意思是我应该将“combinedMap”声明为Map???如果是,请说明下一步是什么为什么需要:ValueComparator vc=新的ValueComparator(组合);树映射树=新树映射(vc);?使用一个MultiMap类:只是为了得到正确的结果:两个贴图的键不会有任何重叠,而只会在值中有重叠。那么,问题是什么?结果将包含两个值为
20
的键。你想以某种方式对那些具有相同值的键进行分组吗?即使比较了组合这两个元素的映射中的元素,也没有办法保留重复值吗?我感谢你的努力和时间,但我想告诉你,类点是opencv库中的内置clas,我知道。建议的解决方案与之配合。我只是在扩展opencv
类。您仍然可以将任何
值点
实例用作
实例。这是OOP的基本原则之一。@感谢您的回答,但我无法理解您在回答中所说的“您的比较器也没有以正确的方式实现。它不应该有外部映射引用”!!请您澄清一下,您的比较器工作正常。但是它的
比较(…)
结果取决于某些内部状态。它不是直接从比较的参数计算出来的。所以,当比较器内部状态发生变化时,
compare(…)
的结果可能会发生变化,甚至失败。
set0.size:3
set1.size:3
combined size:6
list size:6
sortedList:[{398.0, 3.0, 20.0}, {396.0, 311.0, 20.0}, {32.0, 59.0,56.0}, {3.0, 3.0, 209.0}, {32.0, 596.0, 561.0}, {35.0, 34.0, 2099.0}]