Jeśli mam kolekcję, np. Collection<String> strs
Jak mogę uzyskać pierwszy przedmiot? Mógłbym po prostu zadzwonić Iterator
, wziąć pierwszy next()
, a potem wyrzucić Iterator
. Czy istnieje mniej marnotrawny sposób?
Jeśli mam kolekcję, np. Collection<String> strs
Jak mogę uzyskać pierwszy przedmiot? Mógłbym po prostu zadzwonić Iterator
, wziąć pierwszy next()
, a potem wyrzucić Iterator
. Czy istnieje mniej marnotrawny sposób?
Odpowiedzi:
Iterables.get (yourC, indexYouWant)
Ponieważ tak naprawdę, jeśli używasz kolekcji, powinieneś używać kolekcji Google.
Wygląda na to, że jest to najlepszy sposób:
String first = strs.iterator().next();
Świetne pytanie ... Na początku wydaje się to niedopatrzeniem Collection
interfejsu.
Pamiętaj, że „pierwsze” nie zawsze zwróci pierwszą rzecz, którą umieścisz w kolekcji, i może mieć sens tylko w przypadku zamówionych kolekcji. Być może dlatego nie ma get(item)
połączenia, ponieważ kolejność niekoniecznie jest zachowana.
Choć może wydawać się to trochę marnotrawstwem, może nie być tak złe, jak myślisz. Iterator
Naprawdę tylko zawiera informacje indeksowania do kolekcji, a nie zwykle kopię całej kolekcji. Wywołanie tej metody tworzy instancję Iterator
obiektu, ale tak naprawdę jest to jedyny narzut (nie tak jak kopiowanie wszystkich elementów).
Na przykład, patrząc na typ zwracany przez ArrayList<String>.iterator()
metodę, widzimy, że tak jest ArrayList::Itr
. Jest to klasa wewnętrzna, która po prostu uzyskuje bezpośredni dostęp do elementów listy, zamiast je kopiować.
Pamiętaj tylko o sprawdzeniu zwrotu, iterator()
ponieważ może być pusty lub null
zależy od implementacji.
W java 8:
Optional<String> firstElement = collection.stream().findFirst();
W starszych wersjach java istnieje metoda getFirst w Guava Iterables :
Iterables.getFirst(iterable, defaultValue)
getFirst
dostępnej metody. Istnieją get
i getLast
metody
Nie ma czegoś takiego jak „pierwszy” element w Collection
ponieważ jest to… no cóż, kolekcja.
Z metody Collection.iterator () Java doc :
Nie ma żadnych gwarancji dotyczących kolejności zwrotu elementów ...
Więc nie możesz.
Jeśli używasz innego interfejsu, takiego jak Lista , możesz wykonać następujące czynności:
String first = strs.get(0);
Ale bezpośrednio z kolekcji nie jest to możliwe.
get(int n)
jest zdefiniowany dlaCollection
Wygląda na to, że Twoja kolekcja chce być podobna do listy, więc sugeruję:
List<String> myList = new ArrayList<String>();
...
String first = myList.get(0);
W Javie 8 masz do dyspozycji wielu operatorów, na przykład limit
/**
* Operator that limit the total number of items emitted through the pipeline
* Shall print
* [1]
* @throws InterruptedException
*/
@Test
public void limitStream() throws InterruptedException {
List<Integer> list = Arrays.asList(1, 2, 3, 1, 4, 2, 3)
.stream()
.limit(1)
.collect(toList());
System.out.println(list);
}
Guava zapewnia onlyElement
Collector
, ale używaj go tylko wtedy, gdy oczekujesz, że kolekcja będzie miała dokładnie jeden element.
Collection<String> stringCollection = ...;
String string = collection.stream().collect(MoreCollectors.onlyElement())
Jeśli nie masz pewności, ile jest elementów, użyj findFirst
.
Optional<String> optionalString = collection.stream().findFirst();
Możesz wykonać casting. Na przykład, jeśli istnieje jedna metoda z tą definicją i wiesz, że ta metoda zwraca listę:
Collection<String> getStrings();
A po wywołaniu potrzebujesz pierwszego elementu, możesz to zrobić w następujący sposób:
List<String> listString = (List) getStrings();
String firstElement = (listString.isEmpty() ? null : listString.get(0));
Jeśli wiesz, że kolekcja jest kolejką, możesz rzucić kolekcję do kolejki i łatwo ją zdobyć.
Istnieje kilka struktur, z których możesz skorzystać, aby uzyskać zamówienie, ale musisz do niego rzucić.
Zależy to całkowicie od zastosowanej implementacji, listy połączonych arraylist lub innych implementacji zestawu.
jeśli jest ustawiony, możesz bezpośrednio uzyskać pierwszy element, może to być pętla trick nad kolekcją, utwórz zmienną o wartości 1 i uzyskaj wartość, gdy wartość flagi wynosi 1 po tym przerwaniu tej pętli.
jeśli jest to implementacja listy, to łatwo jest zdefiniować numer indeksu.
Funkcjonalny sposób:
public static <T> Optional<T> findFirst(List<T> result) {
return Optional.ofNullable(result)
.map(List::stream)
.flatMap(Stream::findFirst);
}
powyżej zachowaj fragment kodu z NullPointerException i IndexOutOfBoundsException
List<T>
nie spełnia warunku, że powinien pracować dla Collection<String>
, ale oczywiście, że mogą być ustalane za pomocą Collection<T>
, z dodatkową zmianą: .map(Collection::stream)
.
Możesz to zrobić:
String strz[] = strs.toArray(String[strs.size()]);
String theFirstOne = strz[0];
Program javadoc dla kolekcji podaje następujące zastrzeżenie dotyczące uporządkowania elementów tablicy:
Jeśli ta kolekcja gwarantuje, w jakiej kolejności jej elementy są zwracane przez iterator, ta metoda musi zwrócić elementy w tej samej kolejności.