java - 添加元素时集合的属性更改事件旧值

标签 java javabeans propertychangelistener propertychangesupport

我有一个 Java bean,它有一个带有 getter 的集合属性,并且还提供了该集合的添加方法。

因此,当使用 add 方法修改集合时,我必须触发 PropertyChangeEventPropertyChangeEvent 有一个旧值和一个新值。

你如何处理旧值?

为了让事情变得简单,我将在这里使用 String 的集合。例如

public class MyBean {

    private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
    private Set<String> names = new HashSet();

    // Delegate methods to add/remove PropertyChangeListeners are omitted here

    /**
     * The collection property
     */
    public Collection<String> getNames() {
        return Collections.unmodifiableCollection(names);
    }

    public void addName(String name){
          if(names.add(name)){
             Collection<String> oldValue = ????; // How do you get the old value
             Collection<String> newValue = Collections.unmodifiableCollection(names);
             pcs.firePropertyChange("names", oldValue, newValue);
          }
      }
}

获取旧值的一种方法可能是在添加之前创建副本

public void addName(String name) {
    Collection<String> oldValue = new HashSet<>(names);
    if (names.add(name)) {
        Collection<String> newValue = Collections.unmodifiableCollection(names);
        pcs.firePropertyChange("names", oldValue, newValue);
    }
}

但在很多情况下,旧值可能会被无偿复制。

所以另一个想法是不使用 add 方法,而是使用 contains before

public void addName(String name) {
    if (names.contains(name)) {
        return;
    }

    Collection<String> oldValue = new HashSet<>(names);
    names.add(name);
    Collection<String> newValue = Collections.unmodifiableCollection(names);

    pcs.firePropertyChange("names", oldValue, newValue);
}

这适用于Set。但是,当 names 集合是 ArrayList 时,它将不起作用,因为 ArrayList 可以包含相同对象的多个实例。因此 contains 将返回 true,但 add 也会返回 true

在多线程环境中,首先通过 contains 检查然后添加也可能是一个问题,因为与此同时另一个线程可能添加了相同的对象。但我不想在这里介绍这种复杂性。我只是想为单线程环境找到一个好的设计,通常是在 UI 中使用此类 bean(Event-Dispatch-Thread)时。

在这种情况下你如何处理旧值?

最佳答案

您可以使用Map.putIfAbsent实现,并且键和值相同。

如果该键存在,则将返回之前的(旧)值,并用于触发 firePropertyChange。 这在多线程环境中效果很好,只有一个线程能够添加新条目。

关于java - 添加元素时集合的属性更改事件旧值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46511060/

相关文章:

javascript - 使用 MySQL Community Server 和 jQuery AJAX 的 RESTful Web 服务

jsp - jsp中 session 管理的java bean和session的区别

Java EE并发问题

java - 选择在 Spring 中引用哪个 bean?

java - 如何在 addPropertyChangeListener 中打开 JCombobox

java - 如何从线程触发 PropertyChange 事件?

java - 类对象比较 - equals 方法输出错误

java - gson.fromJson 返回空值

Applet 中显示 Java Awt 组件但不显示 Swing 组件

java - 为什么在 JFrame 打开时会触发此属性更改事件?