ObservableList returns 匹配的子列表

ObservableList returns sublist that matches

我不太确定如何表达这个问题,请耐心等待。

我有一个 ObservableList 的用户定义对象,有几个 getter 方法,例如:

public String getName() { return this.name; }
public int getId() { return this.id; }

我想做的是能够通过搜索子字符串从我的主要可观察列表中 return 一个子列表。因此,如果我有一些 类 包含这些名称:

car
carrol
castro
bret

我将如何获取所有对象的 ObservableList<MyClass>,其中名称参数由 getName() 检索,包含 "ca" 的子字符串,如:

car
carrol
castro

或 "car" 的子字符串,如:

car
carrol

到目前为止,这是我的方法:

 public ObservableList<Part> searchBySubstring(String sub, ObservableList<Part> full){
    ObservableList<Part> newParts = FXCollections.observableArrayList();

    for(int i = 0; i < full.size(); i++){
        if(full.get(i).getPartName().contains(sub))
            newParts.add(full.get(i));
    }
    return newParts;
}

如果您只想简单地创建原始 ObservableList 的 "snapshot",那么您已经在做的就是这样做的方法。您可以更改代码以使用 for-each 循环或流,但我认为这更像是一种风格选择。

For-Each 循环:

ObservableList<Part> search(String sub, ObservableList<Part> full) {
    ObservableList<Part> result = FXCollections.observableArrayList();
    for (Part part : full) {
        if (part.getPartName().contains(sub)) {
            result.add(part);
        }
    }
    return result;
}

流:

ObservableList<Part> search(String sub, ObservableList<Part> full) {
    return full.stream()
            .filter(part -> part.getPartName().contains(sub))
            .collect(Collectors.toCollection(FXCollections::observableArrayList));
}

但是,如果您希望 ObservableList 随着原始 ObservableList 的变化而更新,请使用 FilteredList。在这种情况下,您只需要创建 FilteredList 一次 并根据需要更新 Predicate

String sub = ...;
ObservableList<Part> full = ...;
FilteredList<Part> filtered = full.filtered(part -> part.getPartName().contains(sub));
// or use new FilteredList<>(...);

// Then, to "re-search" the list...
String newSub = ...;
filtered.setPredicate(part -> part.getPartName().contains(newSub));

FilteredList 将随着在原始 ObservableList 中添加和删除元素而更新。如果您希望它在 Part(已在列表中)的名称更改时更新,那么您需要做两件事:

  1. PartpartName 公开为 Observable,例如 StringProperty
  2. 通过 observableArrayList(Callback) or observableList(List,Callback) 使用提取器构建原始 ObservableList

使用提取器的示例:

ObservableList<Part> parts = FXCollections.observableArrayList(
        part -> new Observable[]{part.partNameProperty()});

CallbackCallback<E, Observable[]>