1

I have an Arraylist of the Cells from an Excel sheet. I want to create subarraylists of size 50 from the Arraylist of Cells I actually have, beginning from the index of 1590 and ending with size()-700.

I want to get the highest number from every subarraylist and put it in the new Arraylist. in the new Arraylist there should be only the highest values of each subarraylist.

Input data is my Arraylist of Cells.

With this code I get more than 50 numbers and it's not always the highest value. Has anyone an idea?

This is my code:

int partitionSize = 50;

List<List<Cell>> partitions = new ArrayList<>();
List <Cell> high = new ArrayList();
Cell max = data.get(1590);

for (int i = 1590; i < data.size()-700; i += partitionSize) {
    partitions.add(data.subList(i, Math.min(i + partitionSize, data.size()-700)));
}

for (List<Cell> list : partitions) {
    for (int i = 1; i < list.size(); i++) {
        if (list.get(i).getNumericCellValue() > max.getNumericCellValue()) {
            max = list.get(i);
        }
        high.add(max);
    }
}
1
  • Hi, multiple community members took time to answer your question. Please consider acknowledging one with a check. Commented Feb 17, 2022 at 18:23

2 Answers 2

1

The list of partitions may be generated using IntStream::iterate:

int start = 1590;
int end = data.size() - 700;
int size = 50;
List<List<Cell>> partitions = IntStream
    .iterate(start, i -> i < end, i -> i + size) // IntStream
    .mapToObj(i -> data.subList(i, Math.min(i + size, end)))
    .collect(Collectors.toList())
;

Then the list of cells with maximal values can be retrieved as follows:

List<Cell> maxPerRange = partitions
    .stream() // Stream<List<Cell>>
    .map(list -> list.stream() // Stream<Cell>
                     .max(Comparator.comparing(Cell::getNumericCellValue))
                     .get()
    )
    .collect(Collectors.toList());

Similarly, the list of maximal values may be created without explicit splitting the input data in sublists, just by using the appropriate ranges similar to the nested loops:

List<Cell> maxPerRange = IntStream
    .iterate(start, i -> i < end, i -> i + size) // IntStream
    .mapToObj(i -> IntStream.range(i, Math.min(i + size, end))
            .mapToObj(data::get)
            .max(Comparator.comparing(Cell::getNumericCellValue))
            .get()
    )
    .collect(Collectors.toList());
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much it helps me a lot. It didnt know the IntStream API. I like both solutions, the last one its very compact and the first one also great!
This specific version of IntStream/Stream::iterate method was introduced in Java 9
0

You could take advantage of the Stream API.

For example:

List<List<Integer>> partitions = new ArrayList<>();
List<Integer> high = partitions.stream()
    .map(partition -> partition.stream().max(Integer::compareTo))
    .filter(Optional::isPresent)
    .map(Optional::get)
    .collect(Collectors.toList());

4 Comments

What should i do instead of Optional should i put the type instead of and isPresent? The Type of my Arraylist is Cell there is no compareTo method.
You would replace Integer::compareTo with a comparison method of two instances of Cell, but keep Optional::isPresent. I'm sorry, I should have considered: Is Java new to you?
Yes it is new to me, the comment uo p to yours helps me a lot, but thank you for your advice :)
@Nando94 Sorry, I am confused by your last comment. Did my solution work for you or do you need more assistance?