Java : 컬렉션에서 첫 번째 항목 가져 오기


277

과 같은 컬렉션이있는 경우 Collection<String> strs첫 번째 항목을 어떻게 가져올 수 있습니까? 난 그냥 부를 수있는 Iterator처음을,next() , 다음 던져 Iterator멀리합니다. 덜 낭비하는 방법이 있습니까?


1
물론 구현 컨테이너 클래스를 알고 있다면 첫 번째 요소에 액세스하는 더 좋은 방법이있을 수 있습니다.
Rooke


1
Queue.peek ()가 필요하신 것 같습니다.
Johannes

답변:


131

Iterables.get (yourC, indexYouWant)

실제로 컬렉션을 사용하는 경우 Google 컬렉션을 사용해야합니다.


7
그것은 똑같은 일을하고, 먼저 목록인지 확인하고 색인이 있으면 색인으로 가져옵니다. 또한 실제 콜렉션에서 더 빨리 실패하려고하는 코드가 있습니다 (즉, 인덱스가 너무 큰 경우 전체를 반복하지 않고 끝에 예외를 던지지 않고 파악하려고 시도합니다).
Yishai

1
솔직히 성능면에서는 c.iterator (). next ()보다 약간 느릴 수 있지만 코드는 훨씬 명확하고 수정하기 쉽습니다.
Carl

2
나는 그것이 더 깨끗하다는 데 동의하지만 OP는 낭비에 관한 것이지만, 당신의 대답이 받아 들여진 이후에 그것이 바람직한 것 같아요.
Yishai

8
(여전히) 여기에 도착하는 사람들을 위해 : 나는 이미 GC 라이브러리를 사용하고있는 경우 @DonaldRaab (페이지 아래로)을 선호하지만 jheddings의 대답은 아마도 가장 좋은 방법이라고 생각합니다. 내 대답은 실제로 나중에 유연하게 작성하고 싶을 때입니다 (예 : 두 번째 요소가 새로운 핫 니스 라고 결정하는 경우 ).
Carl

4
때로는 컬렉션을 사용하는 코드 만 사용하기 때문에 할 일이 많지 않습니다.
erickrf

436

가장 좋은 방법은 다음과 같습니다.

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

좋은 질문은 ... 처음에는 Collection 인터페이스에 .

"first"가 항상 컬렉션에 넣은 첫 번째 항목을 반환하지는 않으며 주문한 컬렉션에만 의미가있을 수 있습니다. get(item)주문이 반드시 보존되지 않기 때문에 전화 가없는 이유 일 수 있습니다 .

약간 낭비되는 것처럼 보이지만 생각만큼 나쁘지는 않을 수 있습니다. 는 Iterator정말 그냥 수집, 전체 컬렉션이 아니 보통 사본에 인덱싱 정보가 포함되어 있습니다. 이 메소드를 호출하면 Iterator객체를 인스턴스화 하지만 실제로는 모든 요소를 ​​복사하는 것과는 다른 유일한 오버 헤드입니다.

예를 들어, ArrayList<String>.iterator()메소드가 리턴 한 유형을 살펴보면 유형 이ArrayList::Itr . 이것은 목록의 요소를 복사하지 않고 직접 액세스하는 내부 클래스입니다.

반환 값 iterator()이 비어 있거나 null구현에 따라 리턴 될 수 있는지 확인하십시오 .


3
이 "트릭"은 컬렉션에 실제로 내용이있는 경우에만 작동한다는 점에 유의해야합니다. 비어있는 경우, 이터레이터는 오류를 반환 할 수 있습니다.이 에러는 미리 컬렉션 크기를 확인해야합니다.
우주 감정

20
이것이 정답이어야합니다. 나는 왜 대답이 항상 "다른 도서관을 사용 하는가"를 이해하지 못한다. .
Kuzeko

컬렉션의 두 번째 요소는 어떻습니까? first-> next ()가 작동하지 않는 이유는 무엇입니까? 어떻게해야합니까? 감사!
pb772

충분히 안전하지는 않지만 컬렉션이 항상 첫 번째 요소를 가리키는 것은 아닙니다.
다음 개발자

84

자바 8 :

Optional<String> firstElement = collection.stream().findFirst();

이전 버전의 Java의 경우 Guava Iterables에 getFirst 메소드가 있습니다 .

Iterables.getFirst(iterable, defaultValue)

6
Java 8 솔루션은 컬렉션이 정상적으로 비어있는 경우를 처리하기 때문에 특히 유용합니다.
SpaceTrucker

4
안좋다. 4 줄의 코드를 작성하는 것이 게으 르기 때문에 stream () 오버 헤드를 추가하여 get (0)을 얻습니다. if (! CollectionUtils.isEmpty (productList)) {return Optional.of (productList.get (0)); } return Optional.empty ();
RS

getFirst사용할 수 있는 방법이 없습니다. 있습니다 getgetLast방법
user1209216

4
@RS 및 collection ..이므로 productList.get (0)을 호출 할 수 없으면 어떻게됩니까? (OP 질문에 따라)
Denham Coote

40

"첫 번째"항목 Collection은 .. 단순히 컬렉션이기 때문에 없습니다.

Java doc의 Collection.iterator () 메소드에서 :

요소가 반환되는 순서에 대한 보장은 없습니다 ...

그래서 당신은 할 수 없습니다.

List 와 같은 다른 인터페이스 를 사용 하는 경우 다음을 수행 할 수 있습니다.

String first = strs.get(0);

그러나 컬렉션에서 직접 이것은 불가능합니다.


11
나는 생각하지 않습니다 get(int n)에 대해 정의Collection
닉 하이너

2
네 말이 맞아 요. 답변을 업데이트했습니다. 당신은 할 수 없습니다! (컬렉션이 보증을 제공 할 수 있습니다 일부 기저의 클래스에 의해 구현되지 않는 한)
OscarRyz

GET은 Collection 인터페이스에없는
앤디 Gherna

21
오스카, 당신이 사건을 과장하고 있다고 생각합니다 Collection의 첫 번째 요소는 HashSet과 같은 몇 가지 경우에 임의적이지만 .iterator (). next ()입니다. 또한의 안정적인 내가 본 모든 수집 구현. (관련 : 설정이 순서를 보장하지 않는 동안, HashSet의 제외 JDK에서 설정의 모든 단일 하위 유형은 않습니다.)
케빈 Bourrillion

3
그럴 수도 있지만 컬렉션에 새 요소를 추가 할 때 해당 요소가 첫 번째 요소인지 마지막 요소인지 또는 중간에 삽입되는지 인터페이스에 의해 알 수 없습니다. 정확한 결과를 얻으려면 다른 인터페이스를 사용해야합니다. 그러나 아마도 Rosarch에 필요한 것은 무엇이든 관계없이 첫 번째 요소입니다. 밑받침 모음을 아는 것이 도움이 될 수 있지만 변경하지 못하게합니다.
OscarRyz

4

귀하의 컬렉션이 목록과 같은 것처럼 보이기 때문에 다음과 같이 제안합니다.

List<String> myList = new ArrayList<String>();
...
String first = myList.get(0);

2

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);
}

2
@Vitalii Fedorenko의 답변 stackoverflow.com/a/18165855/1562662 가 더 좋습니다.
Chacko Mathew

2

Guava는을 제공 onlyElement Collector하지만 컬렉션에 정확히 하나의 요소가있는 경우에만 사용하십시오.

Collection<String> stringCollection = ...;
String string = collection.stream().collect(MoreCollectors.onlyElement())

얼마나 많은 요소가 있는지 잘 모르는 경우을 사용하십시오 findFirst.

Optional<String> optionalString = collection.stream().findFirst();

1

캐스팅을 할 수 있습니다. 예를 들어,이 정의를 가진 하나의 메소드가 존재하면이 메소드가 List를 리턴한다는 것을 알고 있습니다.

Collection<String> getStrings();

그리고 그것을 호출 한 후 첫 번째 요소가 필요합니다. 다음과 같이 할 수 있습니다 :

List<String> listString = (List) getStrings();
String firstElement = (listString.isEmpty() ? null : listString.get(0));

0

컬렉션이 대기열이라는 것을 알고 있으면 컬렉션을 대기열로 캐스팅하여 쉽게 가져올 수 있습니다.

주문을 얻는 데 사용할 수있는 몇 가지 구조가 있지만 주문해야합니다.


반복하고 싶지 않다면 컬렉션을 사용하지 마십시오. 다른 특정 인터페이스를 대신 사용하십시오.
Adeel Ansari

1
그래도 궁금합니다 ... 실제 기본 데이터가 SortedSet이라고 가정하면 순서는 의미가 있지만 컬렉션 뷰만 가지고 있습니다 (바쁘지 않은 이유 때문에). 컬렉션을 List, Queue 등으로 전송하고 get / poll / etc 등을 시도하면 재해가 발생합니까? 마찬가지로 기본 구조가 List 등인 경우도 마찬가지입니다.
Carl

@Cal-시도하지 않았지만 컬렉션을 원래와 다른 유형으로 캐스팅하면 오류가 발생하지만 시도하지 않았으므로 잘못되었을 수 있습니다.
James Black

0

arraylist linkedlist 또는 기타 set 구현 여부에 따라 사용한 구현에 따라 달라집니다.

그것이 설정되면 첫 번째 요소를 직접 얻을 수 있으며, 컬렉션을 통해 트릭 루프가 될 수 있고, 값 1의 변수를 만들고 그 루프를 중단 한 후 플래그 값이 1 일 때 값을 얻을 수 있습니다.

리스트의 구현 인 경우 인덱스 번호를 정의하면 쉽습니다.


0

기능적인 방법 :

public static <T> Optional<T> findFirst(List<T> result) {
    return Optional.ofNullable(result)
            .map(List::stream)
            .flatMap(Stream::findFirst);
}

위의 코드 스 니펫은 NullPointerException 및 IndexOutOfBoundsException에서 보존합니다.


1
선택한 사항이에 List<T>대해 작동해야하는 조건을 만족 Collection<String>시키지는 않지만 Collection<T>추가 변경 사항을 사용하여을 사용하여 수정할 수 있습니다 .map(Collection::stream).
11

-2

당신은 이것을 할 수 있습니다 :

String strz[] = strs.toArray(String[strs.size()]);
String theFirstOne = strz[0];

Collection에 대한 javadoc은 배열 요소의 다음과 같은 경고를 제공합니다.

이 컬렉션이 요소가 iterator에 의해 리턴되는 순서를 보증하는 경우,이 메소드는 요소를 동일한 순서로 리턴해야합니다.


2
반복자를 만드는 것보다 훨씬 비싼 새로운 String 배열이 만들어집니다.
Jim Ferrans 2009

예, 게시 한 후에 생각했습니다. 사용 된 방법에 관계없이 순서는 Collection의 기본 구현에 따라 다릅니다. "첫 번째"는 상대 용어가됩니다. 그러나 iterator () 방법은 대부분의 경우 더 좋습니다.
Andy Gherna 2009

2
이것이 내가 가지고 있고 못생긴 것을 발견했기 때문에 여기에 왔습니다.
haansn08
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.