Is it possible to check hundreds of string arrays by invoking their string names in a for loop?

Viewed 275
public class MaryPoppinsBagandWeasleyTent {
    public static void main(String[] args) {
        String[] darkorange = {"3darkchartreuse"};
        String[] stripedfuchsia = {"5stripedlavender"};
        String[] dullgray = {"4mutedcyan", "3lightmaroon"};
        String[] dullchartreuse = {"3lighttan", "3dottedbronze"};
        //etc for hundreds of lines
        String[] names = {"darkorange", "stripedfuchsia",
                "dullgray", "dullchartreuse"}; //etc for hundreds of lines
        String directs = "";
        for (int i = 0; i < names.length; i++) {
            if (names[i].contains("shinygold")) {
                System.out.println(names[i]);
                directs += (names[i] + ",");
            }
        }
    }
}

The list of string arrays, as seen above, is extremely long. I have a corresponding string array of all the names of all the string arrays. Is it possible to call each of these string arrays in the for loop? That’s what I was trying to do with names[I], but that only calls the STRING names[i], not the String[] by the name of names[I].

You may hate the extremely long lists of arrays, but I’ll probably learn a better way soon.

Is it possible to check hundreds of string arrays by invoking their string names in a for loop?

4 Answers

tl;dr

To better manage such immutable data known at compile-time, create an enum for each color group, with set or list of color names contained within.

enum ColorGroup
{
    DARK_ORANGE( List.of( "3darkchartreuse" ) ),
    DULL_GRAY( List.of( "4mutedcyan" , "3lightmaroon" ) );

    private List < String > colors;

    // Constructor
    ColorGroup ( List < String > colors )
    {
        this.colors = colors;
    }

    // Getter
    public List < String > getColors ( )
    {
        return this.colors;
    }
}

Use that enum.

for ( ColorGroup colorGroup : ColorGroup.values() )
{
    System.out.println( "colorGroup name: " + colorGroup + " contains: " + colorGroup.getColors() );
}

colorGroup name: DARK_ORANGE contains: [3darkchartreuse]

colorGroup name: DULL_GRAY contains: [4mutedcyan, 3lightmaroon]


Map

If you want to associate a textual name to each array, use a Map. A map stores entries as a pairing, a key that leads to a value. In your case, the key would be a String object and the value would be an array.

Map < String, String[] > map = new TreeMap <>();
map.put( "Dark Orange" , new String[] { "3darkchartreuse" } );
map.put( "Dull Gray" , new String[] { "4mutedcyan" , "3lightmaroon" } );

System.out.println( map );

When run:

{Dark Orange=[Ljava.lang.String;@77459877, Dull Gray=[Ljava.lang.String;@5b2133b1}

Enum versus text

Using text for such labeling can be error-prone. For example, spelling "Dark Grey" versus "Dark Gray".

So you may choose to use the very simple but powerful enum facility found in Java. Enum objects are constants, automatically instantiated when their class loads. As constants, their names are written in all-uppercase per Java conventions. As named objects, their use detects spelling errors at compile-time, and provides type-safety too.

enum ColorGroupName
{
    DARK_ORANGE,
    DULL_GRAY
}

EnumMap

For a Map using enum objects as keys, use the EnumMap implementation for very fast execution using very little memory.

Map < ColorGroupName, String[] > map = new EnumMap( ColorGroupName.class );
map.put( ColorGroupName.DARK_ORANGE , new String[] { "3darkchartreuse" } );
map.put( ColorGroupName.DULL_GRAY , new String[] { "4mutedcyan" , "3lightmaroon" } );

System.out.println( map );

Collection versus array

Many of us prefer collections over arrays.

Map < ColorGroupName, List < String > > map = new EnumMap( ColorGroupName.class );
map.put( ColorGroupName.DARK_ORANGE , List.of( "3darkchartreuse" ) );
map.put( ColorGroupName.DULL_GRAY , List.of( "4mutedcyan" , "3lightmaroon" ) );

System.out.println( map );

When run:

{DARK_ORANGE=[3darkchartreuse], DULL_GRAY=[4mutedcyan, 3lightmaroon]}

Immutable data

If your map is meant to be unchanging, use Map.of to create an unmodifiable map.

Map < ColorGroupName, List < String > > map =
        Map.of(
                ColorGroupName.DARK_ORANGE , List.of( "3darkchartreuse" ) ,
                ColorGroupName.DULL_GRAY , List.of( "4mutedcyan" , "3lightmaroon" )
        );

System.out.println( map );

Enum containing data

If you want to be quite clever, you can store your list of colors within your enum.

An enum is a special kind of Java class, but still a Java class. As a Java class it can carry member variables. And it can offer a constructor. To store data within the enum, pass the data for each enum object to its constructor call.

enum ColorGroup
{
    DARK_ORANGE( List.of( "3darkchartreuse" ) ),
    DULL_GRAY( List.of( "4mutedcyan" , "3lightmaroon" ) );

    private List < String > colors;

    // Constructor
    ColorGroup ( List < String > colors )
    {
        this.colors = colors;
    }

    // Getter
    public List < String > getColors ( )
    {
        return this.colors;
    }
}

Use that enum.

for ( ColorGroup colorGroup : ColorGroup.values() )
{
    System.out.println( "colorGroup name: " + colorGroup + " contains: " + colorGroup.getColors() );
}

colorGroup name: DARK_ORANGE contains: [3darkchartreuse]

colorGroup name: DULL_GRAY contains: [4mutedcyan, 3lightmaroon]

Map implementations

Here is a chart I made to help with choosing a Map implementation.

enter image description here

store keys and values in one array of delimiter-separated strings (easier to maintain), e.g.

public class MaryPoppinsBagandWeasleyTent {

    private static final String DELIMITER_SEMICOLON = ";";

    private static final String[] OPTIONS = {
            "darkorange;3darkchartreuse",
            "stripedfuchsia;5stripedlavender",
            "dullgray;4mutedcyan;3lightmaroon",
            "dullchartreuse;3lighttan;3dottedbronze",

    };

    public static void main(String[] args) {
        String q = "dullgray";
        String[] split;
        List<String> result = new ArrayList<>(0);
        for (String o : OPTIONS) {
            if (null != o && o.startsWith(q)) {
                split = o.split(DELIMITER_SEMICOLON);
                for (int i = 1; i < split.length; i++) {
                    result.add(split[i]);
                }
            }
        }
        System.out.println(result);
    }

Another solution is using 2D array for storing your String arrays. You can use the code below for this implementation.

String[] names = {"darkorange", "stripedfuchsia",
            "dullgray", "dullchartreuse"};

    String directs = "";

    String[][] matrix = {darkorange, stripedfuchsia,
            dullgray, dullchartreuse}; // 2D string arrays

    for (int i = 0; i < matrix.length; i++) {
        for(int j= 0; j < matrix[i].length; j++)
        if (matrix[i][j]=="shinygold") {
            System.out.println(names[i]);
            directs += (names[i] + ",");
        }
    }
Map<String, String[]> map = new TreeMap<>();
map.put("Dark Orange", new String[]{"3darkchartreuse"});
map.put("Dull Gray", new String[]{"4mutedcyan", "3lightmaroon"});

System.out.println(map);
Related