eggboi
eggboi

Reputation: 51

How to condense code with a sequence of lists in Java?

For a class project, we were tasked with creating a program that would give us the way to defuse a certain module in the game called "Keep Talking and Nobody Explodes". I was tasked with creating a program that would solve the keypad module. I have come up with the solution below.

How can I condense this long line of if-statements to find which list(rowOne, rowTwo, etc.) matches up with the user-entered list(input)?

public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        List<String> input = new ArrayList<>();
        System.out.println("Enter the names of the four symbols");
        for(int i = 0; i < 4; i++) {
            input.add(sc.nextLine());
        }

        List<String> rowOne = List.of("balloon", "at", "upsidedowny", "squigglyn", "squidknife", "hookn", "leftc");
        List<String> rowTwo = List.of("euro", "balloon", "leftc", "cursive", "hollowstar", "hookn", "questionmark");
        List<String> rowThree = List.of("copyright", "pumpkin", "cursive", "doublek", "meltedthree", "upsidedowny", "hollowstar");
        List<String> rowFour = List.of("six", "paragraph", "bt", "squidknife", "doublek", "questionmark", "smileyface");
        List<String> rowFive = List.of("pitchfork", "smileyface", "bt", "rightc", "paragraph", "dragon", "filledstar");
        List<String> rowSix = List.of("six", "euro", "tracks", "ae", "pitchfork", "nwithhat", "omega");

        if(rowOne.containsAll(input)) {
            List<String> copy = new ArrayList<>(rowOne);
            copy.retainAll(input);
            System.out.println(copy);
        }
        if(rowTwo.containsAll(input)) {
            List<String> copy = new ArrayList<>(rowTwo);
            copy.retainAll(input);
            System.out.println(copy);
        }
        if(rowThree.containsAll(input)) {
            List<String> copy = new ArrayList<>(rowThree);
            copy.retainAll(input);
            System.out.println(copy);
        }
        if(rowFour.containsAll(input)) {
            List<String> copy = new ArrayList<>(rowFour);
            copy.retainAll(input);
            System.out.println(copy);
        }
        if(rowFive.containsAll(input)) {
            List<String> copy = new ArrayList<>(rowFive);
            copy.retainAll(input);
            System.out.println(copy);
        }
        if(rowSix.containsAll(input)) {
            List<String> copy = new ArrayList<>(rowSix);
            copy.retainAll(input);
            System.out.println(copy);
        }
    }
}

Upvotes: 1

Views: 89

Answers (2)

Basil Bourque
Basil Bourque

Reputation: 338336

List of lists

You can make a list of lists. No need to assign each list to a sequentially named variable.

The idea here is that a List is a collection of objects. An instance of a List is itself an object. Therefore a List object can contain other List objects.

We declare a list of lists: List < List < … > >

List < List < String > > listOfListOfStrings= 
    List.of(
        List.of( … ) ,
        List.of( … ) ,
        …
    )
;

Loop that outer list to obtain each inner list.

for( List< String > listOfStrings : listOfListOfStrings ) 
{
    // process each list-of-strings here
}

Poof! 💨 No more variables named whateverOne, whateverTwo, whateverThree, and so on.

The new version of your code will be much shorter. And be less likely to hide copy-paste typos.

By soft-coding to the size of a list, you can grow and shrink your list of lists without having to change other code.

Here is a full example app.

package … 

import java.util.List;

public class ListOfListsDemo
{
    public static void main ( String[] args )
    {
        List < List < String > > listOfListOfStrings =
                List.of(
                        List.of( "dog" , "cat" , "bird" ) ,
                        List.of( "vanilla" , "chocolate" , "strawberry" ) ,
                        List.of( "Honda" , "Tesla" , "Mazda" )
                );

        for ( List < String > listOfStrings : listOfListOfStrings )
        {
            boolean containsMazda = listOfStrings.contains( "Mazda" );
            String message = listOfStrings.toString() + " contains 'Mazda': " + containsMazda;
            System.out.println( message );
        }
    }
}

When run.

[dog, cat, bird] contains 'Mazda': false
[vanilla, chocolate, strawberry] contains 'Mazda': false
[Honda, Tesla, Mazda] contains 'Mazda': true

Upvotes: 4

Andy Turner
Andy Turner

Reputation: 140309

An alternative to BasilBourque' answer is to use a method:

void method(List<String> input, List<String> row) {
    if(row.containsAll(input)) {
        List<String> copy = new ArrayList<>(row);
        copy.retainAll(input);
        System.out.println(copy);
    }
}

Then invoke like:

method(input, List.of("balloon", "at", "upsidedowny", "squigglyn", "squidknife", "hookn", "leftc"));
method(input, List.of("euro", "balloon", "leftc", "cursive", "hollowstar", "hookn", "questionmark"));
// etc.

Upvotes: 2

Related Questions