IdentitySet / IdentityHashSet(使用IdentityHashMap)

koz*_*zmo 4 java set identity-map observable javafx-8

我知道IdentityHashMap,但是我需要使用“ identitySet ”之类的东西(它使用等于-> o1 == o2)。当我用“ extractor”(JavaFX)收听Observable列表时,我将使用一个:

 List<Person> deleteList = new ArrayList<>();
 List<Person> addList = new ArrayList<>();

 ObservableList<Person> list = FXCollections.observableArrayList(Person.extractor());
    list.add(new Person("a",1));
    list.add(new Person("b",2));
    list.add(new Person("c",3));

    list.addListener((ListChangeListener<Person>) observable -> {
        if(observable.next()) {
            if (observable.wasAdded()) {
                addList.addAll(observable.getAddedSubList());
            }
            if (observable.wasUpdated()) {
                deleteList.add(list.get(observable.getFrom()));
            }
            if (observable.wasRemoved()) {
                deleteList.addAll(observable.getRemoved());
            }
        }
    });
Run Code Online (Sandbox Code Playgroud)

人类:

public class Person {
private final StringProperty s;
private final DoubleProperty d;

//Getters and Setters
// ...

@Override
public int hashCode() {
    int result = s != null ? s.getValue().hashCode() : 0;
    result = 21 * result + (d != null ? Double.hashCode(d.getValue()) : 0);
    return result;
}

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    Person person = (Person) o;
    if (!s.getValue().equals(person.s.getValue())) return false;
    return d.getValue().equals(person.d.getValue());
}


/**
 *Extractor to observe changes in "Property" fields.
 * @return extractor
 */
public static Callback<Person, Observable[]> extractor() {
    return (Person p) -> new Observable[]{p.sProperty(), p.dProperty()};
}
Run Code Online (Sandbox Code Playgroud)

我需要重写equals / hashCode来解决其他问题。

    Person p = new Person("a",1);
    Set<Object> set = new HashSet<>();
    set.add(p);
    p.setD(9999);
    set.add(p);
    System.out.println(set.size());  // size = 2;
Run Code Online (Sandbox Code Playgroud)

koz*_*zmo 9

thx,@BoristheSpider => get Set,它包装了一个IdentityHashMap,使用Collections.newSetFromMap()

// get IdentytitySet wich wrap IdentityHashMap
Set<Person> set = Collections.newSetFromMap( new IdentityHashMap<>() ) 
//test 
Person p  = new Person("a",1);
Person p2 = new Person("a",1);
set.add(p);
set.add(p2);
p.setD(999999999);
set.add(p);//add Person with changed "d" to 999999999
System.out.println(set.toString());
Run Code Online (Sandbox Code Playgroud)

打印:

[Person {s = StringProperty [值:a],d = DoubleProperty [值:9.99999999E8]},Person {s = StringProperty [值:a],d = DoubleProperty [值:1.0]}]


kic*_*hik 8

您可以使用番石榴的Sets.newIdentityHashSet().

https://github.com/google/guava/wiki/CollectionUtilitiesExplained

  • @BoristheSpider Guavas 版本更容易阅读(imo)。`Collections` 版本也不难,但不那么明显。Guava 准确地说出你得到什么(一个身份集),你不必介意这是如何构建的。Java 版本在这方面更加冗长。对于有经验的程序员来说,我当然没有任何问题,但代码可能不仅适用于有经验的程序员。 (4认同)
  • Guava 自己推荐使用 Java 类而不是它们自己的类,如果存在这样的选项。我认为`Collections.newSetFromMap` 是一个更好的选择。 (3认同)
  • @BoristheSpider Guava 无论如何都只是使用该方法,它只是一个外观。 (2认同)