如何从 java.util.Set 中获取第一项?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20511140/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 02:26:51  来源:igfitidea点击:

How to get first item from a java.util.Set?

javaset

提问by KrishPrabakar

I have a Setinstance:

我有一个Set实例:

Set<String> siteIdSet = (Set<String>) pContext.getParent().getPropertyValue(getCatalogProperties().getSitesPropertyName());

The pContext.getParent().getPropertyValue()is out-of-the-box code upon which I don't have any control to modify.

pContext.getParent().getPropertyValue()是开箱即用的代码,我无法对其进行任何修改。

Requirement:

要求:

I wanted to get the firstdefault element out of it (always). However, I couldn't find a method get(index)like in an ArrayList.

我想从中获取第一个默认元素(总是)。但是,我找不到get(index)ArrayList.

Hence, right now, I am doing like this.

因此,现在,我正在这样做。

for (Iterator<String> it = siteIdSet.iterator(); it.hasNext();) {
    siteId = it.next();
    break;
}

Is there any (other) efficient way(short and better) of achieving this?

是否有任何(其他)有效的方式(简短且更好)来实现这一目标?

采纳答案by Taylor Hx

From the Oracle docs:

来自Oracle 文档

As implied by its name, this interface models the mathematical setabstraction.

正如其名称所暗示的那样,该接口对数学集合抽象进行建模。

In Set Theory, "a "set" is a collection of distinct objects, considered as an object in its own right." - [Wikipedia - Set].

集合论中,“一个“集合”是不同对象的集合,被视为一个对象。- [维基百科 - 设置]

Mathematically, elements in sets are not individualised. Their only identity is derived from their presence in the set. Therefore, there is no point in getting the "first" element in a set, as conceptually such a task is illogical.

在数学上,集合中的元素不是个体化的。他们唯一的身份来自他们在系列中的存在。因此,获取集合中的“第一个”元素没有意义,因为从概念上讲,这样的任务是不合逻辑的。

There may be no point to getting the "first" element from a set, but if all you need is to get one single object from a set (with no guarantees as to which object that is) you can do the following:

从集合中获取“第一个”元素可能没有意义,但是如果您只需要从集合中获取一个对象(不保证是哪个对象),您可以执行以下操作:

for(String aSiteId: siteIdSet) {
    siteId = aSiteId;
    break;
}

This is a slightly shorter way (than the method you posted) to get the "first" object of a Set, however since an Iterator is still being created (under the hood) it does not grant any performance benefit.

这是获取 a 的“第一个”对象的稍微短一点的方法(比您发布的方法)Set,但是由于仍在创建 Iterator(在幕后),因此它不会带来任何性能优势。

回答by hanish.kh

Set is a unique collection of items. So there is no notion of first element. If you want items in the sorted order, you can use TreeSetfrom which you can retrieve the first element using TreeSet#first().

Set 是一个独特的项目集合。所以没有第一个元素的概念。如果您想要按排序顺序排列的项目,您可以使用TreeSet,您可以使用TreeSet#first()从中检索第一个元素。

回答by Hari Menon

Setdoes not enforce ordering. There is no guarantee that you will always get the "first" element even if you use an iterator over a HashSetlike you have done in the question.

Set不强制排序。即使您HashSet像在问题中所做的那样使用迭代器,也不能保证您将始终获得“第一个”元素。

If you need to have predictable ordering, you need to use the LinkedHashSetimplementation. When you iterate over a LinkedHashSet, you will get the elements in the order you inserted. You still need to use an iterator, because having a getmethod in LinkedHashSetwould need you to use the concrete class everywhere.

如果需要可预测的排序,则需要使用LinkedHashSet实现。当您遍历 LinkedHashSet 时,您将按照插入的顺序获取元素。您仍然需要使用迭代器,因为有一个get方法LinkedHashSet需要您在任何地方使用具体类。

回答by Nishant Lakhara

There is no point in retrieving first element from a Set. If you have such kind of requirement use ArrayList instead of sets. Sets do not allow duplicates. They contain distinct elements.

从 Set 中检索第一个元素是没有意义的。如果您有此类需求,请使用 ArrayList 而不是集合。集合不允许重复。它们包含不同的元素。

回答by kalakanhu

To Access the element you need to get an iterator . But Iterator does not guarantee in a particular order unless it is some Exceptional case. so it is not sure to get the first Element.

要访问元素,您需要获取迭代器。但是迭代器不保证以特定的顺序,除非是一些特殊的情况。所以不确定是否获得第一个元素。

回答by Mumbleskates

This is a difficult question I came up against the other day myself. java.util.LinkedHashSetmaintains a linked list of its contents (addition-ordered by default) but does not provide any accessors. Other structure types will fail to provide O(1) on add(), remove(), and contains().

这是我前几天自己遇到的一个难题。java.util.LinkedHashSet维护其内容的链接列表(默认情况下按添加顺序),但不提供任何访问器。其他结构类型将无法提供上O(1) add()remove()contains()

You can use a LinkedHashSetand get its iterator(), grab one element, and discard it. If you don't care too much about speed or memory when doing this frequently to numerous different sets, that is probably your solution... but that seemed wasteful to me. Plus I had a little extra desired functionality.

您可以使用 aLinkedHashSet并获取它的iterator(),获取一个元素,然后丢弃它。如果您在频繁地对许多不同的集合执行此操作时不太关心速度或内存,那可能是您的解决方案……但这对我来说似乎很浪费。另外,我还有一些额外想要的功能。

I ended up writing my own class, dubbed RandomAccessLinkedHashSet, which concurrently maintains a hashtable, a doubly linked list, and an order-irrelevant array. I wrote it to comply with both Setand Deque, though the Deque implementation is a little sketchy since it will fail to push()elements it already contains, a little bit of a stretch for the interface's contract. Maintaining the third structure, the array, is not necessary at all for what you're doing, but it also allows access to a randomelement in the set in whatever capacity you can actually provide a random value.

我最终编写了自己的类,称为 dubbed RandomAccessLinkedHashSet,它同时维护一个哈希表、一个双向链表和一个与顺序无关的数组。我写它是为了遵守SetDeque,尽管 Deque 实现有点粗略,因为它会失败push()它已经包含的元素,对接口的契约有点牵强。维护第三个结构,数组,对于您正在做的事情根本没有必要,但它也允许以您实际上可以提供随机值的任何容量访问集合中的随机元素。

If you're interested I can provide this source. I haven't Serializedit yet but it works great in runtime.

如果你有兴趣,我可以提供这个资源。我还没有Serialized,但它在运行时效果很好。

If you cannot guarantee the type of Setprovided in any way, then you'll have to stick with the Iteratorthing.

如果您不能Set以任何方式保证所提供的类型,那么您将不得不坚持使用Iterator

回答by Masudul

As, you mentioned pContext.getParent().getPropertyValuereturn Set. You can convert Setto Listto get the first element. Just change your code like:

正如你提到的pContext.getParent().getPropertyValuereturn Set。您可以转换SetList获取第一个元素。只需更改您的代码,例如:

 Set<String> siteIdSet = (Set<String>) pContext.getParent().getPropertyValue(..);
 List<String> siteIdList=new ArrayList<>(siteIdSet);

 String firstItem=siteIdList.get(0);

回答by Marcin Szymczak

Set by definition is not ordered.

根据定义设置是没有顺序的。

You probably use wrong collection.

您可能使用了错误的集合。

回答by Sagar Koshti

This will return the first element

这将返回第一个元素

set.iterator().next();

回答by Basil Bourque

tl;dr

tl;博士

Call SortedSet::first

称呼 SortedSet::first

Move elements, and call first().

移动元素,然后调用first().

new TreeSet<String>( 
    pContext.getParent().getPropertyValue( … )   // Transfer elements from your `Set` to this new `TreeSet`, an implementation of the `SortedSet` interface. 
)
.first()

SetHas No Order

Set没有订单

As others have said, a Setby definition has no order. Therefore asking for the “first” element has no meaning.

正如其他人所说, aSet根据定义没有顺序。因此,要求“第一个”元素没有意义。

Some implementations of Sethave an order such as the order in which items were added. That unofficial order may be available via the Iterator. But that order is accidental and not guaranteed. If you are lucky, the implementation backing your Setmay indeed be a SortedSet.

的某些实现Set具有顺序,例如添加项目的顺序。该非官方订单可通过Iterator. 但该顺序是偶然的,不能保证。如果幸运的话,支持您的实现Set可能确实是一个SortedSet.

CAVEAT:If order is critical, do not rely on such behavior. If reliability is not critical, such undocumented behavior might be handy. If given a Setyou have no other viable alternative, so trying this may be better than nothing.

警告:如果顺序很重要,请不要依赖此类行为。如果可靠性不重要,这种未记录的行为可能会很方便。如果给出一个Set你没有其他可行的选择,那么尝试这个可能总比没有好。

Object firstElement = mySet.iterator().next();

To directly address the Question… No, not really any shorter way to get first element from iterator while handling the possible case of an empty Set. However, I would prefer an iftest for isEmptyrather than the Question's forloop.

直接解决这个问题……不,在处理可能的空 Set 情况时,从迭代器中获取第一个元素并不是任何更短的方法。但是,我更喜欢if测试isEmpty而不是问题的for循环。

if ( ! mySet.isEmpty() ) {
    Object firstElement = mySet.iterator().next();
)

Use SortedSet

SortedSet

If you care about maintaining a sort order in a Set, use a SortedSetimplementation. Such implementations include:

如果您关心维护 a 中的排序顺序Set,请使用SortedSet实现。此类实现包括:

Use LinkedHashSetFor Insertion-Order

使用LinkedHashSet对于插入顺序

If all you need is to remember elements in the order they were added to the Setuse a LinkedHashSet.

如果您只需要按照添加到元素的顺序记住元素,请Set使用 a LinkedHashSet

To quote the doc, this class…

引用文档,这个类......

maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is the order in which elements were inserted into the set (insertion-order).

维护一个双向链表,贯穿其所有条目。这个链表定义了迭代顺序,也就是元素被插入到集合中的顺序(插入顺序)。