2014-12-19 4 views
2

Рассмотрим список объектов пункта, где каждый элемент связан с целочисленным полем:Перечень объектов, которые имеют максимальное значение

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 

Я хочу, чтобы отфильтровать список с деталями, которые имеют максимальное значение. В этом случае, поскольку максимальное число равно 9, я получу {Item[3],Item[5],Item[9]}. Мой способ сделать это - сначала перебрать весь список, а затем сохранить максимальное значение (9), а затем повторить его и добавить элементы, которые имеют свое поле, равное 9, в новый список.

Но это много кода каждый раз, когда я хочу сделать что-то подобное, и не кажется очень эффективным. Есть ли лучший подход (с точки зрения эффективности или аккуратности)?

+1

'Arrays.max (Item)' получает ваше максимальное количество, что экономит много итераций (EDIT :) в вашем собственном коде. – Charlie

+0

Вам нужно сохранить порядок ввода? Вы можете сделать это за один проход, если нет (но это не будет аккуратно). –

+5

@Charlie Не 'Arrays.max()' выполняет повторение для вас? –

ответ

5

Я бы выбрал предметы за один раз.

Что-то вроде этого псевдокода:

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); 
    } 
} 
0

Просто быстрый код из моего сознания:

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

Позвольте мне знать, если это не работает!

+0

Не «обновляйте» строку «String» в цикле. Используйте 'StringBuilder'. –

+0

@ GáborBakos Fixed – Charlie

1

Вы могли бы сделать что-то вроде этого, я думаю, что

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); 
    } 
} 
1

Самый простой способ сделать это с помощью карты, содержащий номер и список индексов.

Map<int number, List<int index> > 

Итерация по списку обновления Максимальный & хранения его индекс.

-> если такое же максимальное значение выполнено снова, добавьте его индекс также в список.
-> если найден новый максимум, обновите номер с карты.

0

Многое можно сделать в одной строке с 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()); 

Примечание: Это мой код для класса Item

public class Item { 

    private int value; 

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

    public int getValue() { 
    return value; 
    } 
} 
Смежные вопросы