Problem overview
The method addIfMissing receives a shopping list items (a list of strings) and a word item. It adds item at the end only when the list does not hold it yet, and returns the list. When the word is already there, the list stays as it was. The list may start empty.
For ["milk", "eggs"] and "bread" the result is ["milk", "eggs", "bread"]. For "milk" it stays ["milk", "eggs"]. For an empty list and "apples" it becomes ["apples"].
Approach
The rule has a condition ("only when it is missing"), so an if is needed. items.contains(item) is true when the word is in the list, and ! turns that around, so !items.contains(item) is true exactly when the word is missing. Inside the if, a plain add puts the word at the end. After the if, the list is returned in both cases.
An empty list needs no special case: contains on an empty list is false, so the word is added.
Step by step
- Write the condition
if (!items.contains(item))and close its braces right away. - Inside it, call
items.add(item). This runs only for a new word, so the list never gets the same word twice. - After the
if,return items. If nothing was added, the list comes back as it was.
The solution in Java
class Solution {
public List<String> addIfMissing(List<String> items, String item) {
if (!items.contains(item)) {
items.add(item);
}
return items;
}
}
Details worth knowing:
containscompares withequals, so it checks the text, not the identity of the string object. That is the right behaviour for words.- The match is exact, so
"Milk"and"milk"are different words. The lesson's words are all lowercase. - The method changes the list it receives and returns that same list.
Edge cases and common mistakes
- Adding without the check. A bare
items.add(item)puts"milk"in twice. - Forgetting the
!.if (items.contains(item))adds only words that are already there, which is the opposite of the task. - Returning inside the
ifonly. If thereturnsits inside the braces, nothing is returned when the word was already there, and the method does not compile. - Empty list. It works with no special code.
Why not just add and clean up?
You could add the word every time and remove duplicates afterwards, but the check is simpler and keeps the list correct at every moment. A list that never holds the same word twice is the property the task is about, and the if guarantees it. For long lists, a Set is built for exactly this "have I seen it" question, but the lesson uses a list, and contains is the right tool for it.
Tracing the examples
- Adding
"bread"to["milk", "eggs"]:containsisfalse,!makes the conditiontrue, so the word is added at the end. - Adding
"milk"to the same list:containsistrue, the condition isfalse, and the body is skipped. - Adding
"apples"to an empty list: nothing matches, so the word goes in and is the only item.
Testing
Inputs and the output of the solution:
["milk", "eggs"],"bread"givesmilk eggs bread.["milk", "eggs"],"milk"givesmilk eggs.[],"apples"givesapples.
