2013-05-01 2 views
0

삽입 순서를 유지하는 것 외에도 고유 한 요소 집합을 저장하기 위해 LinkedHashSet을 사용하는 기존 기능이 있습니다.LinkedHashSet에서 요소를 검색하는 가장 효율적인 대안은 무엇입니까?

LinkedHashSet에 이미있는 특정 요소를 검색해야하는 새로운 요구 사항이 있습니다. 즉 요소 추가를 시도 할 때 메서드는 요소가 이미 있는지 확인하고 기존 요소를 반환해야합니다. LinkedHashSet에는 최대 10000 개의 요소가있을 수 있습니다. 이를 달성하기

현재 방법은 효율적인 대안 데이터 구조 방법이있는 LinkedHashSet의

Class CustomObject { 
    String id; 
    String name; 

    CustomObject (String id, String name) { 
    this.id = id; 
    this.name = name; 
    } 

    LinkedHashMap<String, LinkedHashSet<CustomObject>> parentRecord = new LinkedHashMap<String, LinkedHashSet<CustomObject>>(4); 
    . 
    . 
    . 
    public CustomObject addCustomObject (CustomObject customObject) 
    //Assume the following child node not to be null 
     Set<CustomObject> child = parentRecord.get("customObjectName"); 

     if (child.contains(customObject)) {   
      Iterator<CustomObject> it = child.iterator();  
      while (it.hasNext()) { 
       CustomObject node = it.next();   
        if (node.getId().equals(customObject.getId())) { 
         return node; 
        } 
      } 
     } 

     child.add(customObject); 

     return customObject; 
    } 

} 

에 반복자를 사용하는 것입니다 그 것이다

  1. 스토어 고유 값

  2. 반환 추가하려고 할 때 이미 존재하는 특정 요소

  3. customObject 자체 따라서 반복기로서 갔다 든 그다지 일 sense.However을 만든다 복귀 신청서 (가능한 경우) customObject 집합에 이미 첨가되어 있기 때문에

을 보존 노드 안에 노드를 만들고 있습니다. 반환 된 customObject는 자식 노드를 가질 수 있습니다.

+0

의미 상'Set.contains (object)'가 true를 반환하면 이미 저장된 요소 (또는 이와 동등한 인스턴스) - contains()!의 매개 변수! 따라서 Set에서 특정 요소를 get()하는 것은 의미가 없습니다. Map은 불변의 식별자를 엔티티의 특정 상태 나 인스턴스에 매핑 할 수 있기 때문에 달성하고자하는 것에 더 적합합니다. – Pyranja

+1

(참고 : 위의 코드는 컴파일되지 않습니다 .' return child;'문이 잘못된 유형의 값을 반환합니다. 'return customObject;'여야합니다.) –

+0

잘 잡히고, 지금 코드를 수정했습니다 .-) – GBP

답변

2

LinkedHashSet<CustomObject> 대신 LinkedHashMap<CustomObject, CustomObject>을 사용하십시오.

(이 CustomObject.equalsCustomObject.hashcode 현재 "일치"방법을 사용하는 것이 가정 그렇지 않으면 외부 "심부름 군"과 제 3 자 대안을 사용하여 ....)

방법이된다 :

public CustomObject addCustomObject (CustomObject customObject) { 
    Map<CustomObject, Custom> child = parentRecord.get("customObjectName"); 

    res = child.get(customObject); 
    if (res == null) { 
     child.put(customObject, customObject); 
     return customObject; 
    } else { 
     return res; 
    } 
} 

모두 O(1)이어야합니다.

+0

덕분에 스티브가 내 요구 사항을 해결해 준 덕분에 – GBP

+0

에게 감사 할 것입니다. – GBP

0

그냥 으로 전화하십시오. 그것은 O (1)로 지정됩니다.

+0

LinkedHashSet에서 get() 메서드를 사용할 수 없습니다! – GBP

+0

Err, oops, 나는 contains()를 의미했다! – EJP

+0

실제로 존재하는지 확인하는 것이 아니라 실제 요소를 반환해야합니다 .-) – GBP

0

LinkedHashMapMap에 해당하는 LinkedHashSet입니다. 삽입 명령 통과를 제공하는 경우 키의 고유성을 보장하고 Map에 항목의 일정 조회를 제공합니다. 이것은 당신을 대신 할 수도 있습니다.

+0

가자. – GBP

+0

고마워. – GBP

0

나는 그 질문을 이해했다. LinkedHashSet 귀하의 요구 사항에 잘 작동합니다.

그러나 에 이 이미 구현되어 있다고 가정합니다. equals() and hashcode().그래서

:

스토어 고유 값

설정은 당신을 위해 그 기능이 있습니다.

반환 특정 요소에 문을 반환하지 않는 이상 단지

if (set.contains(obj)) "return" obj; 

은 "반환"을 수행하여 등호 및 해시 코드 방법

를 추가하려고 할 때 이미 존재하는 경우 메서드가 true를 포함하는 경우, 삽입 할 객체를 가져옵니다. 그것은 set의 obj와 같기 때문입니다. (집합을 반복하고 등가 객체를 가져올 필요가 없습니다.)

contains(obj)은 해시 테이블로 인해 O(1)을 사용합니다.

linkedhashSetlinkedList에 기초하므로, 삽입 순서는 보존 가능한 경우, 삽입 순서를 유지.

+0

추가되는 customObject가 이미 세트에 있으므로 customObject 자체를 반환하는 것이 좋습니다. 그러나 노드 내부에 노드를 작성하기 때문에 어떻게 든 작동하지 않습니다. 반환되는 customObject에는 자식 노드가있을 수 있습니다. 특이한 요구 사항. 하지만 당신의 대답은 유용했습니다! 캔트 투표까지, 나는 초보자입니다. – GBP

+0

@Giri, 자녀는 equals 메소드에서 검사해야합니다. 질문은 "당신은 어떻게 평등을 정의합니까?"입니다. – Kent

+0

'@Override public boolean equals (Object o) { if (this == o)가 true를 반환하면; \t if (o == null || getClass()! = o.getClass())는 false를 반환합니다. CustomObject that = (CustomObject) o; return! (id! = null?! id.equals (that.id) : that.id! = null); }' – GBP

관련 문제