Asking whether a list holds a value
Programs often need to know whether a list contains something: is this name on the guest list, is this item in the cart. contains(x) answers with a boolean. It compares x with each item from the first one on, returns true as soon as one matches, and returns false if none does.
List<String> colors = new ArrayList<>(List.of("red", "green", "blue"));
System.out.println(colors.contains("red")); // true
System.out.println(colors.contains("pink")); // false
Using it in an if
Because the answer is a boolean, it goes straight into an if condition. Put ! in front to ask the opposite question: !colors.contains(x) is true when x is missing.
List<String> cart = new ArrayList<>(List.of("milk", "bread"));
if (cart.contains("milk")) {
System.out.println("Milk is in the cart");
}
if (!cart.contains("eggs")) {
System.out.println("Eggs are missing");
}
Details that matter
Text must match exactly
contains uses equals to compare items, so strings must match in every character, including upper and lower case. colors.contains("Red") is false because the list holds "red".
Any type compiles
contains accepts an Object, so a value of the wrong type is not a compile error. colors.contains(5) compiles and simply returns false on a list of strings. If a check always fails, make sure the value has the same type as the items.
It finds the value, not the position
contains only says yes or no. If you also need the position, indexOf(x) returns the index of the first match, or -1 when the value is not there: on the colors list, indexOf("blue") is 2 and indexOf("pink") is -1.
Cost
Because contains may look at every item, it takes longer on longer lists. For a handful of items that does not matter.
Combining checks
Because each contains call is a boolean, the checks combine with && and ||. For the hike bag, bag.contains("water") && bag.contains("map") is true, while bag.contains("water") && bag.contains("tent") is false. The same method name exists on other types: a Set has contains with the same meaning (and is built to answer it fast), while on a String it asks whether a piece of text appears inside it, so "hello".contains("ell") is true.
The exercise
The list bag holds what is packed for a hike. Two checks are needed, one for each direction:
- Is water packed? Use
bag.contains("water")as the condition and printWater is packedinside. The bag holds water, so this prints. - Is the tent missing? Put
!beforebag.contains("tent")and printPack a tentinside. The bag has no tent, so the condition istrueand this prints too.
List<String> bag = new ArrayList<>(List.of("map", "water", "snacks"));
if (bag.contains("water")) {
System.out.println("Water is packed");
}
if (!bag.contains("tent")) {
System.out.println("Pack a tent");
}
Output:
Water is packed
Pack a tent
Common mistakes
- Forgetting the
!. Writingif (bag.contains("tent"))prints nothing here, because the bag has no tent. When the message is about something missing, the condition needs the!. - Comparing items with
==. Two strings with the same text can be different objects, and==compares the objects.containscompares the text. Ifs1isnew String("water"), thenbag.contains(s1)istruewhilebag.get(1) == s1isfalse. - Expecting an error on an empty list.
containson an empty list is simplyfalse, so the check is safe before anything has been added.
Key takeaways
list.contains(x)returnstrueorfalseand fits directly in anif.!list.contains(x)means "x is missing".- Matching is exact, including letter case, and the argument can be any type, so check that the types agree.
- Use
indexOfwhen you need the position too.
