Collate a growing number of String arrays and search through them [closed]

Posted on

Problem

These string arrays are used to classify whether the incoming feed/message is a driver feed or team feed.

private static final String[] DRIVER_FEED_TYPES = {
        "SEBASTIAN_VETTEL", "LEWIS_HAMILTON", "CHARLES_LECLERC", "MAX_VERSTAPPEN",
};


private static final String[] TEAM_FEED_TYPES = {
        "FERRARI", "MERCEDES", "SAUBER", "REDBULL"
};

This method gets the type of feed through the incoming message and determines the corresponding type through the arrayContains method.

private boolean isFeedEnabled(FormulaOneMessage formulaOneMessage) {
    String feedType = formulaOneMessage.getFeedType();

    if (Helper.arrayContains(DRIVER_FEED_TYPES, feedType)) {
        return isDriverFeedEnabled();
    } else if (Helper.arrayContains(TEAM_FEED_TYPES, feedType)) {
        return isTeamFeedEnabled();
    } else {
        return false;
    }
}

The arrayContains method basically looks through the Object array to see if the object is there.

public static boolean arrayContains(Object[] list, Object item) {
    for (Object s : list) {
        if (s.equals(item)){
            return true;
        }
    }

    return false;
}

The challenge is how to manage the growing number of types of String arrays in the class. Should I make it into a map, stream or an enum?

Also, the if else statement would also grow as I continue to add more FEED_TYPES. Should I continue to use them?

Overall, I wanted to improve the maintainability of this code seeing the number of feed types will continue to grow in the future.

Solution

You should use Sets instead of Arrays and Enums when it makes sense. I would write that as:

enum FeedClass {
    TEAM, DRIVER, OTHER;
    private static final Set<String> DRIVER_FEED_TYPES = new HashSet<>(Arrays.asList(
            "SEBASTIAN_VETTEL", "LEWIS_HAMILTON", "CHARLES_LECLERC", "MAX_VERSTAPPEN"));

    private static final Set<String> TEAM_FEED_TYPES = new HashSet<>(Arrays.asList(
            "FERRARI", "MERCEDES", "SAUBER", "REDBULL"
    ));

    public FeedClass fromType(String feedType) {
        if (DRIVER_FEED_TYPES.contains(feedType)) {
            return DRIVER;
        } else if (TEAM_FEED_TYPES.contains(feedType)) {
            return TEAM;
        } else {
            return OTHER;
        }
    }
}

private boolean isFeedEnabled(FormulaOneMessage formulaOneMessage) {
    FeedType feedType = FeedClass.fromType(formulaOneMessage.getFeedType());
    switch (feedType.getClazz()) {
        case DRIVER:
            return isDriverFeedEnabled();
        case TEAM:
            return isTeamFeedEnabled();
        default:
            return false;
    }
}

Driver names isn’t really something that should be hardcoded, you probably want to move it to database or external file(s).
You can’t really avoid if/switch in isFeedEnabled() unless you move isDriverFeedEnabled and isTeamFeedEnabled into enum, it might not be
possible in your code to do it cleanly.

Leave a Reply

Your email address will not be published. Required fields are marked *