2012-02-27 3 views
1

구아바 API의 모든 기능을 계속 학습합니다. 이 작업을 수행하는 방법에 대한 제안 사항이 있는지 알아보기 위해이 항목을 촬영하려고했습니다. 현재 사진은 다음과 같습니다구아바 그룹화 키

123|”Whatever” : { Object A, ObjectB, ObjectC} 
456|”Something” : { Object A, ObjectB, ObjectC} 

명백한 * Multimap과는 다음과 같습니다 List <ObjectA>, List<ObjectB>, List<ObjectC>

ObjectA { 
    Integer attribute1; 
    String attribute2; 
    …. 
} 
ObjectB { 
    Integer attribute1; 
    String attribute2; 
    …. 
} 
ObjectC { 
    Integer attribute1; 
    String attribute2; 
    …. 
} 

내가 이렇게 이런 식으로 뭔가를 만드는 속성 1 및 속성 2에 의해 함께 3 개 목록 및 그룹 개체를 갖고 싶습니다 반환하지만이 과정을 구축하는 여러 솔루션을 가질 수 있습니다. 이 접근 방법에 대한 생각?

+2

각 속성 조합마다 정확히 하나의 항목이 목록에 있습니까? 또한 세 개의 "Object"클래스가 수퍼 클래스를 공유합니까? –

+0

이들은 수퍼 클래스를 공유 할 수도 있고하지 않을 수도 있으며 각 목록에 존재하지 않을 수도 있습니다. – JustinM

답변

2

attribute1과 attribute2의 조합을 나타 내기 위해 사용자 지정 쌍 클래스가있는 Multimaps.index()를 사용합니다. 당신과 같은 인터페이스가 있다면 코드가/더 많은 청소기 될 것이라고

/** 
* A "pair" class that contains an {@code attribute1} and an {@code attribute2}. Mainly used as a {@link Map} key. 
*/ 
@Immutable 
public class Attribute1AndAttribute2 { 

    @Nullable 
    private final Integer attribute1; 
    @Nullable 
    private final String attribute2; 

    public Attribute1AndAttribute2(@Nullable Integer attribute1, 
            @Nullable String attribute2) { 
     this.attribute1 = attribute1; 
     this.attribute2 = attribute2; 
    } 

    @Nullable 
    public Integer getAttribute1() { 
     return attribute1; 
    } 

    @Nullable 
    public String getAttribute2() { 
     return attribute2; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) { 
      return true; 
     } 
     if (obj instanceof Attribute1AndAttribute2) { 
      Attribute1AndAttribute2 that = (Attribute1AndAttribute2) obj; 
      return Objects.equal(this.attribute1, that.attribute1) 
        && Objects.equal(this.attribute2, that.attribute2); 
     } 
     return false; 
    } 

    @Override 
    public int hashCode() { 
     return Objects.hashCode(attribute1, attribute2); 
    } 

} 


/** 
* Static utility methods pertaining to {@link ObjectA}, {@link ObjectB}, and {@link ObjectC}'s {@code attribute1} and 
* {@code attribute2}. 
*/ 
public final class Attribute1AndAttribute2Utils { 
    private Attribute1AndAttribute2Utils() { /* prevents instantiation */ } 

    public static Multimap<Attribute1AndAttribute2, Object> groupedByAttribute1AndAttribute2(List<ObjectA> as, List<ObjectB> bs, List<ObjectC> cs) { 
     Iterable<Object> abcs = Iterables.concat(as, bs, cs); 
     return Multimaps.index(abcs, Attribute1AndAttribute2ForObjectFunction.INSTANCE); 
    } 

    // enum singleton pattern 
    private enum Attribute1AndAttribute2ForObjectFunction implements Function<Object, Attribute1AndAttribute2> { 
     INSTANCE; 

     @Override 
     public Attribute1AndAttribute2 apply(@Nullable Object object) { 
      if (object instanceof ObjectA) { 
       ObjectA objectA = (ObjectA) object; 
       return new Attribute1AndAttribute2(objectA.attribute1, objectA.attribute2); 
      } else if (object instanceof ObjectB) { 
       ObjectB objectB = (ObjectB) object; 
       return new Attribute1AndAttribute2(objectB.attribute1, objectB.attribute2); 
      } else if (object instanceof ObjectC) { 
       ObjectC objectC = (ObjectC) object; 
       return new Attribute1AndAttribute2(objectC.attribute1, objectC.attribute2); 
      } else { 
       throw new RuntimeException("Object must be ObjectA, ObjectB, or ObjectC, but was " + object); 
      } 
     } 
    } 

} 

참고 : 또한

public interface HasAttribute1AndAttribute2 { 
    Integer getAttribute1(); 
    String getAttribute2(); 
} 

는, 그 속성 1을 가정하고 속성 2는 널 (null) 일 수 있습니다. null이 아닌 경우 페어 클래스를 다음과 같이 변경하는 것이 좋습니다.

/** 
* A "pair" class that contains an {@code attribute1} and an {@code attribute2}. Mainly used as a {@link Map} key. 
*/ 
@Immutable 
public class Attribute1AndAttribute2 { 

    @Nonnull 
    private final Integer attribute1; 
    @Nonnull 
    private final String attribute2; 

    public Attribute1AndAttribute2(@Nonnull Integer attribute1, @Nonnull String attribute2) { 
     this.attribute1 = checkNotNull(attribute1); 
     this.attribute2 = checkNotNull(attribute2); 
    } 

    @Nonnull 
    public Integer getAttribute1() { 
     return attribute1; 
    } 

    @Nonnull 
    public String getAttribute2() { 
     return attribute2; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) { 
      return true; 
     } 
     if (obj instanceof Attribute1AndAttribute2) { 
      Attribute1AndAttribute2 that = (Attribute1AndAttribute2) obj; 
      return this.attribute1.equals(that.attribute1) 
        && this.attribute2.equals(that.attribute2); 
     } 
     return false; 
    } 

    @Override 
    public int hashCode() { 
     return Objects.hashCode(attribute1, attribute2); 
    } 
} 
+0

감사합니다. @Eneveu, 정적 인 경우 좋을 것 같습니다. 그것이 완전히 새로운 집합의 객체를 의미하고, 1 : M 속성이 될 수있는 다른 그룹 키를 기반으로한다면 좀 더 동적 인 것이 어떨까요? – JustinM

+0

나는 "다이나믹"이란 말을 이해하지 못합니다. 객체에 다른 속성이있는 경우 ("attribute3"및 "attribute4"라고합시다) "Attribute1AndAttribute2"클래스의 이름을 "MyKey"로 바꾸고 "attribute3"및 "attribute4"필드 (equals/hashCode 업데이트)를 추가하십시오. 당신의 물건은 어떻게 생겼을까요? –

+0

다이나믹 (Dynamic) - 1 : M 오브젝트와 1 : M 키 목록을 처리 할 수있는 유틸리티 메소드를 더 많이 사용합니다. 모든 객체가 attribute1 또는 attribute2를 가지는 것은 아닙니다. 말이 돼? – JustinM