2015-08-17 4 views
1

Мне нужно провести сравнение значений в списке следующего типа;Сравнение значений между двумя элементами списка того же списка

List<org.bson.Document> 

Данные представляют собой документ Bson с двумя парами ключ: значение (имя и оценка). Мне нужно пройти через этот список и удалить самый низкий из результатов, которые сделал каждый игрок в гольф. Итак, если Джо сыграл две игры, а в первой игре он набрал 72, а вторую игру он набрал 86, потому что это гольф и 86 - это нижний из двух очков, мне нужно удалить элемент из списка, у которого есть оценка 86. Затем он оставит только верхнюю из двух для каждого игрока в гольф и позволит мне сравнить только высокие баллы (более низкое числовое значение).

Каков наилучший способ сделать это с использованием любых новых возможностей Java 1.8 или, мне придется дублировать список, а затем сравнить элемент x в списке A с элементом x + 1 в списке B (после правильной сортировки), а имена равны?

+1

Является ли это список документов, или же документ содержит список? – WillShackleford

+0

Вы хотите сохранить только одну запись на игрока или все, кроме худшего для игрока? Или поставить его по-другому: ваш пример составляет около двух баллов за игрока, всегда ли это так, или вы можете переформулировать его для более чем двух баллов? – dfogni

ответ

0

Нужно ли использовать Список? Попробуйте использовать hashMap, таким образом вы можете проверить, существует ли игрок, который вы пытаетесь вставить в hashMap, и если да, вы смотрите его оценку, если это хуже, вы перезаписываете его. После этого вы должны получить hashMap игроков с наивысшим результатом.

EDIT: My bad .. Я не правильно прочитал ваш вопрос. Вы должны использовать тип данных bson.Document. В этом случае вы можете использовать treeSet и определить пользовательский компаратор, который вернет 0 (true), если два элемента (игроков) имеют одно и то же имя. Затем вы можете применить те же логики, что и в исходном ответе.

0

Я действительно не знаю об 1.8, но я бы просто сравнил записи в том же списке, не создавая второй. Я хотел бы сделать это следующим образом (псевдо-методов, я не знаю BSON):

for (int i=0; i<List.length;i++) { 
    int bestScore = List.getElementAt(i).getScore(); 
    int bestLocation = i; 
    String currname = List.getElementAt(i).getName(); 
    for (int j=i+1;i<List.length;j++) { 
     if (List.getElementAt(j).getName().equals(currname)) { 
      if (List.getElementAt(j).getScore()<bestScore) { 
       List.removeElementAt(bestLocation); 
       bestScore = List.getElementAt(j).getScore(); 
       bestLocation = j; 
      } else { 
       List.removeElementAt(j); 
       j--; 
      } 
     } 
    } 
} 

... или sortof. Подумайте, вы поняли мою идею. Возможно, вам придется искать ошибки, которые могут возникнуть, но я надеюсь, что смогу помочь вам в этой идее.

Кроме того, поскольку List.length изменяет это, возможно, не будет работать, но это может быть добавлено в код при его удалении.

0

Я не уверен с вашим вопросом. Но что я понял из описания, я бы рекомендовал вам использовать HasMap>.

Таким образом, вы сможете сортировать значение для каждого игрока и можете легко удалить самую низкую оценку!

0

Если вы знаете способ перебора всего документа для оценки, вы можете отсортировать список в порядке возрастания. После сортировки вы можете удалить последний элемент из списка. Существует несколько способов сортировки списков. Некоторые из основных - сортировка и сортировка Bubble.

Вы также можете найти индекс максимального значения и удалить этот элемент. Этот метод намного проще и эффективнее. Я также дам вам псевдокод для этого метода. В коде введите имя списка Array, назначенного вами.

int max = list.get(0); 
index = 0; 
for(int i = 1; i < list.size(); i++) 
{ 
if(list.get(i) > max) 
{ 
max = list.get(i); 
index = i; 
} 
} 
list.remove(i); 
1

Я не знаком с BSON так что моя попытка получить поток имя, оценка записей заключается в следующем:

List<org.bson.Document> ldoc = new ArrayList<>(); 
Stream<Entry<String, Integer>> s 
      = ldoc.stream() 
      .flatMap(d -> d.entrySet().stream()) 
      .map(e -> new AbstractMap.SimpleImmutableEntry<String,Integer>(e.getKey(),((Integer)e.getValue()))); 

Я создал поток непосредственно из списка.

List<Entry<String, Integer>> l = new ArrayList<>(); 
    l.add(new AbstractMap.SimpleImmutableEntry<>("Joe", 72)); 
    l.add(new AbstractMap.SimpleImmutableEntry<>("Joe", 66)); 
    l.add(new AbstractMap.SimpleImmutableEntry<>("John", 73)); 
    l.add(new AbstractMap.SimpleImmutableEntry<>("John", 86)); 
    l.add(new AbstractMap.SimpleImmutableEntry<>("John", 99)); 

Одна группа может и свести к минимуму в том же потоке, как это:

Map<String, Optional<Integer>> m = l.stream() 
      .collect(Collectors.groupingBy(e -> e.getKey(), 
          Collectors.mapping(e -> e.getValue(), 
            Collectors.minBy((i1, i2) -> Integer.compare(i1, i2))))); 
System.out.println("m = " + m); 

Это производит вывод:

m = {Joe=Optional[66], John=Optional[73]} 

То есть это карта каждого игрока низкий балл по имя.

Чтобы получить победитель:

String winner = m.entrySet() 
      .stream() 
      .min((e1, e2) -> Integer.compare(e1.getValue().get(), e2.getValue().get())) 
      .get().getKey(); 
System.out.println("winner = " + winner); 

который печатает:

winner = Joe 
Смежные вопросы