如何将Map.values作为集而不是集合?

时间:2015-04-25 11:45:45

标签: java dictionary collections

我有一张地图Map<String, SomeType>,其中SomeType的每个实例都按名称map.put(object.getName(), object)添加。最后,map.values()中没有重复项。

现在,我想从此地图中获取Set<SomeType>,而不像new HashSet<>(map.values())那样制作副本。

这是否可行,仅限标准库?

3 个答案:

答案 0 :(得分:5)

您已经知道如何使用new HashSet<>(map.values())执行此操作。您无法直接获取一组值,因为值可以包含重复项。即使在您的特定Map中没有重复值,在一般Map中也可能存在重复值。

您可以使用Java 8 Streams做一些事情,但它没有明确地实例化Set的优势。

Set<SomeType> values = map.values().stream().collect(Collectors.toSet());

答案 1 :(得分:2)

没有this封装器,这是不可能的。

仅仅因为在你的情况下没有重复,这并不意味着他们不能重复。

Java Collections API允许您在Collection中放置重复值,因此合同必须返回Map而不是Collection

答案 2 :(得分:2)

创建任何build(X, N, List) :- findall(X, between(1, N, _), List). 的{​​{1}}视图是一件简单的事情。

public ActionResult Example(int id) {

    var ci = _contentManager.Get(id);

    var editShape = _contentManaget.BuildEditor(ci);

    // more code
    viewModel.Edit = editShape;

    return View(viewModel);
}

#Template

<div>@Display(Model.EditShape)</div>

有了这个,您可以写SetCollection的所有更改都会自动反映在public final class SetView<E> extends AbstractSet<E> { private final Collection<? extends E> collection; private SetView(Collection<? extends E> collection) { this.collection = collection; } public static <E> SetView<E> of(Collection<? extends E> collection) { return new SetView<>(collection); } @Override public boolean contains(Object e) { return collection.contains(e); } // rest omitted. } 中。

这种方法的问题在于,如果不复制Set<E> set = SetView.of(map.values());,某些方法很难实现。例如,您如何撰写Map

最明智的方法是

Set

但这违背了使用视图的目的,而不是仅仅首先复制元素。如果您知道Collection永远不会包含重复项,那么可以完成

size()

但是我建议不要这样做。允许@Override public int size() { return new HashSet<>(collection).size(); } 包含重复值,并且添加具有相同值的两个条目的可能性意味着Collection的合同将被破坏。

除非您非常有充分理由不想复制这些元素,否则我只会使用@Override public int size() { return collection.size(); }