Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #33471 > unrolled thread
| Started by | Philipp Kraus <philipp.kraus.flashpixx@gmail.com> |
|---|---|
| First post | 2016-01-18 07:57 -0800 |
| Last post | 2016-01-21 10:12 -0500 |
| Articles | 7 — 5 participants |
Back to article view | Back to comp.lang.java.programmer
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
| From | Philipp Kraus <philipp.kraus.flashpixx@gmail.com> |
|---|---|
| Date | 2016-01-18 07:57 -0800 |
| Subject | Stream FlatMap |
| Message-ID | <39a5793c-6a65-4402-9c11-69667a03f11d@googlegroups.com> |
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? Thanks Phil
[toc] | [next] | [standalone]
| From | Sebastian <news@seyweiler.dyndns.org> |
|---|---|
| Date | 2016-01-18 23:11 +0100 |
| Message-ID | <n7jnv4$peu$1@news.albasani.net> |
| In reply to | #33471 |
Am 18.01.2016 18:29, schrieb Stefan Ram: > Philipp Kraus <philipp.kraus.flashpixx@gmail.com> writes: >> List<?> x = [1,2, [4,5, ["a", "b"], "c", "d"], ["x", "y"], "z"]; >> and I would like to flat this list into > > The verb is »to flatten«. > > The code does not compile: > > Main.java:38: error: illegal start of expression > List<?> x = [1,2, [4,5, ["a", "b"], "c", "d"], ["x", "y"], "z"]; > ^ > 1 error > Well, obviously the OP didn't intend that as a list literal, since Java does not have them, but as shorthand in pseudo-code. There's a solution at http://rosettacode.org/wiki/Flatten_a_list#Java It's ugly, does anyone see a way to avoid using instanceof? -- Sebastian
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2016-01-18 18:18 -0500 |
| Message-ID | <n7jrn9$qc7$1@dont-email.me> |
| In reply to | #33473 |
On 1/18/2016 5:11 PM, Sebastian wrote:
> Am 18.01.2016 18:29, schrieb Stefan Ram:
>> Philipp Kraus <philipp.kraus.flashpixx@gmail.com> writes:
>>> List<?> x = [1,2, [4,5, ["a", "b"], "c", "d"], ["x", "y"], "z"];
>>> and I would like to flat this list into
>>
>> The verb is »to flatten«.
>>
>> The code does not compile:
>>
>> Main.java:38: error: illegal start of expression
>> List<?> x = [1,2, [4,5, ["a", "b"], "c", "d"], ["x", "y"], "z"];
>> ^
>> 1 error
>>
>
> Well, obviously the OP didn't intend that as a list literal, since Java
> does not have them, but as shorthand in pseudo-code.
>
> There's a solution at
> http://rosettacode.org/wiki/Flatten_a_list#Java
>
> It's ugly, does anyone see a way to avoid using instanceof?
Since he needs to distinguish between "atoms" and things that
need to be flattened recursively, `instanceof' (or a reflective
equivalent) seems unavoidable.
--
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2016-01-18 20:34 -0500 |
| Message-ID | <n7k3mr$6pq$1@dont-email.me> |
| In reply to | #33471 |
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
[toc] | [prev] | [next] | [standalone]
| From | Sebastian <sebastian.millies@softwareag.com> |
|---|---|
| Date | 2016-01-19 04:12 -0800 |
| Message-ID | <a3a0221a-a5e6-4e0d-9018-4aa770e3eeb5@googlegroups.com> |
| In reply to | #33477 |
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
[toc] | [prev] | [next] | [standalone]
| From | Philipp Kraus <philipp.kraus.flashpixx@gmail.com> |
|---|---|
| Date | 2016-01-19 12:15 -0800 |
| Message-ID | <a9c0a5df-cfab-4bf0-90bb-c99d9573a72c@googlegroups.com> |
| In reply to | #33478 |
> 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.
Thanks for the code excerpt. I have modified this code:
public static Stream<Object> flattenToStream(List<?> list) {
return list.stream().flatMap(item ->
item instanceof List<?> ?
flattenToStream((List<?>)item) :
Stream.of(item));
}
for my system, so it works well with my term, atom structure :-)
Phil
[toc] | [prev] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2016-01-21 10:12 -0500 |
| Message-ID | <n7qshb$pp1$1@gioia.aioe.org> |
| In reply to | #33480 |
On 1/19/2016 3:15 PM, Philipp Kraus wrote:
> Thanks for the code excerpt. I have modified this code:
>
> public static Stream<Object> flattenToStream(List<?> list) {
> return list.stream().flatMap(item ->
> item instanceof List<?> ?
> flattenToStream((List<?>)item) :
> Stream.of(item));
> }
>
> for my system, so it works well with my term, atom structure :-)
Given the data structure then this is more or less how to do it.
There are a couple of variations.
I would do it like:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class SimpleFlatten {
public static Stream<?> flatten(Object o) {
return (o instanceof Collection<?>) ?
((Collection<?>)o).stream().flatMap(elm -> flatten(elm)) :
(o instanceof Object[]) ?
Arrays.stream((Object[])o).flatMap(elm -> flatten(elm)) :
Stream.of(o);
}
public static void main(String[] args) {
List<Object> all = new ArrayList<>();
all.add(1);
all.add("A");
List<Object> sublist = new ArrayList<>();
sublist.add(2);
sublist.add("B");
all.add(sublist);
List<Object> innerlist = new ArrayList<>();
innerlist.add(4);
Object[] subarray = new Object[] { 3, "C", innerlist };
all.add(subarray);
System.out.println(flatten(all).collect(Collectors.toList()));
}
}
But that is just me.
If you want to avoid the instanceof, then you will need to change the
data structure.
Example:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class OOFlatten {
public static abstract class Wrapper {
public abstract Stream<?> stream();
}
public static class ObjectWrapper extends Wrapper {
private Object v;
public ObjectWrapper(Object v) {
this.v = v;
}
@Override
public Stream<?> stream() {
return Stream.of(v);
}
}
public static class CollectionWrapper extends Wrapper {
private Collection<Wrapper> v;
public CollectionWrapper(Collection<Wrapper> v) {
this.v = v;
}
@Override
public Stream<?> stream() {
return v.stream().flatMap(o -> o.stream());
}
}
public static class ArrayWrapper extends Wrapper {
private Wrapper[] v;
public ArrayWrapper(Wrapper[] v) {
this.v = v;
}
@Override
public Stream<?> stream() {
return Arrays.stream(v).flatMap(o -> o.stream());
}
}
public static Stream<?> flatten(Wrapper o) {
return o.stream();
}
public static void main(String[] args) {
List<Wrapper> all = new ArrayList<>();
all.add(new ObjectWrapper(1));
all.add(new ObjectWrapper("A"));
List<Wrapper> sublist = new ArrayList<>();
sublist.add(new ObjectWrapper(2));
sublist.add(new ObjectWrapper("B"));
all.add(new CollectionWrapper(sublist));
List<Wrapper> innerlist = new ArrayList<>();
innerlist.add(new ObjectWrapper(4));
Wrapper[] subarray = new Wrapper[] { new ObjectWrapper(3), new
ObjectWrapper("C"), new CollectionWrapper(innerlist) };
all.add(new ArrayWrapper(subarray));
System.out.println(flatten(new
CollectionWrapper(all)).collect(Collectors.toList()));
}
}
Arne
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.java.programmer
csiph-web