简体   繁体   中英

Checking if a List of Lists contains a certain String

I have made a list of Countries based on Name, Population, Surface etc. I have used the Arrays.asList Methods to add each entry. After that, all entries were added to a new list based on continents. Eg

List<String> countriesAfrica = Arrays.asList("Nigeria", "Ethiopia", etc) are added to List<Africa> africaList = new ArrayList<>(); using a for loop

for (int k = 0; k< countriesAfrica.size(); k++) {
        africaList.add(new Africa(countriesAfrica.get(k), 
                              populationAfrica.get(k),
                              surfaceAfrica.get(k), 
                              fertilityAfrica.get(k)));
}

In order to search by Country Name, I have tried using the contains() method. I have added the country Africa to a List of Lists, as follows:

List<List<String>> list = new ArrayList<>();
for (int i = 0; i < 4; i++) {
    List<String> l = new ArrayList<>();
    for (int j = 0; j < africaList.size(); j++) {
        if (i == 0) {
            l.add(africaList.get(j).getName());
        }
        if (i == 1) {
            l.add(String.valueOf(africaList.get(j).getSurface()));
        }
    }
    list.add(l);
}

Using the contains Method, list.contains("Nigeria"); returns nothing or false when using SOUT. Any ideas where I did wrong?

Original Answer

Your new list has reordered the objects with a list of names, a list of populations, a list of surfaces, and a list of fertility. This means the first element in the list, at index zero, will always contain a list of countries. Therefore, you should retrieve that list, and check it for .contains

System.out.println(list.get(0).contains("Nigeria"));

Edit for more clarification and java.util.stream

It looks like you may have a fundamental misunderstanding of how the contains method works. The method is not recursive. So, when you use contains on a list of lists, you can only check to see if the parent list contains a child list. Take for example the following code:

List<String> names = new ArrayList<>();
List<String> places = new ArrayList<>();
List<String> things = new ArrayList<>();
List<List<String>> everything = new ArrayList<>();

names.add("Bob");
names.add("Steve");
places.add("California");
places.add("New York");
things.add("Watch");
things.add("cars");

everything.add(names);
everything.add(places);
everything.add(things);

If I want to check my everything list to see if it contains the places list, I can simply check it with the contains method.

boolean containsList = everything.contains(places);

this returns true .

However, boolean containsList = everything.contains(places.get(0)) returns false. In fact, my IDE gives me a warning:

List<List<String>> may not contain objects of type String

So, what if I want to check for the presence of "Bob"? As the person who wrote this line of code, I know that Bob is the first element added to the list. Since Lists are ordered, I also know that Bob will always be located somewhere in the 0 index of my list. So, I can simply check if it exists in that index by using the contains method on the index itself.

boolean containsBob = everything.get(0).contains("Bob");

This also returns true .

But what if I don't know where in the list something exists at? What if it could be in any index? This is where streams come in.

boolean caExists = everything.stream().anyMatch(list -> list.contains("California"));

This returns true as well. The difference in this and the previous method, which uses a known index, is that the stream will iterate through the lists contained within everything and run the list.contains() method on that list . Than, if any of the lists return . Than, if any of the lists return true , the result will be true`.

Demonstration

You can see this demonstrated more effectively here:

boolean bobExists = everything.get(0).contains("Bob");
boolean caExists = everything.stream().anyMatch(list -> list.contains("California"));
boolean nothingExists = everything.stream().anyMatch(list -> list.contains("nothing"));
boolean containsList = everything.contains(places);
boolean invalidCheck = everything.contains("Bob");

System.out.println("Contains Bob: " + bobExists);
System.out.println("Contains California: " + caExists);
System.out.println("Contains nothing: " + nothingExists);
System.out.println("Contains the places list: " + containsList);
System.out.println("Invalid check of String to List: " + invalidCheck);

The bobExists boolean uses a known index to check the existence of a known String. The next two variables use stream to check the entire parent list. The containsList checks the existence of a child list. The invalidCheck checks the existence of a String in the parent list. Since the parent list can only contain a list of type String, this will always return false.

The resulting output from running the above code is as follows:

Contains Bob: true
Contains California: true
Contains nothing: false
Contains the places list: true
Invalid check of String to List: false

As you can see, the stream works to check the existence of a string in the child objects, regardless of location. This is the most versatile approach.

I hope this helps clarify things.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM