2

I am trying to instantiate an array by using lambda expressions.

the code I am trying to use is:

public class Main {

    static int x = 0;

    public static void main(String[] args) {

        Test[] t = (Test[]) Stream
                .generate(() -> new Test(x++, 0))
                .limit(10)
                .map((Test v) -> {
                    v.a = v.a * 2;
                    return v;
                }) 
        );

the class I am trying to instantiate is called Test:

public class Test {

int a, b;

 Test(int a, int b) {
    this.a = a;
    this.b = b;
 }
}

I can not perform the cast, it raises an exception:

java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Lperson.Test; at person.Main.main(Main.java:37) Java returned: 1

But if you look at the object classes:

The array is a "[Ljava.lang.Object;" instance

//class "[Ljava.lang.Object;"
        System.out.println(
                Stream.generate(() -> new Test(x++, 0))
                .limit(10)
                .map((Test v) -> {
                    v.a = v.a * 2;
                    return v;
                })
                .toArray().getClass()                
        );

Each object of the array is a "Test" instance

//class "Test"
        System.out.println(
                Stream.generate(() -> new Test(x++, 0))
                .limit(10)
                .map((Test v) -> {
                    v.a = v.a * 2;
                    return v;
                })
                .toArray()[0].getClass()                
        );
David Marciel
  • 865
  • 1
  • 12
  • 29
  • 2
    `Test[]` is not related to `Object[]`: you can't cast between the two. Also, note that `.toArray()` always returns `Object[]`. – Andy Turner Apr 28 '16 at 07:55
  • 2
    Related: http://stackoverflow.com/questions/5690351/java-stringlist-toarray-gives-classcastexception – Alexis C. Apr 28 '16 at 07:57
  • 2
    Besides your main issue, you should note that `Stream.generate` creates an *unordered* stream which happens to do what you intent with a sequential stream, but doesn’t guaranty so. Further, abusing `map` to modify the object is a discouraged programming style… – Holger Apr 28 '16 at 08:29
  • 1
    Better: `Test[] t = new Test[10]; Arrays.setAll(t, ix -> new Test(ix, 0)); for(Test v: t) v.a = v.a * 2;` – Holger Apr 28 '16 at 08:31

1 Answers1

7

You can't just cast a stream and expect it to become an array.

Use the A[] toArray(IntFunction generator) method.

    Test[] a = Stream.generate(() -> new Test(x++, 0))
            .limit(10)
            .map((Test v) -> {
                v.a = v.a * 2;
                return v;
            })
            .toArray(Test[]::new);
OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213