2013-02-05 2 views
3

나는 그들의 평등가 키 주위에 정의하지만, 다른 분야는 내가 '갱신'필요 그래서 때 ... 다를 수 있습니다 요소 Set, 이것은 내가 무엇을 시도했다입니다 있습니다스칼라에서 변경 불가능한 세트의 불변 요소를 "업데이트"하는 방법은 무엇입니까?

object sandbox { 

    case class K(val id: Int, val message: String) { 
    override def equals(that: Any) = that match { 
     case K(this.id, _) => true 
     case _ => false 
    } 
    override def hashCode = this.id 
    override def toString = "(" + id + "," + message + ")" 
    } 

    val s = Set(K(1, "a"), K(2, "b"))    //> s : scala.collection.immutable.Set[test.sandbox.K] = Set((1,a), (2,b)) 
    val updatedElem = K(1, "c")      //> updatedElem : test.sandbox.K = (1,c) 

    s + updatedElem         //> res0: scala.collection.immutable.Set[test.sandbox.K] = Set((1,a), (2,b)) 

    Set(updatedElem) | s       //> res1: scala.collection.immutable.Set[test.sandbox.K] = Set((1,c), (2,b)) 
    } 

이미있는 요소를 추가하면 집합이 변경되지 않고 먼저 제거되고 업데이트를 다시 추가하면 하위 최적으로 보입니다.

union 메서드는 왼쪽에있는 요소 집합을 유지하지만 그 동작은 문서화되지 않습니다. 그래서 나는 그것에 의지해서는 안됩니다.

이제 내가 놓친 부분이 더 명백합니까? 실제 동작에 의존해야합니까? (변경된 경우를 대비해 테스트를 작성해야합니까?) 아니면 두 단계로 업데이트해야합니까?

+0

이 세트는 'id'에만 의존하는 해시 코드를 사용합니다. 이것은'K (1, "a") == K (1, "c")'를 의미하고 추가하지 않는 (예외가없는) 설정을 설명합니다. 다른 메시지를 고려하는 해시를 시도하십시오. – korefn

+0

그러면 이전의 것보다 두 개의 오브젝트가 교체 될 것입니다. – fortran

답변

5

필자의 견해로는 실제로 모델링에서 개념의 문제입니다. 요점은 동등한 객체가 실제로 동등해야한다는 것입니다. 그렇지 않으면 다른 구조를 고려하는 것이 좋습니다. 예를 들어 idmessage (또는 id ~ K(id,message))으로 매핑하는 Map을 사용해 보시기 바랍니다. 컨셉이 더 깨끗해진 것 같습니다. .updated(1,"c")을 사용하면 컨셉을 업데이트 할 수 있습니다.

+0

제가 생각했던 또 다른 옵션은 사실입니다. 하지만 대부분의 경우 키 (일부 필드가 더 있음)를 포함하여 전체 구조에 액세스해야한다고 생각하므로 세트가 더 편리 할 것이라고 생각했습니다. – fortran

+0

@fortran 빌드하는 세트의 유스 케이스를 표시 할 수 있습니까? 세트를 만들고 수정하는 방법이 분명하다고 생각하지만 어떻게 사용하는지 알 수 없습니다. 질문에 해당 정보를 제공 할 수 있다면 사람들이 더 많은 도움을 줄 수 있습니다. – Kane

+0

나는 아직 하나도 가지고 있지 않다. 단지 느낌 일 뿐이다.^_^그것은 게임을위한 것이며, 현재 점수, 손에있는 토큰 등을 저장하는'Player' 구조체이다. – fortran

관련 문제