2

I want to find a substring in an array of strings, without using loop. I'm using:

import java.util.Arrays;

public class MyClass {
    public static void main(String args[]) {

        String[] files = new String[]{"Audit_20190204_061439.csv","anotherFile"};
        String substring= ".csv";

        if(!Arrays.stream(files).anyMatch(substring::contains)) {
            System.out.println("Not found:" + substring);
        }
    }
}

I'm always getting Not found. What is wrong with the approach?

2
  • You are just hiding the loop via the stream. That doesn't make the approach any better not faster than a straightforward, understandable, for loop. Commented Feb 4, 2019 at 9:11
  • On the contrary, see how the overuse of lambdas caused you to make a mistake that is hard to find (wrong parameter order in the substring function). Commented Feb 4, 2019 at 9:12

3 Answers 3

4

You are checking whether the String ".csv" does not contain any of the elements of your Stream, which is the opposite of what you wanted.

It should be:

if (!Arrays.stream(files).anyMatch(s -> s.contains(substring))) {
    System.out.println("Not found:" + substring);
}

P.S. As commented, you can use noneMatch instead of anyMatch, which will save the need to negate the condition:

if (Arrays.stream(files).noneMatch(s -> s.contains(substring))) {
    System.out.println("Not found:" + substring);
}

and if the ".csv" substring should only be searched for in the end of the String (i.e. treated as a suffix), you should use endsWith instead of contains.

Sign up to request clarification or add additional context in comments.

2 Comments

! + anyMatch() -> noneMatch()
The OP probably wants to use String#endWith here, since .csv is an extension, should only appear at the end of the string.
2

You possibly need to check the file extension and can use endsWith for it instead and improve your condition to:

if (Arrays.stream(files).noneMatch(a -> a.endsWith(substring))) {
    System.out.println("Not found:" + substring);
}

Comments

1

I am not a streams guru, but I believe that you want something like this:

String[] files = new String[] { "Audit_20190204_061439.csv", "anotherFile" };

for (String file : files) {
    if (file.endsWith(".csv")) {
        System.out.println("found a CSV file");
    }
}

I use String#endsWith here because presumably .csv refers to a file extension, and should only register a hit if occur at the end of the filename.

We could also use String#matches here:

Pattern pattern = Pattern.compile(".*\\.csv$");
for (String file : files) {
    Matcher matcher = pattern.matcher(file);
    if (matcher.find()) {
        System.out.println("found a CSV file");
    }
}

2 Comments

I would recommend against file#matches() inside loops, better create a Pattern beforehand: Pattern.compile(".*.csv$")
@Lino And in fact you have told me this before. I guess old habits die hard :-(

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.