Якщо у мене є колекція, наприклад Collection<String> strs
, як я можу отримати перший предмет? Я міг просто зателефонувати Iterator
, взяти його спочатку next()
, а потім викинути Iterator
. Чи є менш марнотратний спосіб це зробити?
Якщо у мене є колекція, наприклад Collection<String> strs
, як я можу отримати перший предмет? Я міг просто зателефонувати Iterator
, взяти його спочатку next()
, а потім викинути Iterator
. Чи є менш марнотратний спосіб це зробити?
Відповіді:
Iterables.get (вашC, indexYouWant)
Тому що, якщо ви користуєтеся колекціями, ви повинні використовувати колекції Google.
Схоже, це найкращий спосіб зробити це:
String first = strs.iterator().next();
Чудове запитання ... Спочатку це здається наглядом за Collection
інтерфейсом.
Зауважте, що "first" не завжди повертає перше, що ви помістили в колекцію, і може мати сенс лише для замовлених колекцій. Можливо, тому немає get(item)
дзвінка, оскільки замовлення не обов'язково зберігається.
Хоча це може здатися трохи марнотратним, це може бути не так вже й погано, як ви думаєте. Iterator
Дійсно тільки містить інформацію індексації в колекції, як правило , НЕ копію всієї колекції. Викликання цього методу створює Iterator
об'єкт, але це справді єдиний накладний (не як копіювання всіх елементів).
Наприклад, дивлячись на тип, який повертається ArrayList<String>.iterator()
методом, ми бачимо, що він є ArrayList::Itr
. Це внутрішній клас, який просто отримує доступ до елементів списку безпосередньо, а не копіює їх.
Просто не забудьте перевірити повернення, iterator()
оскільки воно може бути порожнім або null
залежно від реалізації.
У java 8:
Optional<String> firstElement = collection.stream().findFirst();
Для старих версій Java існує метод getFirst у програмі Guava Iterables :
Iterables.getFirst(iterable, defaultValue)
getFirst
методу. Є get
і getLast
методи
Не існує такого поняття, як "перший" предмет у a, Collection
тому що це .. ну просто колекція.
З методу Collection.iterator () документації Java-документа :
Немає гарантій щодо порядку повернення елементів ...
Тож ви не можете.
Якщо ви використовуєте інший інтерфейс, такий як List , ви можете зробити наступне:
String first = strs.get(0);
Але безпосередньо з колекції це неможливо.
get(int n)
, що визначено для цьогоCollection
Здається, що ваша колекція хоче бути схожою на список, тому я б запропонував:
List<String> myList = new ArrayList<String>();
...
String first = myList.get(0);
У Java 8 у вас є кілька операторів, наприклад, ліміт
/**
* 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 надає onlyElement
Collector
, але використовуйте його лише в тому випадку, якщо ви очікуєте, що колекція має саме один елемент.
Collection<String> stringCollection = ...;
String string = collection.stream().collect(MoreCollectors.onlyElement())
Якщо ви не впевнені, скільки елементів є, скористайтеся findFirst
.
Optional<String> optionalString = collection.stream().findFirst();
Можна робити кастинг. Наприклад, якщо існує один метод із цим визначенням, і ви знаєте, що цей метод повертає список:
Collection<String> getStrings();
А після виклику цього вам потрібен перший елемент, ви можете це зробити так:
List<String> listString = (List) getStrings();
String firstElement = (listString.isEmpty() ? null : listString.get(0));
Якщо ви знаєте, що колекція - це черга, ви можете кинути її в чергу і легко отримати її.
Існує кілька структур, якими ви можете скористатися, щоб отримати замовлення, але вам потрібно буде передати його.
Це повністю залежить від того, яку реалізацію ви використовували, чи пов’язаний список архівців, чи інші реалізації набору.
якщо він встановлений, ви можете безпосередньо отримати перший елемент, їх може бути фокус циклу над колекцією, створити змінну значення 1 та отримати значення, коли значення прапора дорівнює 1 після того, як перервати цю петлю.
якщо це реалізація списку, то це легко, визначивши номер індексу.
Функціональний спосіб:
public static <T> Optional<T> findFirst(List<T> result) {
return Optional.ofNullable(result)
.map(List::stream)
.flatMap(Stream::findFirst);
}
вище збереження фрагмента коду від NullPointerException та IndexOutOfBoundsException
List<T>
не задовольняє умову , що він повинен працювати для Collection<String>
, але, звичайно, може бути закріплена з допомогою Collection<T>
, з додатковим зміною: .map(Collection::stream)
.
Ви можете це зробити:
String strz[] = strs.toArray(String[strs.size()]);
String theFirstOne = strz[0];
Javadoc для Collection надає наступне вказівка wrt впорядкування елементів масиву:
Якщо ця колекція дає будь-які гарантії того, в якому порядку її елементи повертаються ітератором, цей метод повинен повернути елементи в тому ж порядку.