5

When streaming through List, how can I collect the output to a linked list?

I have tried the following:

public static void main(String[] args) {
    List<String> firstList = new ArrayList<>();
    firstList.add("pavan");
    firstList.add("kumar");
    LinkedList<String> filtered= new LinkedList<>();
    filtered = (LinkedList<String>) firstList.stream().filter(t->firstList.contains("p")).collect(Collectors.toList());
    System.out.println(filtered);        
}

But this is giving java.util.ArrayList cannot be cast to java.util.LinkedList.

Eran
  • 387,369
  • 54
  • 702
  • 768
nanpakal
  • 971
  • 3
  • 18
  • 37
  • Is there a special reason _why_ you need a `LinkedList` and cannot code against the `List` interface? – Mick Mnemonic Jul 18 '16 at 09:58
  • I wanted to use Deque interface methods implemented by LinkedList – nanpakal Jul 18 '16 at 10:01
  • Okay, it would then still be best to code against the interface and declare the variable as `Deque`. – Mick Mnemonic Jul 18 '16 at 10:03
  • How is that @MickMnemonic – nanpakal Jul 18 '16 at 10:04
  • Doing so would make it simpler to later on switch to another implementation (e.g. `ArrayDeque`, `ConcurrentLinkedDeque`, `LinkedBlockingDeque`). More reasons why it's a good idea, in general, in this post: [What does it mean to “program to an interface”?](http://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface) – Mick Mnemonic Jul 18 '16 at 10:07
  • I am asking about how to name variables like Deque and still code against Interface.Can you please explain – nanpakal Jul 18 '16 at 10:13
  • Use `Deque filtered=firstList.stream() .filter(t -> t.contains("p")) .collect(Collectors.toCollection(ArrayDeque::new));` Note that I replaced `LinkedList` with `ArrayDeque`, as there is really no use case for `LinkedList`, even if you need a `Deque`. Further, I replaced your filter expression with something, that is more likely matching your intention. – Holger Jul 18 '16 at 15:34

2 Answers2

21

collect(Collectors.toList()) returns a List. You can't assume which List implementation it will return.

Use Collectors.toCollection(), to specify the actual Collection (or List in your case) implementation you wish to collect the data into :

LinkedList<String> filtered =
    firstList.stream()
             .filter(t->firstList.contains("p"))
             .collect(Collectors.toCollection(LinkedList::new));
Eran
  • 387,369
  • 54
  • 702
  • 768
-1

Use constructor

 filtered = new LinkedList<String>(firstList.stream().filter(t->firstList.contains("p")).collect(Collectors.toList());

Linked list constructor takes Collection as argument so any return from asList() will be compatible

Shettyh
  • 1,188
  • 14
  • 27