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!

3 Answers 3

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());
Sign up to request clarification or add additional context in comments.

1 Comment

Please also see Side-effects section of Package java.util.stream Description. For more efficient execution, you should replace forEach by reduction. See Holger's comment to the answer below.
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());
    

1 Comment

Or List<Path> listC = Files.list(Paths.get("")).filter(p -> p.toString().endsWith(".txt")).collect(Collectors.toList());
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);

1 Comment

Using the method reference paths::add instead of path -> paths.add(path) would be even nicer in my opinion.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.