所以,我正在处理有关对象4,000,我需要将对象的ID映射到对象。
teamB
事情是,大约34,35次有一个关键的碰撞,其中两个项目具有相同的密钥。我该怎么办?我不想做一个
private HashMap<Foo, Bar> fooBar;
由于列表不会在99%的时间内使用,而且我有一些资源限制。解决这个问题的标准方法是什么?
答案 0 :(得分:1)
您有多种选择:
使用Map<Foo, List<Bar>>
。您提到了资源限制,但是,严重的是,如果4000 List
个对象太多,那么您需要更改硬件: - )
使用常用的多地图实施之一。其中许多使用映射值的某些变体作为列表,因此这主要是实现第一个选项的更简单方法。
更改Bar
的实施以支持复合。这可能非常有效,因为非复合子类可能只返回自身。但它将类设计与实现细节混淆(假设Bars自然不是复合体)。
添加一个支持单个或多个Bar
对象的新类,然后映射到该类。
例如:
interface Bars {
public Stream<Bar> getBars();
public Bars addBars(Bars bars);
}
class SingleBar implements Bars {
private final Bar bar;
public SingleBar(Bar bar) {
this.bar = bar;
}
public Stream<Bar> getBars() {
return Stream.of(bar);
}
public Bars addBars(Bars bars) {
return new MultiBar().addBars(this);
}
}
class MultiBar implements Bars {
private final List<Bar> barList = new ArrayList<>();
public Stream<Bar> getBars() {
return barList.stream();
}
public Bars addBars(Bars bars) {
bars.getBars().forEach(barList::add);
return this;
}
}
Map<Foo, Bars> map = new HashMap<>();
map.merge(foo, new SingleBar(bar), Bars::addBars);
map.get(foo).getBars().forEach(...);
老实说,为避免列表似乎需要做很多工作,而且效率可能不高。我会选择1或2选项。
答案 1 :(得分:0)
我认为您可以使用两个 HashMap
前HashMap < Foo, Bar>
用于存储99%而不用key collisions
而后者HashMap < Foo, List<Bar>>
用于存储保持1%,当你需要通过ID选择对象时,选择所有这两个HashMap。
希望它可以帮到你。
答案 2 :(得分:0)
在apache commons lang中有一个多地图实现。如果你最终不得不做地图&gt;它可能有用的东西。您可能还想找到另一个实际上是唯一的密钥。