代码之家  ›  专栏  ›  技术社区  ›  kozmo

IdentitySet/IdentityHashSet(使用IdentityHashMap)

  •  15
  • kozmo  · 技术社区  · 7 年前

    我知道 IdentityHashMap ,但我需要习惯 "IdentitySet" (使用 equals o1 == o2 ). 我要用它来听“提取器”的可观察列表( JavaFX ):

     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());
                }
            }
        });
    

    人员类别:

    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()};
    }
    

    我需要重写 等于 hashCode 来解决我的其他问题。

    Person p = new Person("a",1);
    Set<Object> persons = new HashSet<>();
    persons.add(p);
    p.setD(999);
    persons.add(p);
    System.out.println(persons.size());  // size = 2;
    
    persons.remove(p);
    System.out.println(persons.size());  // size = 1;
    
    2 回复  |  直到 4 年前
        1
  •  26
  •   kozmo    4 年前

    从地图创建集合

    谢谢, @鲍里斯蜘蛛

    Collections.newSetFromMap(...) ,返回 Set 由指定的映射支持(在我的示例中为- IdentityHashMap ):

    // get IdentytitySet wich wrap IdentityHashMap
    Set<Person> persons = Collections.newSetFromMap(new IdentityHashMap<>()) 
    
    // test 
    Person p  = new Person("a",1);
    Person p2 = new Person("a",1);
    persons.add(p);
    persons.add(p2);
    System.out.println(persons.toString());
    

    标准装置 (漂亮的印花):

    [
      Person{
        s=StringProperty [value: a],
        d=DoubleProperty [value:1.0]
      }, 
      Person{
        s=StringProperty [value: a], 
        d=DoubleProperty [value: 1.0]
      }
    ]
    
    p.setD(999);
    persons.add(p);
    System.out.println(persons.toString());
    

    标准装置 (漂亮的印花):

    [
      Person{
        s=StringProperty [value: a],
        d=DoubleProperty [value: 999.0]
      }, 
      Person{
        s=StringProperty [value: a], 
        d=DoubleProperty [value: 1.0]
      }
    ]
    
    persons.remove(p)
    System.out.println(persons.toString());
    

    标准装置 (漂亮的印花):

    [
      Person{
        s=StringProperty [value: a], 
        d=DoubleProperty [value: 1.0]
      }
    ]