0

I've got two vavr Lists:

List<Object> list1 = List.of("one", "two", "three", "for");
List<Object> list2 = List.of("one", "two", List.of("three", "for"));

How can I transform the list2 to be equal to the list1?

EDIT

I try to explain more what I want to achive:

System.out.println("list1: " + list1);
System.out.println("list2: " + list2);

Output:

list1: List(one, two, three, for)
list2: List(one, two, List(three, for))

I want to flattening all inner lists in the list2, so the flattened list should be equal to list1:

System.out.println("flattened: " + flattened);
System.out.println(list1.equals(flattened));

Should return:

flattened: List(one, two, three, for)
true
kojot
  • 1,634
  • 2
  • 16
  • 32
  • 1
    Have you tried anything? – Michael Feb 05 '19 at 10:17
  • Sure, I tried `map`, `flatMap` and `transform`, but I can't make it work. – kojot Feb 05 '19 at 10:17
  • 4
    Your requirement are unclear. **You** have to first clarify how you *want* things to become equal. Is it ONLY about flattening **all** inner lists, or just the first one you find? You see: when you call `removeAll` for both lists, they are equal, too. – GhostCat Feb 05 '19 at 10:20
  • I want to flattening all inner lists, so the `list1.equals(list2)` should return true. – kojot Feb 05 '19 at 10:23

2 Answers2

5

You can use a Stream with flatMap:

List<Object> flattened =
    list2.stream()
         .flatMap(e -> ((e instanceof List) ? ((List<Object>)e).stream() : Stream.of(e)))
         .collect(Collectors.toList());
System.out.println(flattened);
System.out.println(list1.equals(flattened));

Outputs:

[one, two, three, four]
true

EDIT:

Since the OP is using a different List, here is a similar solution for io.vavr.collection.List:

List<Object> flattened =
    list2.toStream()
         .flatMap(e -> ((e instanceof List) ? ((List<Object>)e).toStream() : Stream.of(e)))
         .collect(List.collector());
Eran
  • 387,369
  • 54
  • 702
  • 768
  • Note that I use vavr, so I don't have `stream()` method on the `list2` object. – kojot Feb 05 '19 at 10:28
  • @kojot your use of `List.of` suggests you are using Java 9 or higher, so you should have Streams. – Eran Feb 05 '19 at 10:29
  • 1
    Yes I do, but the `list2` is not the `java.util.List`, it's `io.vavr.collection.List` – kojot Feb 05 '19 at 10:31
  • @kojot Maybe not really related, but why are you using vavr in the first place? – Lino Feb 05 '19 at 10:32
  • @Lino I've got Spring Webflux project. Vavr got not mutable collections, so they are thread safe. – kojot Feb 05 '19 at 10:35
  • 1
    @kojot why not use the immutable collections from the JDK? Java-9 introduced immutable collections like vavr with `List.of()` – Lino Feb 05 '19 at 10:37
  • @Eran please correct your answer to: `List flattened = list2.toStream() .flatMap(e -> ((e instanceof List) ? ((List)e).toStream() : Stream.of(e))) .collect(List.collector());` so I could mark it as correct. – kojot Feb 05 '19 at 11:21
  • @kojot are those the method names for `io.vavr.collection.List`? OK, I'll add that – Eran Feb 05 '19 at 11:27
  • @Lino With vavr I'm pretty sure that all of collections are immutable, so I can avoid side effects like `List newList = Collections.unmodifiableList(oldList); oldList.add("why this change newList too?");` There are some advantage too, like Persistent Data Structures, Validation and some useful methods. – kojot Feb 05 '19 at 12:25
  • @lino The JDK immutable collections are badly designed. Half their methods will throw a runtime exception, how is that helpful to write safe code? Vavr collections are immutable by design, and don't suffer the JDK List API which is assumed to be mutable. Every operation returns a new list, there's no exception, and no mutation. – Sir4ur0n Feb 09 '19 at 22:29
2

With Vavr you don't need all the stream/collect boilerplate of the JDK:

List<Object> result = list2.flatMap(o -> o instanceof List ? ((List) o) : List.of(o));
Sir4ur0n
  • 1,753
  • 1
  • 13
  • 24