是否可以访问JAVA8流过滤器内的外部变量?

时间:2018-02-21 05:42:01

标签: java lambda collections filter java-stream

我被困在一个senario上,我希望根据条件过滤字符串ArrayList中20%的元素。我搜索了Stream.filter,并且有一些东西阻止我使用它。 我有一个arraylist containsig字符串作为“一,二,三,四”和一个匹配变量String match =“e”;假设我已将列表作为myList,我想做类似的事情,

public List<String> filterArrayList(List<String> myList, String match){
    List<String> filtered_result=myList.stream().filter(elem -> {
    if(elem.indexOf(match)!=-1){
      return true;
    }
    return false;
  }).collect(Collectors.toList());
  return filtered_result; 
}
filterArrayList(somelist,"e");

但这似乎不起作用,因为我无法访问过滤器内的匹配变量。它只返回列表为“e”,这是变量匹配的值。       filtered_result = [“e”]

我也尝试过这样做,

List<String> filtered_result=myList.stream().filter(elem -> elem.contains(match)).collect(Collectors.toList());

这也会返回相同的内容。有什么方法可以在这里做一个工作吗?

PS:我不想仅为此目的创建一个POJO类,也不能创建一个最终变量,因为列表作为这个方法的参数,这是我跨类的多种方法。

编辑:映射到方法的匹配变量因方法而异,并且不能保持不变。

3 个答案:

答案 0 :(得分:3)

为了表明这是按照方法编写的,这是方法

public static List<String> matchFilter(List<String> list, final String match) {
    return list.stream()
        .filter(e -> e.indexOf(match) != -1)
        .collect(Collectors.toList());
}

public static void main(String[] args) {
    String match = "e";
    List<String> myList = Arrays.asList("one", "two", "three", "four");
    System.out.println(matchFilter(myList, match)); // [one, three]
}

在应用流过滤

之前,您应该尝试打印myList的内容

关于额外的评论。

  

我不想为此目的创建一个POJO类

你不需要,但这是一种实用方法,所以它可以作为static方法在一些随机类中关闭,以便在任何地方使用。

  

我也不能创建一个final变量,因为列表作为这个方法的参数,是我跨类的多种方法

如此代码所示,final String match是有效参数。它不需要是最终的,但我表明它不会影响任何事情。列表也可能是最终的,但这里没有理由。使任何变量最终只意味着你不能重新分配它。 您仍然可以添加和删除值final List

注意:这是过滤50%,而不是20%(这在4个元素的列表中是不可能的)

答案 1 :(得分:0)

要在lambda中使用变量match,它必须有效final (它就在这里,在你的例子中)。你的第一个例子在这里工作,但它不优雅;问题必须出在你如何获得myList - 而不仅仅是if return elem.indexOf(match) != -1; - 这可以在这个mcve中进一步细化,

public static void main(String[] args) {
    String match = "e";
    List<String> myList = Arrays.asList("one", "two", "three", "four");
    List<String> filtered_result = myList.stream() //
            .filter(e -> e.indexOf(match) != -1) //
            .collect(Collectors.toList());
    System.out.println(filtered_result);
}

哪个输出

[one, three]

答案 2 :(得分:0)

您是否正在根据列表中的“匹配”变量值进行过滤?如果是,那么下面的代码可以帮助您

        List<String> lines = Arrays.asList("one", "two", "three");
    String match = "e";
    List<String> result = lines.stream()               
            .filter(line -> !match.equals(line))    
            .collect(Collectors.toList());             
    result.forEach(System.out::println);