5

How to collect a stream into a list that is a subtype that I specify?

In other words, I'd like this test to pass. What should I do on the commented line to convert a stream to a MyList instance?

import org.junit.*;
import java.util.*;
import static java.util.stream.Collectors.*;
import static junit.framework.Assert.*;

@Test
public void collectUsingDifferentListType() {
    List<String> aList = new ArrayList<>();
    aList.add("A");
    aList.add("B");
    List<String> list1 = aList.stream().collect(toList());
    MyList<String> list2 = aList.stream().collect(toList(MyList::new));  // this doesn't exist, but I wish it did

    assertEquals(aList, list1);
    assertEquals(ArrayList.class, list1.getClass());
    assertEquals(aList, list2);
    assertEquals(MyList.class, list1.getClass());
}
Tunaki
  • 132,869
  • 46
  • 340
  • 423
Garrett Smith
  • 688
  • 1
  • 7
  • 24
  • 1
    The first assertion is wrong. The returned list of `toList()` happens to be an `ArrayList` in Oracle’s current implementation, but there is no specification guaranteeing you this. On the other hand, the second assertion is not of much use, as the operation fails with a `ClassCastException` if `list2` is not of `MyType` much earlier (unless you consider the possibility of a spurious subclass creation)… and you have a copy&paste error there. – Holger Oct 23 '15 at 11:17

1 Answers1

11

Assuming the MyList type is a Collection, you can use Collectors.toCollection:

MyList<String> list2 = aList.stream().collect(toCollection(MyList::new));
Tunaki
  • 132,869
  • 46
  • 340
  • 423