Java get set item

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

Mathematically, elements in sets are not individualised. Solution 1: This will return the first element Solution 2: Or, using Java8:

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

I have a Set instance:

Set siteIdSet = (Set) 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.

Requirement:

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

Hence, right now, I am doing like this.

for (Iterator it = siteIdSet.iterator(); it.hasNext();)

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

This will return the first element

Object firstElement = set.stream().findFirst().get(); 

And then you can do stuff with it straight away:

set.stream().findFirst().ifPresent(); 

Or, if you want to provide an alternative in case the element is missing (my example returns new default string):

set.stream().findFirst().orElse("Empty string"); 

You can even throw an exception if the first element is missing:

set.stream().findFirst().orElseThrow(() -> new MyElementMissingException("Ah, blip, nothing here!")); 

Kudos to Alex Vulaj for prompting me to provide more examples beyond the initial grabbing of the first element.

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

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)

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.

tl;dr

Move elements, and call first() .

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

Set Has No Order

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

Some implementations of Set have 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 Set may indeed be a 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 Set you have no other viable alternative, so trying this may be better than nothing.

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 if test for isEmpty rather than the Question’s for loop.

Use SortedSet

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

  • TreeSet .
  • ConcurrentSkipListSet .
  • In Google Guava, the SortedSetMultimap class returns a SortedSet from its asMap method.

Use LinkedHashSet For Insertion-Order

If all you need is to remember elements in the order they were added to the Set use 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).

How to get first item from a java.util.Set?, Move elements, and call first(). new TreeSet( pContext.getParent().getPropertyValue( … ) // Transfer elements from your `Set` … Code samplefor(String aSiteId: siteIdSet) Feedback

Java: Get first item from a collection

If I have a collection, such as Collection strs , how can I get the first item out? I could just call an Iterator , take its first next() , then throw the Iterator away. Is there a less wasteful way to do it?

Looks like that is the best way to do it:

String first = strs.iterator().next(); 

Great question. At first, it seems like an oversight for the Collection interface.

Note that «first» won’t always return the first thing you put in the collection, and may only make sense for ordered collections. Maybe that is why there isn’t a get(item) call, since the order isn’t necessarily preserved.

While it might seem a bit wasteful, it might not be as bad as you think. The Iterator really just contains indexing information into the collection, not a usually a copy of the entire collection. Invoking this method does instantiate the Iterator object, but that is really the only overhead (not like copying all the elements).

For example, looking at the type returned by the ArrayList.iterator() method, we see that it is ArrayList::Itr . This is an internal class that just accesses the elements of the list directly, rather than copying them.

Just be sure you check the return of iterator() since it may be empty or null depending on the implementation.

Because really, if you’re using Collections, you should be using Google Collections.

Optional firstElement = collection.stream().findFirst(); 

For older versions of java, there is a getFirst method in guava iterables :

Iterables.getFirst(iterable, defaultValue) 

There is no such a thing as «first» item in a Collection because it is .. well simply a collection.

From the Java doc’s Collection.iterator() method:

There are no guarantees concerning the order in which the elements are returned.

If you use another interface such as List , you can do the following:

But directly from a Collection this is not possible.

How to get the first element of the List or Set?, This will help you retrieve the first element of the list or set. Given that the set or list is not empty (get() on empty optional will throw …

Getting an element from a Set

Why doesn’t Set provide an operation to get an element that equals another element?

Set set = . ; . Foo foo = new Foo(1, 2, 3); **** = 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? 🙁

To clarify, the equals method is overridden, but it only checks one of the fields, not all. So two Foo objects that are considered equal can actually have different values, that’s why I can’t just use foo .

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. 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.

Now to the implied question » how do you get the element then»: I think the best solution is to use a Map instead of a Set , to map the elements to themselves. 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. If you wanted, you could write your own implementation of Set that offers the additional get() method, encapsulating the 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».

«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). 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.

There would be no point of getting the element if it is equal. A Map is better suited for this usecase.

If you still want to find the element you have no other option but to use the iterator:

public static void main(String[] args) < Setset = new HashSet(); set.add(new Foo("Hello")); for (Iterator it = set.iterator(); it.hasNext(); ) < Foo f = it.next(); if (f.equals(new Foo("Hello"))) System.out.println("foo found"); >> static class Foo < String string; Foo(String string) < this.string = string; >@Override public int hashCode() < return string.hashCode(); >@Override public boolean equals(Object obj) < return string.equals(((Foo) obj).string); >> 

If you have an equal object, why do you need the one from the set? If it is «equal» only by a key, an Map would be a better choice.

Anyway, the following will do it:

Foo getEqual(Foo sample, Set all) < for (Foo one : all) < if (one.equals(sample)) < return one; >> return null; > 

With Java 8 this can become a one liner:

return all.stream().filter(sample::equals).findAny().orElse(null); 

Default Set in Java is, unfortunately, not designed to provide a «get» operation, as jschreiner accurately explained.

The solutions of using an iterator to find the element of interest (suggested by dacwe) or to remove the element and re-add it with its values updated (suggested by KyleM), could work, but can be very inefficient.

Overriding the implementation of equals so that non-equal objects are «equal», as stated correctly by david ogren , can easily cause maintenance problems.

And using a Map as an explicit replacement (as suggested by many), imho, makes the code less elegant.

If the goal is to get access to the original instance of the element contained in the set (hope I understood correctly your use case), here is another possible solution.

I personally had your same need while developing a client-server videogame with Java. In my case, each client had copies of the components stored in the server and the problem was whenever a client needed to modify an object of the server.

Passing an object through the internet meant that the client had different instances of that object anyway. In order to match this «copied» instance with the original one, I decided to use Java UUIDs .

So I created an abstract class UniqueItem, which automatically gives a random unique id to each instance of its subclasses.

This UUID is shared between the client and the server instance, so this way it could be easy to match them by simply using a Map.

However directly using a Map in a similar usecase was still inelegant. Someone might argue that using an Map might be more complicated to mantain and handle.

For these reasons I implemented a library called MagicSet, that makes the usage of an Map «transparent » to the developer.

Like the original Java HashSet , a MagicHashSet (which is one of the implementations of MagicSet provided in the library) uses a backing HashMap, but instead of having elements as keys and a **** value as values, it uses the UUID of the element as key and the element itself as value. This does not cause overhead in the memory use compared to a normal HashSet.

Moreover, a MagicSet can be used exactly as a Set, but with some more methods providing additional functionalities, like getFromId(), popFromId(), removeFromId(), etc.

The only requirement to use it is that any element that you want to store in a MagicSet needs to extend the abstract class UniqueItem.

Here is a code example, imagining to retrieve the original instance of a city from a MagicSet, given another instance of that city with the same UUID (or even just its UUID).

class City extends UniqueItem < // Somewhere in this class public void doSomething() < // Whatever >> public class GameMap < private MagicSetcities; public GameMap(Collection cities) < cities = new MagicHashSet<>(cities); > /* * cityId is the UUID of the city you want to retrieve. * If you have a copied instance of that city, you can simply * call copiedCity.getId() and pass the return value to this method. */ public void doSomethingInCity(UUID cityId) < City city = cities.getFromId(cityId); city.doSomething(); >// Other methods can be called on a MagicSet too > 

Java: Get first item from a collection, Sorted by: 518. Looks like that is the best way to do it: String first = strs.iterator ().next (); Great question At first, it seems like an oversight for the …

Источник

Читайте также:  Window server 2008 php mysql
Оцените статью