在Java中将Set<Integer>转换为Set<String>

14

有没有一种简单的方法将 Set<Integer> 转换为 Set<String> 而不必遍历整个集合?


2
List类似:https://dev59.com/tnVD5IYBdhLWcg3wU56H#61663 - Tom Hawtin - tackline
10个回答

13

不,最好的方法是使用循环。

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

最好选择简单、相对快速、直接表达的方法。

(更新:) 在Java 8中,如果你想隐藏循环,可以使用Lambda表达式完成同样的事情。

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

或者,使用Streams:

Set<String> strs = ints.stream().map(Integer::toString).collect(toSet());

1
理论上,你的代码在调用 toString() 时可能会抛出 NullPointerException,因为 Set<T> 可以包含空值。 - Luke Hutteman
1
@Luke,出于这个原因,我更喜欢更短的""+integer ;) - Peter Lawrey
@PeterLawrey 与其处理大量额外的方法调用和一个新的StringBuilder,String.valueOf(integer)更快,并且具有与""+integer相同的结果。 - Cajunluke
@CajunLuke 尽管操作会更快,但开发人员需要做更多的工作。如果您关心速度,您不应该将整数作为字符串添加到HashSet中。您可能正在使用一个库,它将int[]包装起来以将int保存为原语类型。 - Peter Lawrey
@PeterLawrey 我从未想过用int[]来包装原始类型。我得记住这一点。 - Cajunluke
显示剩余6条评论

10
使用Java8流的map和collect能力:
 Set< String >  stringSet = 
   intSet.stream().map(e -> String.valueOf(e)).collect(Collectors.toSet());

6
不可以,你需要对每个整数进行格式化,并将其添加到字符串集合中。

2

如果您真的不想遍历整个集合,可以使用装饰器。


你能提供一个例子吗?我不熟悉装饰器的概念。 - Cajunluke
在这种情况下,你会如何应用装饰器模式? - Oliver Charlesworth
1
如果我们只是想让一个 Set<Integer> 看起来像一个 Set<String> 但不创建另一个集合(例如,如果只有一部分集合可能被检查),那么您可以创建 AbstractSet<String> 的子类,该子类将封装 Set<Integer> 并在各个方法中进行转换。 - Kathy Van Stone
这取决于Mat的需求。对于单一需求(函数),我可能会创建一个简单的对象,其中包含设置并实现所需的函数。对于多个需求,我可能会选择另一种解决方案 :) - VirtualTroll

2

1
据我所知,您必须遍历集合;特别是当涉及到不自然的转换时。例如,如果您想将Set-Timestamp转换为Set-Date,可以使用Java泛型的某些组合来实现(因为Timestamp可以强制转换为Date)。但是由于Integer无法转换为String,因此您需要进行迭代。

可能有人不同意“否定”的答案,认为包装器/装饰器是更好的答案。 - Isaac Truett

1
你可以自己实现一个 Set<String>,并在需要时进行必要的转换,同时将所有调用重定向到原始集合。根据集合的使用方式,这种方法可能表现得更好或更差。

1
使用Java 8与Eclipse Collections
Set<String> strings = IntSets.mutable.with(1, 2, 3).collect(String::valueOf);

这不需要将 int 值和 Integer 装箱,但如果需要,也可以这样做:
Set<String> strings = Sets.mutable.with(1, 2, 3).collect(String::valueOf);

Sets.mutable.with(1, 2, 3)将返回一个MutableSet<Integer>,而不像IntSets.mutable.with(1, 2, 3)会返回一个MutableIntSet

注意:我是Eclipse Collections的提交者。


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;
 }

0

Java 7 + Guava(可能无法切换到Java 8)。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接