所以我正在尝试用Java对多图进行排序,这是这些图的样子:
Map<Integer, Pair<Double, Color>> inputMap;
Map<Integer, Pair<Double, Color>> outputMap;
这是我的配对课程:
class Pair<Double, Color> {
public final Double x;
public final Color y;
public Pair(Double x, Color y) {
this.x = x;
this.y = y;
}
}
我正在尝试按配对的第一项对其进行排序。我试图使用这样的东西:
outputMap = new TreeMap<>(inputMap);
但是这并不能完全按照我的想法工作……似乎根本无法对它进行排序。
我如何通过Pair.X对地图进行排序?
答案 0 :(得分:3)
所有SortedMap实现(包括TreeMap
)均按key
而不是value
排序。
https://docs.oracle.com/javase/7/docs/api/java/util/SortedMap.html
一个地图,进一步提供了其键的总体排序。
通过Map
在内部对value
进行排序也不利于针对通过key
访问而优化的性能。
Map
仅将一个值与每个键相关联。
当您查看put
的文档时,这一点尤其清楚
在此映射中将指定的值与指定的键相关联(可选操作)。 如果映射先前包含键的映射,则旧值将替换为指定值。
因此,您用Map<Integer, Pair<Double, Color>>
定义的甚至都不是MultiMap。这就解释了为什么它不符合您的预期。
您正在寻找的是SortedSetMultimap
SetMultimap,其给定键的值集保持排序;也就是说,它们包含一个SortedSet。
使用
//Class renamed to reflect what it actually is, to avoid conflicts with other Pairs. Also you don't need generics then, which you did not use any way.
class ColorPair implements Comparable {
public final Double x;
public final Color y;
public ColorPair (Double x, Color y) {
this.x = x;
this.y = y;
}
//compares only the first component of the Pair
public int compareTo(ColorPair other){
return Double.compare(x, other.x)
}
}
然后您可以使用
创建SortedSetMultimap。TreeMultimap<Integer, ColorPair> sortedSetMap = new TreeMultimap<>() `
并用ColorPair
s
答案 1 :(得分:1)
您不能按地图值排序-只能按键排序。
如果您同时需要-对对象的O(1)HashMap访问和排序遍历-创建一个排序列表并在其中保留相同的对象。
List<Pair<Double, Object>>outputList = inputMap.values().stream().sorted((o1, o2) -> 0 /*IMPLEMENT_COMPARATOR_HERE*/).collect(Collectors.toList());
如果地图是可变的-最好创建一个将同时包含地图和列表的类,并提供“ add”,“ get”和“ remove”之类的方法。应避免直接访问这些结构。
请不要忘记同步两个数据结构上的操作,以使您的代码线程安全。
答案 2 :(得分:0)
突出显示
您可以使用以下方法对地图进行排序:
Map<Integer, Pair<Double, Color>> sortedMap = map.entrySet().stream()
.sorted(Comparator.comparingDouble(e -> e.getValue().x))
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(p1, p2) -> p1,
LinkedHashMap::new));
完整代码
public static void main(String[] args) {
new MyClass().test();
}
public void test() {
Map<Integer, Pair<Double, Color>> map = Map.of(
1, new Pair<>(1.0, Color.BLACK),
2, new Pair<>(3.0, Color.RED),
3, new Pair<>(2.0, Color.BLUE));
Map<Integer, Pair<Double, Color>> sortedMap = map.entrySet().stream()
.sorted(Comparator.comparingDouble(e -> e.getValue().x))
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(p1, p2) -> p1,
LinkedHashMap::new));
System.out.println(sortedMap);
}
class Pair<Double, Color> {
public final Double x;
public final Color y;
public Pair(Double x, Color y) {
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Pair<?, ?> pair = (Pair<?, ?>) o;
return Objects.equals(x, pair.x) &&
Objects.equals(y, pair.y);
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
@Override
public String toString() {
return "Pair{" +
"x=" + x +
", y=" + y +
'}';
}
}
输出
{1=Pair{x=1.0, y=java.awt.Color[r=0,g=0,b=0]}, 3=Pair{x=2.0, y=java.awt.Color[r=0,g=0,b=255]}, 2=Pair{x=3.0, y=java.awt.Color[r=255,g=0,b=0]}}