2014-09-05 2 views
1

내가 진행중인 프로젝트에서 큰 데이터 세트에 다차원 피벗을 만들려고합니다. 나는 int들로 사용할 모든 키를, 그래서 기본적으로, 나는 그것이 거대한 얻을 수 있습니다, 나는이 N 차원 배열을 사용할 수 없습니다빠른 원시적 int 다중 키 맵?

(int1, int2, int3, .. intN) -> (Aggregate1, Aggregate2, ... , AggregateM)

의 집합을 반환하려면 아마 될 것입니다 부족한. 나는 Trove를 보았지만 Multi-key map이 없다. 아파치 공유는 다중 키 맵을 가지고 있지만, 이는 Objects을위한 것이다; 아마도 작동 할 것이지만, int이 자동 상자 화되어 Integers이되고, 그 반대의 경우도 마찬가지입니다.

누구나 원시 다중 키 맵 구현을 알고 있습니까? (객체에 매핑 된)

또는 다른 사람에게 좋은 힌트가 있습니까? 더 좋은 방법이 있습니까?

[편집] 삽입 시간이 덜 흥미로 우며,지도가 값을 검색하는 데 많이 사용되므로 조회시 성능이 필요합니다.

[편집 2] 모든 답변 주셔서 감사합니다. 내 구현 선택은 int []를 포함하는 사용자 정의 클래스이므로 불변이므로 hashcode은 생성시 계산할 수 있습니다.

private static class MultiIntKey 
{ 
    int[] ints; 

    private int hashCode; 

    MultiIntKey(int[] ints) 
    { 
     this.ints = ints; 
     this.hashCode = Arrays.hashCode(this.ints); 
    } 

    @Override 
    public int hashCode() 
    { 
     return this.hashCode; 
    } 

    @Override 
    public boolean equals(Object obj) 
    { 
     if (this == obj) 
     { 
      return true; 
     } 
     if (obj == null) 
     { 
      return false; 
     } 
     if (this.getClass() != obj.getClass()) 
     { 
      return false; 
     } 
     MultiIntKey other = (MultiIntKey) obj; 
     if (this.hashCode != other.hashCode) 
     { 
      return false; 
     } 
     if (!Arrays.equals(this.ints, other.ints)) 
     { 
      return false; 
     } 
     return true; 
    } 
} 
+1

'SparseArray'의 소스 코드를보고 다중 키를 사용하도록 수정할 수 있습니다. –

+0

"멀티 키"가 정확히 무엇을 의미합니까? – chrylis

+0

다중 키 : 하나의 키에 여러 항목이 결합되어 있습니다. 예를 들어 Apache Commons에는 CombinedKey가 'Objects'로 구성된 다중 키 맵이 있습니다. – RobAu

답변

4

아파치 공유에는 다중 키 맵이 있지만 이는 개체를위한 것입니다. 그건 아마 작동하지만, ints 자동으로 정수 및 그 반대로 얻을 것이다대로 덜 흥미로운 것 같습니다.

확실히, N 개체를 사용하는 것은 바람직하지 않습니다.

  • 키가 작 으면 int 또는 long으로 패킹 해보십시오.
  • 많이 반복하는 경우 trove4j를 사용하여 TIntObjectMap<TIntObjectMap<Value>>을 고려하십시오. 더 많은 중첩이 가능합니다.
  • 그렇지 않으면 간단히 모든 int를 캡슐화하는 간단한 개체를 만듭니다. 객체 오버 헤드는 수 바이트이지만, 이는 4*N과 비교하면 그렇게 나쁘지 않습니다. 맵 오버 헤드가 큰 오버 헤드가 될 수 있습니다 ...

지도가 변경되지 않으면 Guava의 ImmutableMap으로 이동하십시오. 구아바 Table을보세요. 2D 만 가능하지만 조금 저장하는 것이 좋습니다.


당신이 많이 최적화해야 확실 경우에만 일부를 기반으로 자신의 구현에 대한 생각, 제몫지도가 필요하지 않습니다 (당신은? 일부 벤치마킹 또는 프로파일 링을 수행 한) int[], 여기서 모든 키를 순서대로 배치합니다. 아마 당신은 가치가 없다는 것을 알게 될 것입니다.하지만 좋은 운동입니다. : D

-1

가장 쉬운 방법이해야 할 일 :

  • 모든 키를 포함하는 사용자 정의 클래스를 만들기 검색을위한 JSON/하네스 MongoDB를에

    1. 변환을 &가 equals 메소드의 해시 코드를 정의하고,지도를 사용
  • +3

    1. 룩업에서 정수의 각 집합을'String'으로 변환하면 속도가 느려진다. 몹시 끔찍하게, 나는 생각한다. – RobAu

    +0

    2. 솔루션의 일부일 수도 있지만 많은 개체를 만들지 않기를 원합니다. – RobAu

    +2

    @RobAu 매우 좋습니다. 사용자 정의 솔루션이 필요할 수도 있습니다. 한 가지 조언을드립니다. 두 제안이 모두 비효율적이라고 지적했습니다. 이는 유효합니다. 그러나 코드를 실행하기 전에 코드를 최적화하고 병목 현상이 실제로 어디에서 발생했는지 파악하는 것은 어렵습니다. – ControlAltDel

    1

    각각의 키가 될 수 있습니다

    IntBuffer.wrap(new int[] { value1, value2, value3 }) 
    

    IntBuffer의 hashCode, equals 및 compareTo 메서드는 해당 내용에 따라 달라 지므로 HashMap 또는 TreeMap 키로 작동합니다. 기술적으로는 이러한 메서드는 버퍼의 나머지 요소에 따라 달라 지므로 만드는 IntBuffers의 위치 나 제한을 절대 변경하지 마십시오.

    한 가지주의 할 점은 IntBuffer.wrap(new int[] { 1, 2 })과 같지 않습니다. IntBuffer.wrap(new int[] { 2, 1 }).

    +0

    아, 재미있는 생각 :). 그것은 여전히 ​​객체 생성이지만, 나는 그것이 없이는 할 수 없다고 생각합니다. 내 int의 순서는 고정되어 있습니다 (배열에 있어야 함). – RobAu

    +1

    @RobAu 단순함으로는 좋지만 메모리 오버 헤드가 큽니다.두 개의 객체, 즉 int []와 HeapIntBuffer를 생성합니다.이 객체 자체에는 두 개의 필드가 있습니다. 타이핑을 저장하려면 [Lombok] (http://projectlombok.org)의'@Value {int value1; int value2;}'그리고 끝났습니다 (모든 것은 불변이고 getters, 생성자, equals 및 hashCode를 얻습니다). – maaartinus

    0

    (INT1, INT2, INT3 .. INTN) == (INT1 + ""INT2 + ""..)와 스트링 키. 인턴() 동일한 테이블

    그래서 모든 키 intern을 통해 새 개체가 거의 없습니다. 키를 동적으로 원할 때마다 인턴을 사용해야합니다.

    +0

    문자열 옵션이 작동하지만 int1 * 10 등의 옵션은 분명히 작동하지 않습니다. (1, 2)와 (30, 1)을 생각해 봅시다 - 이것들은 동일한 키를 생성 할 것입니다 - 50. –

    +0

    저는 동의합니다. 중간에 문자열을 타이핑하기 시작한 다음 첫 번째 부분을 삭제하는 것을 잊었습니다. – tgkprog