2

Consider an object list of Item where each item is associated with an integer field:

Item[0]->1
Item[1]->4
Item[2]->2
Item[3]->9
Item[4]->1
Item[5]->9
Item[6]->3
Item[7]->6
Item[8]->7
Item[9]->9

I want to filter out a list with the items that have the maximum value. In that case since the maximum number is 9, I will receive {Item[3],Item[5],Item[9]}. My way of doing this is having to iterate the whole list first, then store the maximum value (9) somewhere and then iterate it again and add the items which have their field equal to 9 to a new list.

But this is a lot of code everytime I want to do something similar, and doesn't seem very efficient. Is there a better approach (either in terms of efficiency or tidyness)?

ᴘᴀɴᴀʏɪᴏᴛɪs
  • 7,169
  • 9
  • 50
  • 81

5 Answers5

5

I'd probably select the items in one go.

Something like this pseudocode:

int max = Integer.MIN_VALUE;
Set<Item> maxItems = new LinkedHashSet<>();
for( Item item : items ) {
  //if the item has a greater value clear the set and set the new max value
  if( item.value > max ) {
    maxItems.clear();
    max = item.value;
  }   

  //due to the code above value should always be <= max here, so we just need to check ==
  if( item.value == max ) {
    maxItems.add( item );
  }
}
Thomas
  • 87,414
  • 12
  • 119
  • 157
1

You could do something like this I think

List<Integer> maxValues = new ArrayList<Integer>();
int max = Integer.MIN_VALUE;
for(int i = 0; i < item.length; i++) {
   if(item[i] > max) {
       max = item[i];
       maxValues = new ArrayList<Integer>();
   }

   if(item[i] == max) {
       maxValues.add(i);
   }
}
wastl
  • 2,643
  • 14
  • 27
1

Easiest way to do is using a Map containing the number and a List of indexes.

Map<int number, List<int index> >

Iterate through the list updating the Maximum & storing its index.

-> if same Maximum value is met again, add its index also to the list.
-> if new Maximum is found, update the number from the Map.

Vivek Vijayan
  • 337
  • 5
  • 19
0

Just a quick code from my mind:

int max=Arrays.max(Item);
StringBuilder sb=new StringBuilder();
for(int i=0; i<Item.length; i++) {
    if(Item[i]==max) {
        s.append(i+",");
    }
}
System.out.println(sb.toString());

Let me know if this doesn't work!

Charlie
  • 978
  • 1
  • 7
  • 27
0

A lot of things can be done in one single line with Java 8:

List<Item> items = ... //The logic is the same with an array.

//Get the max value.
int max = items.stream().mapToInt(Item::getValue).max().getAsInt();

//Filter items which have this max value.
List<Item> result = items.stream()
                    .filter(item -> item.getValue() == max)
                    .collect(Collectors.toList());

Note : This is my code for the class Item

public class Item {

  private int value;

  public Item(int value) {
    this.value = value;
  }

  public int getValue() {
    return value;
  }
}
Arnaud Denoyelle
  • 29,980
  • 16
  • 92
  • 148