2010-02-01 4 views
6

Java에서 콜렉션을 반환하는 가장 좋은 방법은 무엇입니까?java : 콜렉션을 반환합니다.

발신자가 추가 할 컬렉션을 제공해야합니까? 아니면 상품의 List<> 또는 Set<>을 돌려 주시겠습니까? 아니면 둘다?

public class Item { ... } 

public class SomeOtherClass 
{ 
    private List<Item> myItems; 

    public List<Item> getItems() 
    { 
    return Collections.unmodifiableList(this.myItems); 
    } 
    public void collectItems(Collection<? super Item> target) 
    { 
    target.addAll(myItems); 
    } 
} 

참고 : 위의 예는 즉시 반환 할 수있는 목록의 전 존재를 가정합니다. 그러한 목록이 이전에 존재하지 않았고 호출자가 getItems() 또는 collectItems()를 호출 할 때 생성 되어야만하는 경우에도 적절한 대답에 관심이 있습니다. (Mykola에서 제기 한 포인트를 기반으로 collectItems의 이름을 변경했습니다.)

+0

+1은 Collections.unmodifiableList를 표시합니다. 내가 뭘 찾고 있었는지. – Adam

답변

6

나는 단지 List<Item> getItems() 방법을 선호합니다. 발신자가 myCollection.addAll(foo.getItems()) 성과를 수행하는 것보다 void getItems(Collection<? super Item> target)에는 실질적인 이점이 없습니다. Collections.unmodifiableXYZ은 컬렉션의 전체 복사본이 아닌 래퍼 만 생성하므로 래퍼가 즉시 사용되고 폐기되는 경우 절대로 첫 번째 세대에서 벗어나지 않으며 적은 오버 헤드로 신속하게 수집됩니다.

항목 컬렉션이 항상 실현되는 경우가 아니라면 얼마나 많은 항목이 있는지 알지 못할 때 getItems가 Iterable<Item>을 반환하는 것을 고려할 수 있습니다. 항목의 수를 알고 반복자를 쓸 수 있다면 AbstractCollection의 맞춤 하위 클래스를 작성하고이를 반환하는 것이 쉽습니다.

+1

반복자를 언급하는 데 +1 –

12

return을 통해 함수를 반환하는 것이 더 좋을 때 (성능상의 문제가없는 한) 더 좋습니다. 그런 식으로 무슨 일이 벌어지고 있는지 분명히합니다.

두 번째 옵션 (채우기 클라이언트 컬렉션)을 선택하는 경우 모호한 코드를 피하기 위해 getItems에서 fillWithItems과 같은 기능으로 이름을 바꾸는 것이 좋습니다.

또한 JavaBeans 및 해당 규칙을 잊지 마십시오.

+0

+1은 이름 바꾸기를 제안합니다. –

0

컬렉션을 반환해야합니다. in/out 매개 변수를 사용하는 것보다 Java에서 더 일반적인 방법입니다. 나는 큰 컬렉션을 반환하기위한 성능 저하가있을 어떤 이유도 보지 않으며 더 깨끗한 코드가 될 것입니다.

+2

벌칙은 반환하는 컬렉션을 변경할 수 없도록하는 것입니다. –

+0

그래서 컬렉션의 복사본이나 복제본을 반환하십시오. 컬렉션을 사용자가 만든 복사본으로 복사하는 것보다 페널티가 적습니다. – Casey

0

Java가 작동하는 경우 일반적으로 반환 버전이 필요합니다.

그러나 어떤 유형의 콜렉션을 제어 할 필요가 있다면 작성한 버전을 인수로 전달할 수 있습니다.

일반적으로 어떤 유형의 콜렉션이 생성되는지 신경 쓰지 않아도되므로 일반적으로 리턴 버전을 사용해야합니다. 그런데 unmodifiableList를 잘 사용합니다.

0

참고 : 집합을 반환하고 목록을 반환하면 다른 의미가 있습니다.

세트에는 중복이없고 명시된 순서가 없습니다. 집합에 요소를 추가하면 요소의 순서가 달라질 수 있습니다.

목록에는 중복을 포함 할 수 있으며 요소를 추가해도 목록의 전체 순서는 변경되지 않습니다.

public List<Item> getItems() 
{ 
    return Collections.unmodifiableList(this.myItems); 
} 

나는 후자의 형태가 어떤 도움이 될 것입니다 상황을 생각할 수 없다 :

당신이 목록을 반환하는 방법에 관해서는, 나는 첫 번째 양식을 사용합니다. 목록은 공간을 사전 할당 할 수있는 배열과 다릅니다. 따라서 목록을 전달하면 성능이 저하되지 않습니다.

+0

여러 컬렉션을 모으고 각각에 10,000 개의 항목을 포함 할 수 있으면 대상 컬렉션을 대신 전달하려고합니다. 또는 컬렉션의 유형이 중요 할 경우 (목록 대 집합) 큰 수의 항목이있는 경우. –

0

새로운 컬렉션을 만드는 것보다 기존 컬렉션을 채우기 위해 생각할 수있는 유일한 이유는 컬렉션의 개체 유형에 문제가있을 때입니다. 자바 라이브러리의 toArray (Object [] a) 함수와 마찬가지로 프로그램이 컴파일 타임에 배열 요소의 적절한 유형을 알 수 없으므로 반환 할 수 없습니다. String []. 그래서 그들은 대신 적절한 타입의 요소를 가진 호출자 패스를 가지며, 그것들을 채 웁니다.

반환 할 개체 유형을 정확히 알고있는 시간의 90 %이므로 그냥 할 수 있습니다.

0

서명을 변경하여 Collection 또는 Iterable을 반환 할 수 있습니다. Iterable을 반환하는 경우 클라이언트가 List에 캐스트 (및 수정) 할 가능성이 없도록 myItems 대신 직접 새로운 Iterable (myItems.iterator())을 반환 할 수 있습니다. 목록을 수정하지 않으려면 Iterator를 반환하는 것도 고려해보십시오. 그러나 Iterable은 for-each 루프에서 직접 사용할 수 있으므로 더 좋습니다.

Iterable을 반환하면 의도를 분명히하고 위의 예에서 수정하지 못하게합니다. 유일한 의미는 임의 액세스를 잃어 버렸기 때문에 필요에 따라 문제가되지 않을 수도 있다는 것입니다.

+0

Iterable이 인터페이스라는 것을 감안할 때,'newIterable (myItems.iterator())'는 합법적이지 않다; 다른 의미가 있니? –

+0

예, 당신은 그것을 구현하는 새로운 익명 클래스 (또는 기본 반복 가능)를 반환해야 할 것입니다. – GreenieMeanie

관련 문제