繁体   English   中英

使用Java 8流过滤包含来自另一个列表中的一个或多个字符串的字符串列表

[英]Filter a list of strings which contains one or more strings from another list with Java 8 streams

我想使用TextField中插入的字符串来过滤列表。 我在TextField上使用KeyReleased事件来过滤每个键上的列表。 当我输入单词时,下面的代码片段会过滤列表,但是当我按空格键并开始键入另一个单词时,列表会变空。 我对溪流有点新意。 我不知道我做错了什么。


private ObservableList<Products_Data> productList;
@FXML       
private JFXTextField searchField;
@FXML       
private TableView<Products_Data> productTable;
@FXML
void searchKeyReleased(KeyEvent event) {
    String searchText = searchField.getText();
    List<String> searchableWords = Arrays.asList(searchText.toLowerCase().trim().split("\\s+"));
    List<Products_Data> filteredList =  searchableWords.stream()
        .flatMap(i ->productList.stream()
        .filter(j -> j.getPartDesc().toLowerCase().contains(i)))
        .collect(Collectors.toList());
    ObservableList<Products_Data> productFilteredList = FXCollections.observableArrayList(filteredList);
    productTable.setItems(productFilteredList);
}

----------
public class Products_Data {
    private final StringProperty partDesc = new (this,"PartDesc",null);

    public Products_Data() {}

    public final StringProperty getPartDescProperty() {return partDesc;}
    public final String getPartDesc(){return partDesc.get();}
    public final void setPartDesc(String partDesc) {     
        getPartDescProperty().set(partDesc);
    }

}

我无法在您的Stream代码中看到根本问题。 你编写它的方式不是很有效,它允许在结果列表中多次出现匹配多个单词的元素。 也许,您设置结果的UI无法处理此问题。

我将从输入的文本中创建一个单独的过滤器,如果元素中出现任何单词,它将匹配,使用不区分大小写的匹配,而不是重复地将每个字符串转换为小写。 例如,使用这样的实用方法:

static final Pattern SPACE = Pattern.compile("\\s+");

public static <T> Predicate<T> getFilter(Function<? super T, String> f, String words) {
    String regex = SPACE.splitAsStream(words)
        .map(Pattern::quote).collect(Collectors.joining("|"));
    Predicate<String> sp = Pattern.compile(regex, Pattern.CASE_INSENSITIVE).asPredicate();
    return t -> sp.test(f.apply(t));
}

可以用作

List<Products_Data> filteredList = productList.stream()
    .filter(getFilter(Products_Data::getPartDesc, searchField.getText()))
    .collect(Collectors.toList());

匹配的核心应该是这样的:

productList.stream().filter(
    product -> searchableWords.stream().allMatch(
        searchWord -> product.getPartDesc().toLowerCase().contains(searchWord)
    )
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM