1

I have a string of space separated bits (1's and 0's) that I want to convert to an array of enums. Below is my effort so far.

This is the Enum class

enum Color { RED, GREEN }

Here is the conversion code.

Color[] colors = (Color[]) Arrays.stream(sc.nextLine().split("\\s"))
    .map(i -> {
         if (i.equals("0")) return Color.RED;
         else return Color.GREEN;
    })
    .toArray();

I am facing the following problems with this code:

  1. It uses type casting to change from an array of Objects to an array of Colors which may create runtime errors. I would like it very much if there was no type casting.

  2. The map function. I have searched here on StackOverflow on mapToObj to see if there is a way I can specify the return type of the map. I think it is safer when you specify that the map should return a Color object.

5
  • Very interesting! How do I specify it is a 0 or a 1 Commented Apr 8, 2020 at 16:54
  • How do you specify what is a 0 or a 1? Commented Apr 8, 2020 at 16:55
  • Yes. How do I tell Color which one it is Commented Apr 8, 2020 at 16:56
  • With your map function, as you do currently? Commented Apr 8, 2020 at 16:56
  • Like this: map(i -> i.toArray[i]) ? Commented Apr 8, 2020 at 16:57

2 Answers 2

4

To avoid the casting, pass parameter to toArray:

.toArray(Color[]::new)

This is the only change required.

There is no need to specify a return type for the map function. The fact that you're returning only instances of Color means its return type is Color.

Sign up to request clarification or add additional context in comments.

5 Comments

I think you should have kept the part about polyexpression. It was fascinating. And mind blowing
@GilbertS it wasn't actually correct, though. Method invocations aren't polyexpressions. The lambda and method reference are, just not the Stream.map(...) itself.
Okay, I don't understand what you just said, but I will research more. I know method references look like this: Color[]::new. But one thing I still can't figure out is why you said I should use: .toArray(new Color[0]). What is the 0 in the Color[] array. Is it always 0?
@GilbertS I got the API confused with Collections.toArray, which takes an array, rather than a method reference to construct a new instance of an array. The reason for zero is somewhat complicated (e.g. you could pass in a pre-sized array), but the current "best practice" is to use zero.
Ohh! The size. Gotcha. Although it doesn't work in practice. The IDE says: reason: no instance(s) of type variable(s) A exist so that Color[] conforms to IntFunction<A[]>
2

This is the way to go:

Color[] colors = Arrays.stream(sc.nextLine().split("\\s"))
    .map(i -> i.equals("0") ? Color.RED : Color.GREEN)
    .toArray(Color[]::new);

If you want to convert a Stream to an object array, you need to use Stream::toArray(IntFunction) method.

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.