[英]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.