Java映射,几个关键的冲突,解决方法

时间:2016-11-17 02:30:46

标签: java hashmap mapping

所以,我正在处理有关对象4,000,我需要将对象的ID映射到对象。

teamB

事情是,大约34,35次有一个关键的碰撞,其中两个项目具有相同的密钥。我该怎么办?我不想做一个

    private HashMap<Foo, Bar> fooBar;

由于列表不会在99%的时间内使用,而且我有一些资源限制。解决这个问题的标准方法是什么?

3 个答案:

答案 0 :(得分:1)

您有多种选择:

  1. 使用Map<Foo, List<Bar>>。您提到了资源限制,但是,严重的是,如果4000 List个对象太多,那么您需要更改硬件: - )

  2. 使用常用的多地图实施之一。其中许多使用映射值的某些变体作为列表,因此这主要是实现第一个选项的更简单方法。

  3. 更改Bar的实施以支持复合。这可能非常有效,因为非复合子类可能只返回自身。但它将类设计与实现细节混淆(假设Bars自然不是复合体)。

  4. 添加一个支持单个或多个Bar对象的新类,然后映射到该类。

  5. 例如:

    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)

我认为您可以使用两个 HashMapHashMap < Foo, Bar>用于存储99%而不用key collisions而后者HashMap < Foo, List<Bar>>用于存储保持1%,当你需要通过ID选择对象时,选择所有这两个HashMap。

希望它可以帮到你。

答案 2 :(得分:0)

在apache commons lang中有一个多地图实现。如果你最终不得不做地图&gt;它可能有用的东西。您可能还想找到另一个实际上是唯一的密钥。