7

I was wondering how to refer to the result of a lambda in Java? This is so I can store the results into an ArrayList, and then use that for whatever in the future.

The lambda I have is:

try {
    Files.newDirectoryStream(Paths.get("."),path -> path.toString().endsWith(".txt"))
         .forEach(System.out::println);
} catch (IOException e) {
    e.printStackTrace();
}

and inside the .forEach() I want to be able to assign each file name to the array in turn, for example, .forEach(MyArrayList.add(this))

Thanks for any help in advance!

Nicholas K
  • 15,148
  • 7
  • 31
  • 57

3 Answers3

10

Use :

List<String> myPaths = new ArrayList<>();
Files.newDirectoryStream(Paths.get("."), path -> path.toString().endsWith(".txt"))
     .forEach(e -> myPaths.add(e.toString()));

Edit :

We can achieve the same in one line using :

List<String> myPaths = Files.list(Paths.get("."))
                            .filter(p -> p.toString().endsWith(".txt"))
                            .map(Object::toString)
                            .collect(Collectors.toList());
Nicholas K
  • 15,148
  • 7
  • 31
  • 57
  • 1
    Please also see _Side-effects_ section of [Package java.util.stream Description](https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html). For more efficient execution, you should replace `forEach` by reduction. See Holger's comment to the answer below. – Ritesh Oct 02 '18 at 16:54
9

You can achieve that by collecting the result of the newDirectoryStream operation :

  1. You can add the elements in a list as you iterate it but that's not the better way :

    List<Path> listA = new ArrayList<>();
    Files.newDirectoryStream(Paths.get(""), path -> path.toString().endsWith(".txt"))
         .forEach(listA::add);
    
  2. You may use another method like find which returns a Stream<Path> that would be easier to use and collect the elements in a list :

    List<Path> listB = Files.find(Paths.get(""), 1,(p, b) -> p.toString().endsWith(".txt"))
                            .collect(Collectors.toList());
    
  3. Or Files.list()

    List<Path> listC = Files.list(Paths.get("")).filter(p -> p.toString().endsWith(".txt"))
                            .collect(Collectors.toList());
    
azro
  • 53,056
  • 7
  • 34
  • 70
  • 2
    Or `List listC = Files.list(Paths.get("")).filter(p -> p.toString().endsWith(".txt")).collect(Collectors.toList());` – Holger Oct 02 '18 at 14:52
3

You can create a variable which represents the current element in forEach and refer it, for example:

ArrayList<Path> paths = new ArrayList<>();

Files.newDirectoryStream(Paths.get("."), path -> path.toString().endsWith(".txt"))
        .forEach(path -> paths.add(path));

which also can be simplied to:

Files.newDirectoryStream(Paths.get("."), path -> path.toString().endsWith(".txt"))
        .forEach(paths::add);
xingbin
  • 27,410
  • 9
  • 53
  • 103