我有一个类的集合,存储一些我需要执行以下操作的数据:
你能想到在Java中有效的方法吗?
首先,我想到使用带有ids作为键的HashMap
然后,我考虑使用TreeMap,将有序值作为键
同时使用这两种结构似乎不是一个好的解决方案,因为它们必须同步。我想某种BiMultiMap按其值排序,从特定值开始迭代它可以解决我的问题,但我找不到办法做到这一点。
我试图用一个例子来说明我的需求。这列火车不是我的实际问题,我试图让它变得不那么抽象。
public static class Train implements Comparable<Train> {
String id;
int maxSpeed;
String trainColor;
public Train(String id, int d1, String d2){
this.id = id;
this.maxSpeed = d1;
this.trainColor = d2;
}
@Override
public String toString() {
return id + " = (" + maxSpeed + ", " + trainColor + ")";
}
@Override
public int compareTo(Train o) {
return Integer.compare(this.maxSpeed, o.maxSpeed);
}
}
public static void main(String[] args){
// Let's say I need two things:
// - the trains that can go higher than a certain speed
// - the train data of a particular train
int start = 3;
String seekedId = "FlyingScotman";
Train d1 = new Train("HogwartExpress", 5, "blue");
Train d2 = new Train("TGV", 4, "red");
Train d3 = new Train("FlyingScotman", 3, "blue");
Train d4 = new Train("OrientExpress", 2, "black");
Train d5 = new Train("Trans-Siberian", 1, "grey");
/******* HashMap implementation *******/
Map<String, Train> hashMapData = new HashMap<String, Train>();
hashMapData.put(d1.id, d1);
hashMapData.put(d2.id, d2);
hashMapData.put(d3.id, d3);
hashMapData.put(d4.id, d4);
hashMapData.put(d5.id, d5);
hashMapData = MapUtil.sortByValue(hashMapData);
// Bad: I have to iterate the whole collection to reach the subcollection
System.out.println("\n>>>>>>> HashMap: subcollection");
for(Map.Entry<String, Train> entry : hashMapData.entrySet()) {
if (entry.getValue().maxSpeed < start) {
continue;
}
System.out.println(entry.getValue());
}
// Good: I get my data directly
System.out.println("\n>>>>>>> HashMap: get");
System.out.println(hashMapData.get(seekedId));
/******* TreeMap implementation *******/
TreeMap<Integer, Train> treeMapData = new TreeMap<Integer, Train>();
treeMapData.put(d1.maxSpeed, d1);
treeMapData.put(d2.maxSpeed, d2);
treeMapData.put(d3.maxSpeed, d3);
treeMapData.put(d4.maxSpeed, d4);
treeMapData.put(d5.maxSpeed, d5);
// Good: I can iterate a subcollection efficiently
System.out.println(">>>>>>> TreeMap: subcollection");
for(Map.Entry<Integer, Train> entry : treeMapData.tailMap(start).entrySet()) {
System.out.println(entry.getValue());
}
System.out.println("\n>>>>>>> TreeMap: get");
// Bad: I have to iterate the whole collection to reach the data
for(Map.Entry<Integer, Train> entry: treeMapData.entrySet()) {
if (entry.getValue().id.equals(seekedId)) {
System.out.println(entry.getValue());
}
}
// Also bad: the values used as keys might not be unique
}
输出
>>>>>>> TreeMap: subcollection
FlyingScotman = (3, blue)
TGV = (4, red)
HogwartExpress = (5, blue)
>>>>>>> TreeMap: get
FlyingScotman = (3, blue)
>>>>>>> HashMap: subcollection
FlyingScotman = (3, blue)
TGV = (4, red)
HogwartExpress = (5, blue)
>>>>>>> HashMap: get
FlyingScotman = (3, blue)
MapUtil.sortByValue
方法由Carter Page:Sort a Map<Key, Value> by values (Java)
提前致谢,如果有任何不明确的地方,请告诉我。
答案 0 :(得分:0)
您可以为实现HashMap
的{{1}}创建包装类,并添加一个有序集来存储值。番石榴Map
应该是好的,因为它允许具有相同顺序的元素。
它看起来像数据库中的索引。您将以更慢的修改为代价获得更快的读取操作。
TreeMultiset