77

I would like to convert the string containing abc to a list of characters and a hashset of characters. How can I do that in Java ?

List<Character> charList = new ArrayList<Character>("abc".toCharArray());
user2418306
  • 2,352
  • 1
  • 22
  • 33
phoenix
  • 3,531
  • 9
  • 30
  • 31

12 Answers12

83

In Java8 you can use streams I suppose. List of Character objects:

List<Character> chars = str.chars()
    .mapToObj(e->(char)e).collect(Collectors.toList());

And set could be obtained in a similar way:

Set<Character> charsSet = str.chars()
    .mapToObj(e->(char)e).collect(Collectors.toSet());
Nestor Milyaev
  • 5,845
  • 2
  • 35
  • 51
waggledans
  • 1,231
  • 10
  • 7
59

You will have to either use a loop, or create a collection wrapper like Arrays.asList which works on primitive char arrays (or directly on strings).

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

Here is an Arrays.asList like wrapper for strings:

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

This one is an immutable list, though. If you want a mutable list, use this with a 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;
       }
    };
}

Analogous to this you can implement this for the other primitive types. Note that using this normally is not recommended, since for every access you would do a boxing and unboxing operation.

The Guava library contains similar List wrapper methods for several primitive array classes, like Chars.asList, and a wrapper for String in Lists.charactersOf(String).

Dom
  • 1,687
  • 6
  • 27
  • 37
Paŭlo Ebermann
  • 73,284
  • 20
  • 146
  • 210
37

The lack of a good way to convert between a primitive array and a collection of its corresponding wrapper type is solved by some third party libraries. Guava, a very common one, has a convenience method to do the conversion:

List<Character> characterList = Chars.asList("abc".toCharArray());
Set<Character> characterSet = new HashSet<Character>(characterList);
Mark Peters
  • 80,126
  • 17
  • 159
  • 190
  • 1
    Looks like I have reinvented the wheel here ... I suppose `Chars.asList` does about what the `asList` method in my answer does. – Paŭlo Ebermann Jun 12 '11 at 04:07
  • 8
    Also in Guava is `Lists.charactersOf("abc")` which is is a little shorter and doesn't make us call `toCharArray()` – Brad Cupit Jan 06 '14 at 18:45
17

Use a Java 8 Stream.

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

Breakdown:

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>

(I have absolutely no idea why String#chars() returns an IntStream.)

Salem
  • 13,516
  • 4
  • 51
  • 70
  • 2
    https://stackoverflow.com/questions/22435833/why-is-string-chars-a-stream-of-ints-in-java-8 – Saikat Oct 18 '18 at 04:50
9
List<String> result = Arrays.asList("abc".split(""));
Mathieu Allain
  • 339
  • 1
  • 4
  • 13
8

The most straightforward way is to use a for loop to add elements to a new List:

String abc = "abc";
List<Character> charList = new ArrayList<Character>();

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

Similarly, for a Set:

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

for (char c : abc.toCharArray()) {
  charSet.add(c);
}
coobird
  • 159,216
  • 35
  • 211
  • 226
4

Create an empty list of Character and then make a loop to get every character from the array and put them in the list one by one.

List<Character> characterList = new ArrayList<Character>();
char arrayChar[] = abc.toCharArray();
for (char aChar : arrayChar) 
{
    characterList.add(aChar); //  autoboxing 
}
Ricardo A.
  • 685
  • 2
  • 8
  • 35
Sai
  • 3,819
  • 1
  • 25
  • 28
1

You can do this without boxing if you use Eclipse Collections:

CharAdapter abc = Strings.asChars("abc");
CharList list = abc.toList();
CharSet set = abc.toSet();
CharBag bag = abc.toBag();

Because CharAdapter is an ImmutableCharList, calling collect on it will return an ImmutableList.

ImmutableList<Character> immutableList = abc.collect(Character::valueOf);

If you want to return a boxed List, Set or Bag of Character, the following will work:

LazyIterable<Character> lazyIterable = abc.asLazy().collect(Character::valueOf);
List<Character> list = lazyIterable.toList();
Set<Character> set = lazyIterable.toSet();
Bag<Character> set = lazyIterable.toBag();

Note: I am a committer for Eclipse Collections.

Donald Raab
  • 6,458
  • 2
  • 36
  • 44
1

Using Java 8 - Stream Funtion:

Converting A String into Character List:

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

Converting A Character List into String:

 String givenStringVariable =  characterList
                                            .stream()
                                            .map(String::valueOf)
                                            .collect(Collectors.joining())
Arpan Saini
  • 4,623
  • 1
  • 42
  • 50
0

IntStream can be used to access each character and add them to the list.

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

To get a list of Characters / Strings -

List<String> stringsOfCharacters = string.chars().
                                   mapToObj(i -> (char)i).
                                   map(c -> c.toString()).
                                   collect(Collectors.toList());
0

We can convert List of String into Set of characters as below.

Set<Character> charSet = new HashSet<>();
List<String> strList = List.of("abc", "cde", "def", "afc");
strList.forEach(str -> {
                charSet.addAll(str.chars()
                                  .mapToObj(c -> (char) c)
                                  .collect(Collectors.toSet()));
            });

Output will be something like this.

[a, b, c, d, e, f]
Abra
  • 19,142
  • 7
  • 29
  • 41