15

Is there a simple way to convert Set<Integer> to Set<String> without iterating through the entire set?

1

10 Answers 10

14

No. The best way is a loop.

HashSet<String> strs = new HashSet<String>(ints.size());
for(Integer integer : ints) {
  strs.add(integer.toString());
}

Something simple and relatively quick that is straightforward and expressive is probably best.

(Update:) In Java 8, the same thing can be done with a lambda expression if you'd like to hide the loop.

HashSet<String> strs = new HashSet<>(ints.size());
ints.forEach(i -> strs.add(i.toString()));

or, using Streams,

Set<String> strs = ints.stream().map(Integer::toString).collect(toSet());
Sign up to request clarification or add additional context in comments.

11 Comments

Perhaps you meant toString instead of stringValue ;)
@Peter That indeed I did. I must have been thinking of Integer's .intValue().
Theoretically, your code could throw a NullPointerException in the call to toString() as a Set<T> can contain a null value.
@Luke True, but, as this is an example, handling it would be unimportant and, honestly, I wouldn't handle it even in production code until it proved to be an issue. Why bother if you know the input set won't have any nulls?
@Luke, For this reason I prefer the shorter ""+integer ;)
|
10

use Java8 stream map and collect abilities:

 Set< String >  stringSet = 
   intSet.stream().map(e -> String.valueOf(e)).collect(Collectors.toSet());

Comments

6

No. You have to format each integer and add it to your string set.

Comments

2

You can use a decorator if you really don't want to iterate through the entire set

4 Comments

Can you provide an example? I'm not familiar with the concept of decorators.
How would you apply the decorator pattern in this scenario?
If we just wanted a Set<Integer> to look like a Set<String> but not create another set (say if only a fraction of the set is likely to be checked) you would create a subclass of AbstractSet<String> that would wrap the Set<Integer> and do the conversions in individual methods.
Well it would depends on Mat needs. For a single need (function), i will probably create a simple object containing the set and implementing my required function. For more than one need, I will probably choose another solution :)
2

You could use Commons Collections' TransformedSet or Guava's Collections2.transform(...)

In both cases, your functor would presumably simply call the Integer's toString().

Comments

1

You could implement Set<String> yourself and redirect all calls to the original set taking care of the necessary conversions only when needed. Depending on how the set is used that might perform significantly better or significantly worse.

Comments

1

AFAIK, you have to iterate through the collection; especially when there is a conversion involved that isn't natural. i.e. if you were trying to convert from Set-Timestamp- to Set-Date-; you could achieve that using some combination of Java Generics (since Timestamp can be cast to Date). But since Integer can't be cast to String, you will need to iterate.

1 Comment

Presumably, someone disagreed with the "no" answers and feels that a wrapper/decorator is a better answer.
1

Using Eclipse Collections with Java 8:

Set<String> strings = IntSets.mutable.with(1, 2, 3).collect(String::valueOf);

This doesn't require boxing the int values and Integer, but you can do that as well if required:

Set<String> strings = Sets.mutable.with(1, 2, 3).collect(String::valueOf);

Sets.mutable.with(1, 2, 3) will return a MutableSet<Integer>, unlike IntSets.mutable.with(1, 2, 3) which will return a MutableIntSet.

Note: I am a committer for Eclipse Collections.

Comments

0
private static <T> Set<T> toSet(Set<?> set) {
    Set<T> setOfType = new HashSet<>(set.size());
    set.forEach(ele -> {
        setOfType.add((T) ele);
    });
    return setOfType;
 }

Comments

0

Java 7 + Guava (presumably no way to switch to Java 8).

new HashSet<>(Collections2.transform(<your set of Integers>, Functions.toStringFunction()))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.