16

I have a string as follows:

"[Monday, Tuesday]"

I want to convert this string to a list of enums of type "Day". My "Day" enum is as follows:

public enum Day {
    Monday,Tuesday;
}

I obtained my input string by calling toString() on a List of "Day"s. As follows:

List<Day> days = new ArrayList<Day>();
days.add(Day.Monday);
days.add(Day.Tuesday);

String input = days.toString();

I know that I can parse the input string by commas and brackets. But, is there any efficient way to do this?

To repeat, I want to covert string to a list of enums.

** EDIT **

Question is not just about converting String to enum and vice versa. It involves lists and string parsing.

hrishikeshp19
  • 8,838
  • 26
  • 78
  • 141
  • And what have you tried so far? – Giovanni Botta Apr 15 '15 at 21:13
  • I don't think there's much to do but to remove the first and last character then split on `, `... – assylias Apr 15 '15 at 21:13
  • As I explained, I have tried parsing the input string by commas and brackets. But, I hope that there is a better way to do the same with less lines of code. – hrishikeshp19 Apr 15 '15 at 21:15
  • So your real concern is to improve the code rather than having an issue with it. Well then, you may post your question in codereview.stackexchange.com and wait for somebody there to provide comments. – Luiggi Mendoza Apr 15 '15 at 21:17
  • @GiovanniBotta: I know "a solution" to the problem. So, I am not aiming to solve the problem. I am aiming to solve this with less lines of code. Looking for "a better solution". – hrishikeshp19 Apr 15 '15 at 21:18
  • @riship89 do you *have* to "save" the enums as a String from `days.toString()`? You could simplify it a bit with, say, `String input = String.join(",", days);`, then parse back with `String[] enums = input.split(","); for (String e : enums) Day d = Day.valueOf(e);` ? – assylias Apr 15 '15 at 21:20
  • @LuiggiMendoza: I believe this question is well suited for just stackoverflow. – hrishikeshp19 Apr 15 '15 at 21:20
  • Well you need to tokenize the string and convert each token to an enum. That seems like the optimal solution to me and if you are wondering if there are utilities that do that, I don't think so. The business logic determines what to do if one (or more) of the tokens does not correspond to an enum value. – Giovanni Botta Apr 15 '15 at 21:20
  • You don't even post your code here, so it looks more like you can't do this. If you have code that already works and **want to improve it**, then the question **is not suited** for here. If you have a piece of code that works and need other ways to do it, then the question **is suited** for here. – Luiggi Mendoza Apr 15 '15 at 21:22
  • Yes, I want to know other ways to do it. I am not looking to improve my code. I simply want to know other ways. – hrishikeshp19 Apr 15 '15 at 21:23
  • If that's your real intent, at least provide your current code. – Luiggi Mendoza Apr 15 '15 at 21:25
  • Your question looks like [XY problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Why do you even need to parse string representing list of enums? Both `ArrayList` and `enum` are `Serializable` so you can save/load; send/receive them directly. – Pshemo Apr 15 '15 at 21:27
  • @Pshemo: that makes sense. I can just serialize and deserialize that list of enums. – hrishikeshp19 Apr 15 '15 at 21:29
  • @Pshemo: I did what you said. Instead of using toString(), I used serializer and deserializer. And it looks a lot better. If you post it, I can accept that. – hrishikeshp19 Apr 15 '15 at 21:40

3 Answers3

21

In case you use Java 8:

//assume your Day enum has more values
String string = "[Monday, Wednesday, Tuesday, Friday, Thursday]";
String stringWithNoBrackets = string.substring(1, string.length() - 1);
List<Days> days = Arrays.asList(stringWithNoBrackets.split(",\\s+"))
        .stream()
        .map(Days::valueOf)
        .collect(Collectors.toList());
System.out.println(days);

Also, we don't need to convert the array into a list, using less code:

List<Days> days2 = Arrays.stream(stringWithNoBrackets.split(",\\s+"))
    .map(Days::valueOf)
    .collect(Collectors.toList());
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
  • Thank you!, I used the following one in order to allow as much spaces as possible before and after the comma: List days2 = Arrays.stream(stringWithNoBrackets.split("\\s*,\\s*")) .map(Days::valueOf) .collect(Collectors.toList()); – Chris Sim Jul 22 '20 at 14:02
4

Your question doesn't really make much sense. If you want to send or store list of enums then you can simply serialize and deserialize it since ArrayList and each enum are Serializable.

Example:

List<Day> ofiginalList = new ArrayList<Day>();
ofiginalList.add(Day.Monday);
ofiginalList.add(Day.Tuesday);

ByteArrayOutputStream bout = new ByteArrayOutputStream();

ObjectOutput out = new ObjectOutputStream(bout);
out.writeObject(ofiginalList);

ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
ObjectInput in = new ObjectInputStream(bin);

List<Day> deserializedList = (List<Day>) in.readObject();
System.out.println(deserializedList);

Output: [Monday, Tuesday].

Pshemo
  • 122,468
  • 25
  • 185
  • 269
  • This looks much better. No need for toString(). Thank you! Although, I used ObjectMapper from jackson. – hrishikeshp19 Apr 15 '15 at 21:59
  • Which serialization tool you use is up to you. I just give example showing that it is possible to serialize/deserialize such list :) – Pshemo Apr 15 '15 at 21:59
1

You can try doing something like

List<Day> days = new ArrayList<>();
StringTokenizer tokenizer = new StringTokenizer("[Monday, Tuesday]", "[], ");
while (st.hasMoreTokens()) {
  String token = st.nextToken();
  days.add(Day.valueOf(Day.class, token));
}
Claudio
  • 1,848
  • 12
  • 26
  • *StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead.* from [javadoc](https://docs.oracle.com/javase/7/docs/api/java/util/StringTokenizer.html) – Luiggi Mendoza Apr 15 '15 at 21:25
  • Looks better! But I think StringTokenizer is legacy. – hrishikeshp19 Apr 15 '15 at 21:26
  • True, it is more or less deprecated. You can replace easily by a split with a regexp (and probably a substring before that to chop []). – Claudio Apr 15 '15 at 21:35