Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #33478

Re: Stream FlatMap

Newsgroups comp.lang.java.programmer
Date 2016-01-19 04:12 -0800
References <39a5793c-6a65-4402-9c11-69667a03f11d@googlegroups.com> <n7k3mr$6pq$1@dont-email.me>
Message-ID <a3a0221a-a5e6-4e0d-9018-4aa770e3eeb5@googlegroups.com> (permalink)
Subject Re: Stream FlatMap
From Sebastian <sebastian.millies@softwareag.com>

Show all headers | View raw


Am Dienstag, 19. Januar 2016 02:35:11 UTC+1 schrieb Eric Sosman:
> On 1/18/2016 10:57 AM, Philipp Kraus wrote:
> > Hello,
> >
> > I have got a list like:
> >
> > List<?> x = [1,2, [4,5, ["a", "b"], "c", "d"], ["x", "y"], "z"];
> >
> > and I would like to flat this list into
> >
> > y = [1, 2, 4, 5, "a", "b", "c", "d", "x", "y", "z"]
> >
> > The list can store any object type so it can be a raw value or any collection typ (with recursion).
> > How can I flat this list with the streams?
> 
>      Got it!!!
> 
> import java.util.Arrays;
> import java.util.List;
> import java.util.stream.Collectors;
> import java.util.stream.Stream;
> 
> public class Foo {
> 
>     public static Stream<Object> flatten(Object thing) {
>        return (thing instanceof List)
>              ? ((List<Object>) thing).stream().flatMap((item) -> 
> flatten(item))
>              : Stream.of(thing);
>     }
> 
>     public static void main(String[] unused) {
>        List<?> list = Arrays.asList(
>              1,
>              2,
>              Arrays.asList(
>                    4,
>                    5,
>                    Arrays.asList("a", "b"),
>                    "c",
>                    "d"
>              ),
>              Arrays.asList("x", "y"),
>              "z"
>        );
> 
>        System.out.println(list);
>        System.out.println();
>        List<?> flattened = flatten(list).collect(Collectors.toList());
>        System.out.println(flattened);
>     }
> }
> 
> -- 
> esosman@comcast-dot-net.invalid
> "Don't be afraid of work. Make work afraid of you." -- TLM

Yes, that's a variant of the Rosetta solution: There solution differs from yours by having List in the signature and the instanceof check inside the flatMap. I like that better, because the signature already announces that only Lists can be flattened.

Here's a non-recursive solution that pushes the nested elements onto a stack:

public List<?> flattenNonRecursive(List<?> list) {
  List<Object> flattened = new ArrayList<>();
  Stack<Object> stack = new Stack<>();
  stack.pushAll(list);
  while (!stack.isEmpty()) {
    Object item = stack.pop();
    if (item instanceof List<?>) 
      stack.pushAll((List<?>) item);
    else 
      flattened.add(item);
  }
  return flattened;
}

static class Stack<T> extends ArrayDeque<T> {
  void pushAll(List<? extends T> ts) {
    ListIterator<? extends T> listIter = ts.listIterator(ts.size());
    while(listIter.hasPrevious()){
      push(listIter.previous());
    }
  }
}
  
-- Sebastian

Back to comp.lang.java.programmer | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Stream FlatMap Philipp Kraus <philipp.kraus.flashpixx@gmail.com> - 2016-01-18 07:57 -0800
  Re: Stream FlatMap Sebastian <news@seyweiler.dyndns.org> - 2016-01-18 23:11 +0100
    Re: Stream FlatMap Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-01-18 18:18 -0500
  Re: Stream FlatMap Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-01-18 20:34 -0500
    Re: Stream FlatMap Sebastian <sebastian.millies@softwareag.com> - 2016-01-19 04:12 -0800
      Re: Stream FlatMap Philipp Kraus <philipp.kraus.flashpixx@gmail.com> - 2016-01-19 12:15 -0800
        Re: Stream FlatMap Arne Vajhøj <arne@vajhoej.dk> - 2016-01-21 10:12 -0500

csiph-web