How to check if each String in an array is unique?

I've got an application with six FXML textFields, where a user can provide six String inputs. These inputs are checked against a list of 31 names. If each String is not one of the names on the list, it's rejected.

I've gathered the Strings into an Array, and I'd like to check if they are unique (so the user cannot enter the same input more than once). But I've got no idea how to go about doing this!

What do you suggest, Java gurus?

Posted Oct 7, 2019, 11:56 PM UTC

2319
Firadine•

Instead of adding them to an array, add them to a Set. When you are done adding, get the set size. If it is less than 6 you know there was duplicates (which sets won’t allow).

28
E3FxGaming•

If OP adds the values to the set one by one, OP can also check the return value of the add method. add returns true if the set did not already contain the element, or returns false if the set already contained the element.

10
JavaSuck•

OP can also check the return value of the add method

boolean unique = Arrays.stream(theArray).allMatch(new HashSet<String>()::add);
1
Java_JuniorOP•

Thank you. I've been doing Java for almost a year and have never even heard of a Set, somehow. D'oh!

1
Firadine•

There are a lot of different Data Structures that are best in certain situations. Try to familiarize yourself with the concepts behind all of them and it will carry over to other languages as well. Learning to organize information correctly will have huge return on investment for time and code readability.

3
Java_JuniorOP•

I'll say.

I've worked with Lists, Arrays, ArrayLists, Hashmaps/Maps, Queues, Stacks, and I think that's it. I haven't done Trees. But I can't believe I've never even heard of Sets. I just looked in my main training book, Java: A Beginner's Guide by Herbert Schildt, and it's not even in here!

1
TyrSniper•

The best way would be to use the "contains" method from List and therefore ArrayList. (Turn your string array into an ArrayList)

Iterate over the list, and call list.contains(str)

10
[deleted]•

[deleted]

-9
toshels•

How about sets like user mentioned above ? What are pros and cons using this method instead the one above.

4
differentshade•

it works but is not the "correct way"

you are doing a O(n n) operation where it is not necessary

better use a set. a typical set is a hash set, so iterating over a list and checking existence of elements in a set is O(n log n)

but if you are using a set, then might as well just check set size to determine duplicates O(n) or check on adding to set if element already exists O(log n)

and no - it's not 'premature optimization' but just knowing the data structures and algorithms you use

4
[deleted]•

[deleted]

1
EquationTAKEN•

Don't imply that there's only one correct way.

The Set method is equally elegant, if not more so.

4
harapr•

This works but isn't efficient. List.contains is an O(n) operation - Needing to look at each entry in the List. Looking up a value in a HashSet is an O(1) operation - but has a one-time cost of creating the HashSet which is O(n) though since we need to add each element of the List to the Set.

2
jeremysimons•

You could also try using an arraylist....

2
codemamba8•

You can use indexOf and a loop to check each string's index in the array against indexOf. Because indexOf returns the index of the first instance of that value in the array, then if the current string in the loop has a different index than its indexOf, it must be a duplicate value.

2
-techno_viking-•

Maybe I'm missing something but why not just check if the array .contains the String before you add it? If it does return false else return true.

1
eignatik•

If the algorithm complexity matters then I would do it this way:

  1. put all the 31 strings into a Set;
  2. check an input string against the Set by invoking Set.contains that runs with O(1) complexity (constant time).

Another solution would be creating a enum class where you can define all you strings. This enum should also provide with a method “getByValue” that returns the enum object according to the given value. If there is no mapped value, it will return UNKNOWN for example. You can then check and handle it. But it very much depends on a concrete context. I don’t know much about those strings. If there might be even more strings, probably enum isn’t a good solution (which is even arguable when it comes to 31 values).

P.S.: List#contains runs with O(n) while Set#contains O(1) as it uses HashMap inside and checks the value by hashCode/equals as it’s stored as a hash map key.

1
nyawqabob•

use distinct method on array's stream if you wanna use list not set

-2
darklord1031•

That’s a lot of unnecessary overheard when you can use List#contains...

1
nutrecht•

List.contains is O(n) generally.

1
[deleted]•

[deleted]

-4
Vote4SovietBear•

I would use hashmap to keep track of string frequency for posterity, but if one is certain that that isn’t needed, a set is sufficient - just check if it exists.

1