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

我想使用 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);

    }


}


一只甜甜圈
浏览 409回答 2
2回答

波斯汪

我在您的 Stream 代码中看不到根本问题。您编写的方式不是很有效,它允许匹配多个单词的元素在结果列表中多次出现。也许,您设置结果的 UI 无法处理这个问题。我将从输入的文本中创建一个过滤器,如果元素中出现任何单词,它将匹配,使用不区分大小写的匹配,而不是将每个字符串重复转换为小写。例如,使用这样的实用方法:static final Pattern SPACE = Pattern.compile("\\s+");public static <T> Predicate<T> getFilter(Function<? super T, String> f, String words) {&nbsp; &nbsp; String regex = SPACE.splitAsStream(words)&nbsp; &nbsp; &nbsp; &nbsp; .map(Pattern::quote).collect(Collectors.joining("|"));&nbsp; &nbsp; Predicate<String> sp = Pattern.compile(regex, Pattern.CASE_INSENSITIVE).asPredicate();&nbsp; &nbsp; return t -> sp.test(f.apply(t));}可以用作List<Products_Data> filteredList = productList.stream()&nbsp; &nbsp; .filter(getFilter(Products_Data::getPartDesc, searchField.getText()))&nbsp; &nbsp; .collect(Collectors.toList());

临摹微笑

你的匹配核心应该是这样的:productList.stream().filter(&nbsp; &nbsp; product -> searchableWords.stream().allMatch(&nbsp; &nbsp; &nbsp; &nbsp; searchWord -> product.getPartDesc().toLowerCase().contains(searchWord)&nbsp; &nbsp; ))
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java