1

If I want to see if one substring equals any of several other substrings. Is this possible to do without putting each case beside each other:

Current way:

if ( substr.equals("move") || substr.equals("mv") || substr.equals("mov") ){…}

Shorter version (not working):

if ( substr.equals("move" || "mv" || "mov") )
chris Frisina
  • 19,086
  • 22
  • 87
  • 167
  • Not with the native JDK, but it's pretty easy to write a method of yours which does that – fge Jun 16 '13 at 21:20

6 Answers6

8

Put all your strings in a Set<String> and use the contains method.

For example:

private final Set<String> wordMoveTokens = new HashSet<String>(Arrays.asList("move", "mv", "moov"));
...
// substr = "move"
if (wordMoveTokens.contains(substr) ) {
   .... // True
}

Take a look here for more examples.

Community
  • 1
  • 1
Jean Logeart
  • 52,687
  • 11
  • 83
  • 118
4

I can think of at least 3 different ways to do this:

  1. Use a Set<String> to hold all the possible matches and use Set<String>.contains() in your if statmeent.

  2. If you are using JDK 1.7, you can use a switch statement:

    switch (substr) {
        case "move":
        case "mv":
        case "mov":
            // ...
            break;
    }
    
  3. Use a regular expression:

    if (substr.matches("move|mov|mv") {
        //...
    }
    
Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
3

You can try this way

substr.matches("move|mv|mov");

but be careful with regex special characters like $,^,+,* and others.

Pshemo
  • 122,468
  • 25
  • 185
  • 269
2

You may use:

if ((Arrays.asList("move","mov","mv")).contains(substr))
Vishal K
  • 12,976
  • 2
  • 27
  • 38
1

Try:

private static final Set<String> SUBSTRINGS = new HashSet<>(Arrays.asList("move", "mv", "mov"));

...

SUBSTRINGS.contains(substr);
Puce
  • 37,247
  • 13
  • 80
  • 152
  • @TomHawtin-tackline why not? Of course, you can move this code to a helper method if you like, but there's nothing wrong with a HashSet here. – Puce Jun 16 '13 at 21:33
  • Why you want to wrap it with Set? List also have `contains` method. – Pshemo Jun 16 '13 at 21:33
  • 1
    It is true, but to create HashSet you need first to iterate over all List elements. With `List.contains()` you iterate until you find correct object. Also to generate hashcode you need to iterate over all String characters. So it will be similar to O(1) after you do O(n). – Pshemo Jun 16 '13 at 21:42
  • @Pshemo I'm aware of that. But it's also about hashCode generation and int comparison vs String comparison. I guess it also depends on the imput and I haven't benchmarked it. Maybe it's just a personal taste to use HashSet for contains-operations when working with data structures which work well with hash based data structures. It will surely pay off as soon as you have to compare different String against the same set of values. – Puce Jun 16 '13 at 21:53
  • @Pshemo see my edit. The gain is more clear now. Of course this depends if you know the set of strings you want to compare against at compile time or if this set is dynamic and a one-off thing as well. – Puce Jun 16 '13 at 21:58
  • OK, lets say that your answer will have better performance if we will use once created HashSet few times to check if it `contains(substr)` (that is why I wont remove my +1). But in situation where it will be used only once I believe it is better to just use `Arrays.asList("move", "mv", "mov").contains(substr)`. – Pshemo Jun 16 '13 at 22:00
  • @Pshemo: Code which is executed "only once" today may be executed multiple times tomorrow. If the code is really executed only once then a few CPU cycles won't matter. If it is executed multiple times, CPU does matter. Summary: Why not always use the `Set` method? – A.H. Jun 16 '13 at 22:48
  • @A.H. I am not saying about executing code once, but creating once and using multiple times same instance of `HashSet`. Creating that instance is full O(n) - because we need to iterate over all elements in List) but using its `contains` method is close to O(1) like getting element from array. But while using `contains()` from List O(n) is the maximal time required for `contains`, because we can find match before earlier, and wont have to iterate over last element of list. – Pshemo Jun 16 '13 at 22:58
1

Within the native JDK, no.

There are however many possibilities. There is a kind of shortcut if you use a Set:

// Written with Guava, I'm too lazy
final Set<String> moves = ImmutableSet.of("move", "mv", "mov");
moves.contains(substr); // true if there is a match

Or a custom function:

public boolean matchesOneOf(String whatToMatch, String... candidates)
{
    for (final String s: candidates)
        if (whatToMatch.equals(s))
            return true;
    return false;
}

Now, it all depends on your data. Your best bet is to structure it effectively so that you do not have to do what you currently do ;)

fge
  • 119,121
  • 33
  • 254
  • 329