通过过滤器列表运行String列表

时间:2017-11-16 22:55:37

标签: java lambda java-8 java-stream

我有5 private void Form1_Load(object sender, EventArgs e) { // TODO: This line of code loads data into the 'scrumMasterDataSet.Current_Configuration_Settings' table. You can move, or remove it, as needed. this.current_Configuration_SettingsTableAdapter.Fill(this.scrumMasterDataSet.Current_Configuration_Settings); // TODO: This line of code loads data into the 'scrumMasterDataSet.Teams' table. You can move, or remove it, as needed. this.teamsTableAdapter.Fill(this.scrumMasterDataSet.Teams); } private void team_NamesComboBox_SelectedIndexChanged(object sender, EventArgs e) { String status = team_NamesComboBox.Text; team_NameTextBox.Text = status; } private void team_NameTextBox_TextChanged(object sender, EventArgs e) { //this.teamsTableAdapter.Update(this.scrumMasterDataSet.Teams); this.Validate(); this.current_Configuration_SettingsBindingSource.EndEdit(); this.current_Configuration_SettingsTableAdapter.Update(this.scrumMasterDataSet.Current_Configuration_Settings); } }

List<String>

如何通过过滤器列表传递List<Filter>并使用一个过滤器的输出作为另一个过滤器的输入?我可以使用for循环来做到这一点。我想知道如何使用java 8 stream和lambda

来实现这一点

5 个答案:

答案 0 :(得分:2)

以下是如何链接List<Filter>并将其应用于使用流的List<String>

List<String> strings = ...
List<Filter> filters = ...

strings = filters.stream()
        .reduce(s -> s, (a, b) -> s -> b.filter(a.filter(s)))
        .filter(strings);

但正如我在评论中提到的,我认为最干净的解决方案是一个简单的for循环:

for (Filter filter : filters) {
    strings = filter.filter(strings);
}

答案 1 :(得分:0)

函数api的想法是使用表示操作的“功能接口”,类似于方法。在这种情况下,Predicate<T>表示对T起作用并返回boolean的操作,这是Stream#filter方法所需的操作。因此,您可以只使用Predicate<T>过滤Stream<T>(来自您的列表),而不是为您过滤列表的内容:

//in our example, 'T' will be a String
List<Predicate<String>> filters = Arrays.asList(s -> s.startsWith("Hello"));
Stream<String> stream = Stream.of("Test", "Hello world");
//because we have a list of predicates, we need to apply the #filter for each one
for (Predicate<String> pred : filters) {
    stream = stream.filter(pred);
}
stream.forEach(System.out::println); //prints "Hello world"

如果您不需要存储它们的列表,则可以类似地链接:

Stream.of("Test", "Hello world")
    .filter(s -> s.startsWith("Hello"))
    .filter(s -> s.length() > 5)
    .forEach(System.out::println); //prints "Hello world"

对于lambdas本身来说,实现List<"Filter">的应用并不太可行,如果它们存在于lambda范围之外,则lambdas需要变量(有效)为final。

答案 2 :(得分:0)

假设您有以下列表:

List<String> myStrings;
List<Filter> myFilters;

现在你做了:

List<String> myFilteredStrings = myFilters
    .stream()
    .reduce(new ArrayList<String>(myStrings), (strings, filter) -> filter.filter(strings), (l1, l2) -> {
        List<String> combined = new ArrayList(l1);
        combined.addAll(l2);
        return combined;
});

如果您有权访问番石榴图书馆,可以使用Iterables.concatLists.newArrayList使其更清晰

List<String> myFilteredStrings = myFilters
        .stream()
        .reduce(Lists.newArrayList(myStrings), (strings, filter) -> filter.filter(strings), (l1, l2) -> Lists.newArrayList(Iterables.concat(l1, l2));

答案 3 :(得分:0)

将您的转换减少为单个转换,并将其应用于每个元素:

List<String> filter(List<String> strToFilter) {
    List<Function<String, String>> transformations; // populate as you wish
    Function<String, String> reduction = transformations.stream().reduce(identity(), (a, b) -> a.andThen(b));
    return strToFilter.stream().map(reduction::apply).collect(toList());
}

答案 4 :(得分:-1)

A&#34;过滤器&#34;是Predicate,所以只需将它们链接起来:

List<String> filter(List<String> strToFilter) {
    return strToFilter.stream()
        // these predicates are just examples
        .filter(s -> s.contains("foo"))
        .filter(s -> s.length() > 5)
        .collect(Collectors.toList());
}