从集合中获取元素

本文翻译自:Getting an element from a Set

Why doesn't Set provide an operation to get an element that equals another element? 为什么Set不提供一个操作来获得一个等于另一个元素的元素?

Set<Foo> set = ...;
...
Foo foo = new Foo(1, 2, 3);
Foo bar = set.get(foo);   // get the Foo element from the Set that equals foo

I can ask whether the Set contains an element equal to bar , so why can't I get that element? 我可以问Set是否包含一个等于bar的元素,为什么我不能得到那个元素? :( :(

To clarify, the equals method is overridden, but it only checks one of the fields, not all. 为了澄清,重写了equals方法,但它只检查其中一个字段,而不是所有字段。 So two Foo objects that are considered equal can actually have different values, that's why I can't just use foo . 所以两个被认为相等的Foo对象实际上可以有不同的值,这就是为什么我不能只使用foo


#1楼

参考:https://stackoom.com/question/uyJc/从集合中获取元素


#2楼

To answer the precise question " Why doesn't Set provide an operation to get an element that equals another element?", the answer would be: because the designers of the collection framework were not very forward looking. 为了回答准确的问题“ 为什么 Set不提供一个操作来获得一个与另一个元素相等的元素?”,答案是:因为集合框架的设计者不是非常具有前瞻性。 They didn't anticipate your very legitimate use case, naively tried to "model the mathematical set abstraction" (from the javadoc) and simply forgot to add the useful get() method. 他们没有预料到你的合法用例,天真地试图“模拟数学集抽象”(来自javadoc)并且忘记添加有用的get()方法。

Now to the implied question " how do you get the element then": I think the best solution is to use a Map<E,E> instead of a Set<E> , to map the elements to themselves. 现在回到隐含的问题“你如何获得元素”:我认为最好的解决方案是使用Map<E,E>而不是Set<E>来将元素映射到它们自己。 In that way, you can efficiently retrieve an element from the "set", because the get() method of the Map will find the element using an efficient hash table or tree algorithm. 这样,您可以从“set”中有效地检索元素,因为Map的get()方法将使用有效的哈希表或树算法找到该元素。 If you wanted, you could write your own implementation of Set that offers the additional get() method, encapsulating the Map . 如果你愿意,你可以编写自己的Set实现,提供额外的get()方法,封装Map

The following answers are in my opinion bad or wrong: 以下答案在我看来是坏的还是错的:

"You don't need to get the element, because you already have an equal object": the assertion is wrong, as you already showed in the question. “你不需要获得元素,因为你已经有了一个相同的对象”:断言是错误的,正如你已经在问题中所表明的那样。 Two objects that are equal still can have different state that is not relevant to the object equality. 两个相等的对象仍然可以具有与对象相等无关的不同状态。 The goal is to get access to this state of the element contained in the Set , not the state of the object used as a "query". 目标是访问Set包含的元素的这种状态,而不是用作“查询”的对象的状态。

"You have no other option but to use the iterator": that is a linear search over a collection which is totally inefficient for large sets (ironically, internally the Set is organized as hash map or tree that could be queried efficiently). “你没有其他选择,只能使用迭代器”:这是对集合的线性搜索,对于大集合来说是完全低效的(具有讽刺意味的是,在内部, Set被组织为可以有效查询的哈希映射或树)。 Don't do it! 不要这样做! I have seen severe performance problems in real-life systems by using that approach. 通过使用该方法,我已经在现实系统中看到了严重的性能问题。 In my opinion what is terrible about the missing get() method is not so much that it is a bit cumbersome to work around it, but that most programmers will use the linear search approach without thinking of the implications. 在我看来,缺少get()方法的可怕之处并不在于解决它有点麻烦,但大多数程序员都会使用线性搜索方法而不考虑其含义。


#3楼

Quick helper method that might address this situation: 可以解决这种情况的快速帮助方法:

<T> T onlyItem(Collection<T> items) {
    if (items.size() != 1)
        throw new IllegalArgumentException("Collection must have single item; instead it has " + items.size());

    return items.iterator().next();
}

#4楼

Object objectToGet = ...
Map<Object, Object> map = new HashMap<Object, Object>(set.size());
for (Object o : set) {
    map.put(o, o);
}
Object objectFromSet = map.get(objectToGet);

If you only do one get this will not be very performing because you will loop over all your elements but when performing multiple retrieves on a big set you will notice the difference. 如果你只做一个得到这将不会很好,因为你将遍历所有元素,但在大集上执行多次检索时你会发现差异。


#5楼

I know, this has been asked and answered long ago, however if anyone is interested, here is my solution - custom set class backed by HashMap: 我知道,很久以前就已经提出并回答了这个问题,但是如果有人有兴趣,这是我的解决方案 - 由HashMap支持的自定义集合类:

http://pastebin.com/Qv6S91n9 http://pastebin.com/Qv6S91n9

You can easily implement all other Set methods. 您可以轻松实现所有其他Set方法。


#6楼

尝试使用数组:

ObjectClass[] arrayName = SetOfObjects.toArray(new ObjectClass[setOfObjects.size()]);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值