2015-01-26 5 views
3

두 개의 문자열 속성이 포함 된 개체 목록이 있습니다.guava - 반복문 반복 반복 방지

public class A { 
    public String a; 
    public String b; 
} 

나는 두 Sets 재산 a을 포함하는 하나 하나 b 검색하려는.

순진 접근 방법은 무엇인가 긴이 라인이다 : 나는이 방법으로 결국 구아바의 기능적인 방법으로 일을하려고

List<A> list = .... 
Set<String> listofa = new HashSet<>(); 
Set<String> listofb = new HashSet<>(); 
for (A item : list) { 
    if (item.a != null) 
     listofa.add(item.a); 
    if (item.b != null) 
     listofb.add(item.b); 

} 

: 나는 두 번 반복 할 것

Function<String,A> getAFromList = new Function<>() { 
    @Nullable 
    @Override 
    public String apply(@Nullable A input) { 
     return input.a; 
    } 
}; 

Function<String,A> getBFromList = Function<>() { 
    @Nullable 
    @Override 
    public String apply(@Nullable A input) { 
     return input.b; 
    } 
}; 

FluentIterable<A> iterables = FluentIterable.from(list); 

Set<String> listofAs = ImmutableSet.copyOf(iterables.transform(getAFromList).filter(Predicates.notNull())); 

Set<String> listofBs = ImmutableSet.copyOf(iterables.transform(getBFromList).filter(Predicates.notNull())); 

그러나이 방법 목록에.

두 번 또는 여러 번 반복하는 것을 피하는 방법이 있습니까?

일반적으로 (guava/java뿐만 아니라) 일반적인 사용 방법으로 이러한 유스 케이스를 어떻게 해결할 수 있습니까?

답변

1

먼저 최적화를 수행 중이지만 성능이 중요한 경우 구아바 (즉, 첫 번째 방법)를 통해 일반적인 Java 메소드를 사용하십시오. here을 참조하십시오.

나는 두 가지 결과를 원하기 때문에 어떤 시점에서는 두 세트를 반복하지 않아야하지만 (순수한 함수가 아니기 때문에 실제로는 fp 방식이 아님)). 반복하면 중간 구조에 한번 반복 할 것입니다 최적화를 필요로 할만큼 비싼 그러나 경우

:

a_b_pairs = transformToJustAB(input) //single expensive iteration 
list_of_a = transformA(a_b_pairs) //multiple cheaper iterations 
list_of_b = transformB(a_b_pairs) 
1

그래서 간단한 대답은 두 번 반복해야한다는 것입니다. 그것에 대해 생각 해봐. ListN 개의 요소가있는 경우 에 N 삽입을 삽입하고 두 번째 SetN 삽입을 삽입해야합니다. 기능적으로 또는 다른 방법으로 변환 (추출) 또는 삽입 여부에 관계없이 N을 두 번 반복해야합니다.

두 개로 나간다면 Lists은보기를 생성하고 필요에 따라 반복 할 수 있기 때문에 다릅니다.

+0

음. 나는 따라갈 수 있는지 잘 모르겠다. 'Lists '를 사용할 때 이것이 어떻게 다른가요? 나는 여전히 초기 목록을 두 번 반복해야한다. 느리게 소비 된보기 만있는 경우에도이 두 목록의 항목에 액세스하면 Sets와 동일한 방식으로 목록을 두 번 반복해야합니다. 또는 나는 무엇인가 놓치고 있냐? –

+0

아니요, 맞습니다. 뷰를 통한 초기화는 O (1)이지만 O (N)에있는 요소에 반복적으로 액세스하면 초기화됩니다. 이 전략은 항상 하나 또는 두 컬렉션을 반복하지 않는 경우에만 잘 작동합니다. –

1

당신이 달성하고자하는 것은 술어를 사용하여 모음을 분할하거나 분할하는 것입니다.

구아바에서는 Multimap.index을 사용할 수 있습니다. 관련 질문 및 답변 here을 참조하십시오.

Multimaps.index 하나의 반복 처리에 의해 해결 될 수
1

:

Function<A, String> filterAB = new Function<A, String>() { 
     @Override 
     public String apply(A input) { 

      if (input.a != null) { 
       return "a"; 
      } 
      if (input.b != null) { 
       return "b"; 
      } 
      return "empty"; 
     } 
    }; 

    ImmutableListMultimap<String, A> partitionedMap = Multimaps.index(list, filterAB); 

출력을위한 세 개의 항목이 구아바 Multimap됩니다

  1. A-NOT- "모두와 불변의 목록 null "오브젝트를 키"a "아래에 배치합니다.
  2. 키 "b"아래의 모든 "b-not-null"개체가있는 불변 목록.
  3. 그리고 a와 b가 모두 "empty"키 아래에서 null 인 객체를 사용하는 불변의 목록 일 수 있습니다.