2009-05-07 4 views
0

그래서, 나는 연속적인 BlockingQueue 큐에 3 개의 값을 전달해야하는 상황이있다 :HashMaps를 작성하는 대신에 "Pair"또는 n-size를리스트 콜렉션에 삽입하는 방법?

(SelectableChannel, ComponentSocketBasis, Integer). 

실제로 해시 맵핑 될 필요가 없으며 HashMap을 사용하는 것은 어리석은 일이다. 항상 각 항목에 대해 단 하나의 키가됩니다. 그들이 일종의 주문 세트에 있다면 그것은 괜찮을 것입니다. 그러나 알려진 대안이 없기 때문에 구현시 HashMap을 사용하고 난독 화 된 제네릭 구성을 만들었습니다.

private LinkedBlockingQueue<HashMap<HashMap<SelectableChannel, ComponentSocketBasis>, Integer>> deferredPollQueue = new LinkedBlockingQueue<HashMap<HashMap<SelectableChannel, ComponentSocketBasis>, Integer>>(); 

이것은 정말 우스운 것 같습니다. 나는 끔찍한 n00b이어야한다. 분명히 값을 검색하거나 낭비 할 때 키를 분해 할 필요가없는 더 좋은 방법이 있습니다 (이론적으로 - 실제로는 Java가 항상 부풀어 있습니다 :) 필요없는 쓸모없는 해시 계산에 알고리즘의 복잡성 왜냐하면 나는 1의 키 공간을 가지기 때문에 3 개의 참조를 관계형으로 매핑하기를 원하지는 않지만 그것들을 그룹화하기 만하기 때문입니다. 이 구현을 통해 나는 값을 끌어 내야 만한다.

while(deferredPollQueue.size() > 0) { 
    System.out.println("*** Draining new socket channel from queue"); 
    HashMap<HashMap<SelectableChannel, ComponentSocketBasis>, Integer> p = deferredPollQueue.take(); 

    SelectableChannel chan = null; 
    ComponentSocketBasis sock = null; 
    int ops = 0; 

    HashMap<SelectableChannel, ComponentSocketBasis> q = p.keySet().iterator().next(); 

    chan = q.keySet().iterator().next(); 
    sock = q.get(chan); 

    ops = p.get(q).intValue(); 

    SelectionKey k = chan.register(selector, ops); 

    if(!channelSupervisorMap.containsKey(k)) 
     channelSupervisorMap.put(k, sock); 
} 

나는 감정적 인 이유를 가진 모든 사람들이 아마 우스운 방법이라고 생각한다. 그래서 질문은 - 무엇이 옳은가? 방법? :) 어디서나 java.util.Pair 또는 java.util.Triplet의 증거를 찾을 수 없습니다.

정교회 방식 (TM)은이 트리플렛을 수용 할 목적으로 사용자 정의 클래스 또는 인터페이스를 수행하는 것이 겠지만 이러한 대규모 시스템에서의 작은 작업은 터무니없이 길고 불필요한 것 같습니다. , 다시 자바 자체입니다.

같은 토큰으로, 아마도 ArrayList 또는 Vector 또는 그 파생물에 값을 넣을 수 있습니다. 그러나 자바에서는 여기에서이 HashMap에서 벗어나는 것보다 좀 더 간결한 방법으로 어드레싱하지 않습니다. 알고리즘의 복잡성 문제를 해결할 수도 있지만.

Perl 토지로 돌아가서 배열 참조를 배열 내부의 값으로 사용하면됩니다.

push(@$big_queue_array, [$elem1, \%elem2, \@elem3]); 

Java에서 가장 좋은 점은 무엇입니까?

답변

5

일반 페어 또는 트리플 클래스를 만들지 않는 이유는 무엇입니까? 거의 모든 Java 5+ 프로젝트는 자신의 util 클래스에서 끝납니다!

+0

심각하게? 이것은 정결 한 것으로 간주됩니까? :) 죄송합니다, C와 펄 녀석 - 그냥 물건을 알아 내려고. –

+1

예, 일반 쌍은 http://en.wikipedia.org/wiki/Generics_in_Java에서 equals 및 hashcode를 재정의하는 것을 잊었지만 예제 중 하나입니다. – JeeBee

+0

코드에서 "private LinkedBlockingQueue > foo;"가됩니다. 그러나 세 멤버와 함께 구체적인 클래스를 만드는 데는 아무런 문제가 없으며 Pair/Triplet에서와 같이 "getFirst()"대신 "getSelectableChannel()"과 같은 정상적인 메서드 이름을 사용할 수 있습니다. – JeeBee

4

당신은 트리플렛을 보유하기위한 커스텀 클래스가 부풀어 오르고 불필요하다고 말할 수 있습니다.하지만 실제로는 그것을 수행하는 방법입니다. 이것이 객체 지향 모델링의 작동 방식입니다. 커스텀 클래스는 명백하고 읽기 쉽고, 일반적인 홀더 클래스보다 런타임 리소스를 더 이상 차지하지 않습니다.

+0

그것이 내가 의심하는 것이지만,하고 싶지 않았습니다. 죄송합니다, 초보자는 여기에 있습니다. TheDailyWTF 등에서 끝내고 싶지 않았습니다. 그런 점에서이 상황에서 이러한 값을 유지하는 데 필요한 사용자 지정 triplet 클래스를 만들어야한다고 생각합니까? 아니면 위의 주석으로 제안하고 Object 참조가있는 일반 쌍 및/또는 Triplet 클래스를 만드시겠습니까? –

+0

위의 반복 된 이유로 커스텀 클래스를 만들 것입니다. 가독성이 왕이다, 나의 친구. – skaffman

+0

이것은 궁극적으로 무의미한 미학적 인 종류의 논쟁 일지 모르지만 실제로는 3 요소 Triplet 제네릭이 읽기 쉽고 훨씬 간결한 것처럼 보입니다. –

2

Functional Javapairs, triplets을 가지고 있으며, 인해 임의 arity에 대한 HList라는 유형도있다 arity에 8까지 튜플.

LinkedBlockingQueue<P3<SelectableChannel, ComponentSocketBasis, Integer>> 

이 그냥 라이브러리, 그래서 클래스 패스에 항아리를 드롭하고 당신은 갈 수 있어요 : 그래서 당신의 유형이 될 것입니다.

2

개체가 어떤 위치에 있는지 알기 때문에 개체를 저장하기 위해 ArrayList를 사용할 수 있습니다. SelectableChannel 및 ComponentSocketBasis 멤버를 사용하여 새 클래스를 만드는 것이 좋습니다.

이러한 종류의 작업을 많이 수행하려는 경우 일반 페어 또는 튜플을 만들면 많은 시간을 절약 할 수 있지만이 장소 만 사용한다면, 새로운 클래스를 생성하면 코드를 훨씬 쉽게 읽을 수 있습니다.

코드에서 클래스 이름을 볼 때마다 그 코드가 무엇인지 정확하게 알 수 있지만 일반 합병을 볼 때 사용 된 내용을 이해하는 것이 더 어려울 수도 있습니다. 에 대한.

프로그래밍 시간과 가독성 간의 균형이 맞지 않습니다.