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]));