Home > Back-end >  Java Lambda to map a List<Object[]> to a (x[0] -> increment from starting value) map
Java Lambda to map a List<Object[]> to a (x[0] -> increment from starting value) map

Time:11-03

I have a List<Object[]> events where [0] in each row is an ID that I need. Also I have an int startSeq which is a certain starting number.

I need to obtain a Map<Integer,Integer> where Event ID -> startSeq i where i is an increment by 1 from startSeq.

Example:

int startSeq = 6;
List<Object[]> events = dao.getEvents();
// ((Object[])events.get(0))[0] = 200676, ((Object[])events.get(1))[0] = 204561, ...
200676 -> 6
204561 -> 7
205156 -> 8

Problem: If I go with an IntStream option as the basis for my stream, I don't have a way to track the index of the List (key) in toMap:

Map<Integer,Integer> map = IntStream.range(startSeq, startSeq  events.size())
                                    .boxed().collect(Collectors.toMap(
                                                      x -> /* Can't track List, no relation to IntStream*/
                                                      Function.identity()))

If I go with the List Stream option as the basis, I can't track the sequential increment in the value of toMap:

Map<Integer,Integer> map = events.stream().collect(Collectors.toMap(
                                                      x -> (Integer)x[0], 
                                                      y -> /* How to relate i increment from startSeq? */)

CodePudding user response:

Use AtomicInteger:

AtomicInteger startSeq = new AtomicInteger(6);
Map<Integer, Integer> map = events
    .stream()
    .collect(Collectors.toMap(
        x -> (Integer)x[0], 
        x -> startSeq.getAndIncrement()
    ));

or int[]

int[] startSeq = {6};
Map<Integer, Integer> map = events
    .stream()
    .collect(Collectors.toMap(
        x -> (Integer)x[0], 
        x -> startSeq[0]  
    ));

CodePudding user response:

You can iterate over the range of (startSeq, startSeq events.size()) and substract startSeq from each index to map to list elements:

int startSeq = 6;
List<Object[]> events = List.of(new Object[]{200676,"foo"}, new Object[]{204561,"bar"}, new Object[]{205156,"baz"});

Map<Integer,Integer> map =
    IntStream.range(startSeq, startSeq   events.size())
             .mapToObj(i -> Map.entry((Integer)(events.get(i-startSeq)[0]), i))
             .collect(Collectors.toMap(Entry::getKey, Entry::getValue));

System.out.println(map);

If you need keep insertion order:

....
.collect(Collectors.toMap(Entry::getKey, Entry::getValue,(x, y) -> y, LinkedHashMap::new));

CodePudding user response:

One approach would be to do the following:

final int startSeq = 6;
final List<Object[]> events = List.of(new Object[] {1}, new Object[] {2}, new Object[] {3});
Map<Integer,Integer> map = IntStream.range(0, events.size())
                .boxed().collect(Collectors.toMap(i -> (Integer)events.get(i)[0], i -> startSeq   i));

Please note, this may work only if startSeq and events can be made final or member variables.

CodePudding user response:

You could do it like this. You may need to slightly alter how I dereferenced the event object you mentioned.

  • stream the indices for the array size
  • map the value and index to an array
  • then collect the values from the array and place in the map.
int startSeq = 6;
Map<Integer, Integer> map = IntStream.range(0, events.size())
        .mapToObj(i -> new int[] { (int)events.get(i)[0], i   startSeq })
        .collect(Collectors.toMap(arr -> arr[0],
                arr -> arr[1]));
  •  Tags:  
  • java
  • Related