Matthew Adams
Matthew Adams

Reputation: 2197

What's a more functional way in Java 8 of updating items in a list with their index?

Given:

  static class Item {
    String name;
    int index;

    Item(String name) {
      this.name = name;
    }
  }

  @Test
  public void test() {
    List<Item> items =
        Arrays.stream(new String[] {"z", "y", "x"})
          .map(Item::new)
          .collect(Collectors.toList());
    items.sort(Comparator.comparing(o -> o.name));

    // begin functionalize me    
    int i = 0;
    for (Item it : items) {
      it.index = i++;
    }
    // end functionalize me

    assertEquals(0, items.get(0).index);
    assertEquals(1, items.get(1).index);
    assertEquals(2, items.get(2).index);
  }

What is a more functional way in Java 8 of writing the code between the "functionalize me" comments? I was considering a strategy using reduce or collect, but can't quite see the solution in my head.

Upvotes: 0

Views: 53

Answers (1)

Holger
Holger

Reputation: 298153

You should not assume the list returned by Collectors.toList() to be mutable. Hence, you must not call sort on it. In your specific case, you can just sort before collecting:

List<Item> items = Stream.of("z", "y", "x")
  .map(Item::new)
  .sorted(Comparator.comparing(o -> o.name))
  .collect(Collectors.toList());

or, since name is identical to the incoming string:

List<Item> items = Stream.of("z", "y", "x")
  .sorted()
  .map(Item::new)
  .collect(Collectors.toList());

Then, you can update the list items using

IntStream.range(0, items.size()).forEach(i -> items.get(i).index = i);

Upvotes: 3

Related Questions