Java集合:将字符串转换为字符列表

77

我想将包含abc的字符串转换为字符列表和字符哈希集。在Java中该如何实现?

List<Character> charList = new ArrayList<Character>("abc".toCharArray());
12个回答

83
在Java中,从Java 8开始,你可以使用流(streams)。 字符对象列表:
List<Character> chars = str.chars()
    .mapToObj(e->(char)e).collect(Collectors.toList());

而且可以以类似的方式获得设置。
Set<Character> charsSet = str.chars()
    .mapToObj(e->(char)e).collect(Collectors.toSet());

导入 java.util.stream.Collectors 是使这段代码片段正常工作所必需的。 - Andrea Gottardo
chars方法是在Java 9中引入的 - 在Java 8中不存在。 - Steve Chambers
@SteveChambers 在Java 8中,它确实存在于CharSequence上:https://docs.oracle.com/javase/8/docs/api/java/lang/CharSequence.html#chars-- - Unmitigated
@Unmitigated 啊,好观点。 - Steve Chambers

59

你将不得不使用循环或创建一个集合包装器(例如Arrays.asList),该包装器可用于原始字符数组(或直接用于字符串)。

List<Character> list = new ArrayList<Character>();
Set<Character> unique = new HashSet<Character>();
for(char c : "abc".toCharArray()) {
    list.add(c);
    unique.add(c);
}

这里是一个类似于Arrays.asList的字符串包装器:

public List<Character> asList(final String string) {
    return new AbstractList<Character>() {
       public int size() { return string.length(); }
       public Character get(int index) { return string.charAt(index); }
    };
}
这是一个不可变的列表。如果你需要可变的列表,可以使用带有char[]的这个:
public List<Character> asList(final char[] string) {
    return new AbstractList<Character>() {
       public int size() { return string.length; }
       public Character get(int index) { return string[index]; }
       public Character set(int index, Character newVal) {
          char old = string[index];
          string[index] = newVal;
          return old;
       }
    };
}
类似于这个,你可以为其他原始类型实现这个方法。 请注意,通常不建议使用此方法,因为每次访问都会进行装箱和拆箱操作。 Guava库 包含了一些基本数组类的 类似于列表包装方法,例如Chars.asList,还有一个用于字符串的包装器在 Lists.charactersOf(String) 中。

37

一些第三方库解决了将原始数组和其对应包装类型的集合之间进行转换的问题。其中一个非常常见的是Guava,它提供了一种方便的方法来进行转换:

List<Character> characterList = Chars.asList("abc".toCharArray());
Set<Character> characterSet = new HashSet<Character>(characterList);

1
貌似我在这里重复了已有的工作... 我想Chars.asList做的就是我答案中asList方法所做的事情。 - Paŭlo Ebermann
8
在Guava中还有Lists.charactersOf("abc"),它略微更短,并且不需要调用toCharArray() - Brad Cupit

17

使用Java 8 Stream

myString.chars().mapToObj(i -> (char) i).collect(Collectors.toList());

故障:

myString
    .chars() // Convert to an IntStream
    .mapToObj(i -> (char) i) // Convert int to char, which gets boxed to Character
    .collect(Collectors.toList()); // Collect in a List<Character>

我完全不知道为什么String#chars()会返回一个IntStream流。


2
https://dev59.com/JWEh5IYBdhLWcg3waC5t - Saikat

9
List<String> result = Arrays.asList("abc".split(""));

8
最直接的方法是使用一个 for 循环将元素添加到新的 List 中:
String abc = "abc";
List<Character> charList = new ArrayList<Character>();

for (char c : abc.toCharArray()) {
  charList.add(c);
}

同样,对于一个Set

String abc = "abc";
Set<Character> charSet = new HashSet<Character>();

for (char c : abc.toCharArray()) {
  charSet.add(c);
}

4
创建一个空的字符列表,然后循环获取数组中的每个字符,并逐一将它们放入列表中。
List<Character> characterList = new ArrayList<Character>();
char arrayChar[] = abc.toCharArray();
for (char aChar : arrayChar) 
{
    characterList.add(aChar); //  autoboxing 
}

1
如果您使用Eclipse Collections,则无需装箱即可完成此操作:
CharAdapter abc = Strings.asChars("abc");
CharList list = abc.toList();
CharSet set = abc.toSet();
CharBag bag = abc.toBag();

因为CharAdapter是一个ImmutableCharList,在其上调用collect将返回一个ImmutableList
ImmutableList<Character> immutableList = abc.collect(Character::valueOf);

如果你想要返回一个装箱的 ListSetBag,其中包含 Character,那么以下内容可用:
LazyIterable<Character> lazyIterable = abc.asLazy().collect(Character::valueOf);
List<Character> list = lazyIterable.toList();
Set<Character> set = lazyIterable.toSet();
Bag<Character> set = lazyIterable.toBag();

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


1

使用Java 8 - Stream功能:

将字符串转换为字符列表:

ArrayList<Character> characterList =  givenStringVariable
                                                         .chars()
                                                         .mapToObj(c-> (char)c)
                                                         .collect(collectors.toList());

将字符列表转换为字符串:

 String givenStringVariable =  characterList
                                            .stream()
                                            .map(String::valueOf)
                                            .collect(Collectors.joining())

0

IntStream 可以用于访问每个字符并将它们添加到列表中。

String str = "abc";
List<Character> charList = new ArrayList<>();
IntStream.range(0,str.length()).forEach(i -> charList.add(str.charAt(i)));

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