fgarci03
fgarci03

Reputation: 430

How to find if an ArrayList contains a character from a String?

I am trying to build a function that evaluates an ArrayList (with contents from a file) and checks if all its characters are contained inside a variable (String), and act accordingly if thats not the case.

For example, ["hello", "I am new to Java", "Help me out!"].contains("aeIou") would be ok because all the chars in "aeIou" exist on the array. If it was "aeiou" it would return a message, because 'i' is not in the array, as it's case sensitive (it wouldn't need to test the others). But note that the test chars could be anything, not just letters.

I've built this function, and although it does compile without errors, it always returns that the character is not in the array, although it is:

private static void ValidateDecFile(String testStr, ArrayList<String> fcontents) {
  int count = 0;

  for(int j = 0; j < testStr.length(); j++) {
    if(!Arrays.asList(fcontents).contains(testStr.charAt(j))) {
      String errMsg = "Character '" + testStr.charAt(j) + "' is not in the string.";
    }
  }
}

From the searches I've made, I am assming this is a variable type problem, that does not return the expected "output" for the comparison.

But I've outputed testStr.length(), Arrays.asList(fcontents), testStr.charAt(j) and they all return the expected results, so I have no idea what's going on!

Whatever I do, this function always returns the errMsg String, and the char that "fails" the comparison is always the first char of testStr.

Upvotes: 1

Views: 9875

Answers (5)

Bohemian
Bohemian

Reputation: 425418

You can do the test in one line:

List<String> list;
String chars;

String regex = chars.replaceAll(".", "(?=.*\\Q$0\\E)") + ".*";
StringBuilder sb = new StringBuilder();
for (String s : list)
    sb.append(s);
boolean hasAll = s.toString().matches(regex);

In java 8, the whole thing can be one line:

boolean hasAll = list.stream()
    .collect(Collectors.joining(""))
    .matches(chars.replaceAll(".", "(?=.*\\Q$0\\E)") + ".*");

The trick is to turn chars into a series of look ahead assertions and run that over the list concatenate into one giant string.

This will work for any input chars and any test chars, due to the regex treating each char as a literal.

Upvotes: 4

isaac.hazan
isaac.hazan

Reputation: 3874

In Java 8 using streams you can simplify it with the following:

    String searchStr = "aeliou";
    List<String> data = Arrays.asList("hello", "I am new to Java", "Help me out!");
    for(int i = 0; i < searchStr.length(); i++ )
    {
        final int c = i;
        if( ! data.stream().anyMatch(t ->  t.contains(Character.toString(searchStr.charAt(c)))) )
                System.out.println("not found:" + searchStr.charAt(i));
    }

Or even shorter in a single statement using the chars() method from java 8:

    String searchStr = "aeliou";
    List<String> data = Arrays.asList("hello", "I am new to Java", "Help me out!");
    searchStr.chars().forEach(c -> {
        if (!data.stream().anyMatch(t -> t.contains(Character.toString((char)c))))
            System.out.println("not found:" + Character.toString((char)c));
    } );

Upvotes: 0

Xavi L&#243;pez
Xavi L&#243;pez

Reputation: 27880

Invoking contains() on a List will compare each element in the list to the argument, so in your example it would be comparing hello, I am new to Java and so on to each one of the search characters.

Inside the loop, you should be testing if any of the Strings in the List contain the character, not if one of the Strings in the List is the character.

Note that String.contains() needs a CharSequence as an argument, and charAt returns a char. You could use indexOf instead and test if it returns a positive number.

private static void ValidateDecFile(String testStr, ArrayList<String> fcontents) {
  int count = 0;

  String errMsg;
  for(int j = 0; j < testStr.length(); j++) {
      boolean found = false;
      for (int i = 0;i<fcontents.size() && !found;i++) { 
           found = fcontents.get(i).indexOf(testStr.charAt(j)) >= 0;
      }

      if (!found){
          errMsg = "Character '" + testStr.charAt(j) + "' is not in the string.";
    }
  }
}

Ideone demo.

Upvotes: 0

sarveshseri
sarveshseri

Reputation: 13985

private static void ValidateDecFile(String testStr, ArrayList<String> fcontents) {
    String fullStr = "";

    for( int j = 0; j < fcontents.length(); j++ ) {
        fullStr += fcontents.get( j );
    }

    for(int j = 0; j < testStr.length(); j++) {
        if( !fullStr.contains( testStr.charAt(j) ) ) {
            String errMsg = "Character '" + testStr.charAt(j) + "' is not in the string.";
            System.out.println( errMsg );
        }
    }
}

Upvotes: 0

Kalaiarasan Manimaran
Kalaiarasan Manimaran

Reputation: 1658

Try the below one, You need to iterate and check each elements in the list and not the list

Hopt you will get the required

      private static void ValidateDecFile(String testStr, ArrayList<String> fcontents) {
              int count = 0;
              boolean flag = false;
              for(int j = 0; j < testStr.length(); j++) {
                  flag = false;
                  for(String content:fcontents){
                      if(content.contains(""+(testStr.charAt(j)))){
                          flag=true;
                      }
                  }
                if(flag) {
                  String errMsg = "Character '" + testStr.charAt(j) + "' is not in the string.";
                }
              }
        }

Upvotes: 0

Related Questions