Se eu tiver uma coleção, como Collection<String> strs
, como posso retirar o primeiro item? Eu poderia simplesmente chamar um Iterator
, pegar o primeiro next()
e depois jogar Iterator
fora. Existe uma maneira menos dispendiosa de fazer isso?
Se eu tiver uma coleção, como Collection<String> strs
, como posso retirar o primeiro item? Eu poderia simplesmente chamar um Iterator
, pegar o primeiro next()
e depois jogar Iterator
fora. Existe uma maneira menos dispendiosa de fazer isso?
Respostas:
Iterables.get (yourC, indexYouWant)
Porque, na verdade, se você estiver usando coleções, deve usar coleções do Google.
Parece que é a melhor maneira de fazer isso:
String first = strs.iterator().next();
Ótima pergunta ... No começo, parece uma supervisão para o Collection
interface.
Observe que "first" nem sempre retorna a primeira coisa que você coloca na coleção e pode fazer sentido apenas para coleções ordenadas. Talvez seja por isso que não há uma get(item)
ligação, pois a ordem não é necessariamente preservada.
Embora possa parecer um pouco inútil, pode não ser tão ruim quanto você pensa. Ele Iterator
realmente contém apenas informações de indexação na coleção, e não geralmente uma cópia de toda a coleção. A invocação desse método instancia o Iterator
objeto, mas essa é realmente a única sobrecarga (não é como copiar todos os elementos).
Por exemplo, olhando para o tipo retornado pelo ArrayList<String>.iterator()
método, vemos que é ArrayList::Itr
. Esta é uma classe interna que apenas acessa os elementos da lista diretamente, em vez de copiá-los.
Apenas certifique-se de verificar o retorno, iterator()
pois ele pode estar vazio ou null
dependendo da implementação.
No java 8:
Optional<String> firstElement = collection.stream().findFirst();
Para versões mais antigas do java, existe um método getFirst no Guava Iterables :
Iterables.getFirst(iterable, defaultValue)
getFirst
método disponível. Existem get
e getLast
métodos
Não existe o "primeiro" item em um Collection
porque é ... bem, simplesmente uma coleção.
No método Collection.iterator () do Java doc :
Não há garantias quanto à ordem em que os elementos são retornados ...
Então você não pode.
Se você usar outra interface, como Lista , poderá fazer o seguinte:
String first = strs.get(0);
Mas diretamente de uma coleção, isso não é possível.
get(int n)
é definido paraCollection
Parece que sua coleção quer ser parecida com uma lista, então eu sugiro:
List<String> myList = new ArrayList<String>();
...
String first = myList.get(0);
No Java 8, você tem muitos operadores para usar, por exemplo, limite
/**
* 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);
}
O Goiaba fornece um onlyElement
Collector
, mas só o usa se você espera que a coleção tenha exatamente um elemento.
Collection<String> stringCollection = ...;
String string = collection.stream().collect(MoreCollectors.onlyElement())
Se você não tiver certeza de quantos elementos existem, use findFirst
.
Optional<String> optionalString = collection.stream().findFirst();
Você pode fazer um casting. Por exemplo, se existe um método com esta definição e você sabe que esse método está retornando uma Lista:
Collection<String> getStrings();
E depois de invocá-lo, você precisa do primeiro elemento, pode fazê-lo assim:
List<String> listString = (List) getStrings();
String firstElement = (listString.isEmpty() ? null : listString.get(0));
Se você souber que a coleção é uma fila, poderá convertê-la em uma fila e obtê-la facilmente.
Existem várias estruturas que você pode usar para obter o pedido, mas precisará convertê-lo.
Depende totalmente de qual implementação você usou, se arraylist linkedlist ou outras implementações de set.
se estiver definido, você poderá obter diretamente o primeiro elemento, o loop pode ser um truque sobre a coleção, criar uma variável de valor 1 e obter valor quando o valor do sinalizador for 1 após a interrupção desse loop.
se for a implementação da lista, será fácil definir o número do índice.
Maneira funcional:
public static <T> Optional<T> findFirst(List<T> result) {
return Optional.ofNullable(result)
.map(List::stream)
.flatMap(Stream::findFirst);
}
preservação de snippet de código acima de NullPointerException e IndexOutOfBoundsException
List<T>
não satisfazer a condição de que ele deve trabalhar para um Collection<String>
, mas é claro que pode ser corrigido usando Collection<T>
, com a alteração adicional: .map(Collection::stream)
.
Você poderia fazer isso:
String strz[] = strs.toArray(String[strs.size()]);
String theFirstOne = strz[0];
O javadoc para Collection fornece a seguinte advertência por ordem dos elementos da matriz:
Se essa coleção garantir qualquer ordem de retorno de seus elementos por seu iterador, esse método deverá retornar os elementos na mesma ordem.