如何将ObservableList<Person>映射为ObservableList<String>(无需手动实现监听器)
无需手动实现ListChangeListener的映射方案
当然有,JavaFX 原生就提供了无需手动编写ListChangeListener的方式,实现ObservableList<Person>到ObservableList<String>的映射:
1. 只读映射:使用FXCollections.transform()
这个方法会生成一个与源列表绑定的只读ObservableList,自动同步源列表的结构变化(元素增删、排序等)。如果需要让映射列表随Person的name属性更新而变化,只需在创建源列表时指定要监听的属性:
// 创建源列表时,声明监听Person的name属性 ObservableList<Person> personList = FXCollections.observableArrayList(person -> new Observable[]{person.name}); // 生成映射列表,提取每个Person的name值 ObservableList<String> nameList = FXCollections.transform(personList, person -> person.name.get());
此时,无论是源列表添加/删除Person对象,还是某个Person的name属性更新,nameList都会自动同步变化。
2. 可写映射:结合Bindings.bindContent()(谨慎使用)
如果需要可写的映射列表,可以通过Bindings.bindContent()配合流转换实现单向同步,但这种方式每次源列表变化都会重新生成整个目标列表,性能不如前者,且双向同步需要额外处理避免数据不一致:
ObservableList<Person> personList = FXCollections.observableArrayList(person -> new Observable[]{person.name}); ObservableList<String> nameList = FXCollections.observableArrayList(); // 绑定源列表到目标列表,自动同步变化 Bindings.bindContent(nameList, Bindings.createObjectBinding( () -> personList.stream() .map(Person::name) .map(StringProperty::get) .collect(Collectors.toList()), personList ));
内容的提问来源于stack exchange,提问作者JHeut
相关产品推荐
相关产品推荐

