Java 如何将两个贴图合并为一个,并保持重复值
我有两个hashmaps“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 请让我知道如何在不丢失重复值
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}]