Как получить каждый массив строк с наибольшим числом и уникальным ключом?

У меня есть ArrayList<String[]>, который содержит следующие данные:

[Branford, Paddock Lane, 136, 1]
[Branford, Paddock Lane, 42, 3]
[Branford, Hartford Road, 117, 0]
[Branford, Hartford Road, 45, 3]
[McAlister, Sigourney Street, 103, 3]
[McAlister, Sigourney Street, 61, 1]
[McAlister, Stanford Street, 1, 3]
[McAlister, Stanford Street, 34, 4]
[Cypress Gardens, Route 115, 112, 12]
[Cypress Gardens, Park Road, 10, 4]
[Cypress Gardens, Park Road, 49, 4]
[Cypress Gardens, Old Farm Road, 28, 5]
[Cypress Gardens, Old Farm Road, 79, 3]
[Germfask, Exeter Court, 28, 7]
[Germfask, South Boulevard, 119, 6]
[Germfask, South Boulevard, 135, 3]
[Minford, Liberty Lane, 41, 3]
[Minford, Liberty Lane, 52, 4]
[Minford, State Street West, 103, 0]

Первый элемент каждого массива строк — это название города, а последний элемент — счетчик. Мне нужно извлечь данные, которые также будут содержать массив строк, но только с одним названием города и самым большим счетчиком. Например, для Branford результатом будет [Branford, Paddock Lane, 42, 3]. Как я могу извлечь эти данные только с помощью циклов forEach? Спасибо.

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

Вывод не такой, как ожидалось, так как он не содержит данных.

final int[] max = {Integer.parseInt(arrayListSrc.get(0)[3])};
ArrayList<String[]> arrayList = new ArrayList<>(1);
final int[] index = {0};
arrayListSrc.forEach(strings -> {
  if (strings[0].equals(arrayListSrc.get(index[0])[0])) {
    if (Integer.parseInt(strings[3]) < Integer.parseInt(arrayListSrc.get(index[0])[3])) {
      if (Integer.parseInt(arrayListSrc.get(index[0])[3]) > max[0]) {
        max[0] = Integer.parseInt(arrayListSrc.get(index[0])[3]);
        arrayList.add(strings);
      }
    }
  }
  index[0]++;
});

Почему бы и нет Branford, Paddock Lane, 42, 3?

forpas 23.03.2019 23:05

Пожалуйста, отредактируйте в вопросе минимальный код, демонстрирующий, что вы уже пытались сделать.

KevinO 23.03.2019 23:08

@forpas ой, мой плохой.

vcalmic 23.03.2019 23:15

@KevinO я добавил код

vcalmic 23.03.2019 23:20

Ваш код чрезвычайно трудно читать, вероятно, и вам по нескольким причинам. Вы используете бессмысленные имена (строки arrayListSrc). Вы везде используете магические числа. Вы используете строки для представления целых чисел. Вы не должны иметь дело со List<String[]>. Вы должны иметь дело с List<Address>, где Address — это класс с городом, улицей, номером и счетчиком. Именование вещей и использование правильных типов значительно упрощает задачу.

JB Nizet 23.03.2019 23:24

Что представляют собой последние два числа в вашем массиве? @ВиталийКалмык

MS90 23.03.2019 23:33

@ MS90 первое число - это номер улицы, а второе - количество

vcalmic 23.03.2019 23:51

Я не думаю, что вы поняли причину замечания @forpas. Брэнфорд указан дважды с числом 3. Как обрабатывать записи с одинаковым числом для одного и того же города?

pjanssen 24.03.2019 00:50
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
8
104
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

У меня было что-то вроде этого:

Map<String, String[]> result = new TreeMap<>();


for(String[] s : source) {
    if (!result.containsKey(s[0])){
        result.put(s[0], s);
    } else if (Integer.valueOf(result.get(s[0])[3]) < Integer.valueOf(s[3])) {
        result.put(s[0], s);
    }
}

for(String k : result.keySet()) {
    System.out.println(k + ": " + Arrays.toString(result.get(k)));
}

Это должно напечатать:

Branford: [Branford, Paddock Lane, 42, 3]
Cypress Gardens: [Cypress Gardens, Route 115, 112, 12]
Germfask: [Germfask, Exeter Court, 28, 7]
McAlister: [McAlister, Stanford Street, 34, 4]
Minford: [Minford, Liberty Lane, 52, 4]

Это тот результат, который вам нужен? У вас есть проблема, заключающаяся в том, что у вас есть записи с одинаковым количеством просмотров.

Да, именно этого результата я и добивался. Большое спасибо за ваше объяснение

vcalmic 24.03.2019 16:39

@VitaliyKalmyk Пожалуйста, используйте кнопки «Принять ответ» и «Проголосовать за», чтобы передать это.

pjanssen 25.03.2019 15:44

Прежде всего, попробуйте в следующий раз сопоставить свой String[] с подходящей структурой данных, так как с этим будет намного проще обращаться. Просто создайте подходящий класс, вот для чего предназначено объектно-ориентированное программирование.

Но, чтобы ответить на вопрос, вы можете нанести на карту равнину List<String[]> следующим образом:

Map<String, String[]> results = source.stream().collect(
        Collectors.toMap(s -> s[0], Function.identity(),
                BinaryOperator.maxBy(
                        Comparator.comparing(s -> Integer.valueOf(s[3])))));

Результатом является карта, где ключ представляет название города, а значение — исходное String[], максимальное значением счетчика. Это решение не требует использования forEach(), а требует потоковых операций для достижения ожидаемого результата.

Однако вы можете использовать forEach() для печати или дальнейшей обработки результатов:

results.forEach((s, strings) -> {
    System.out.println(s + " " + Arrays.toString(strings));
});

Что ж, у вас правильный подход, но почему бы не внести его в список? @Глейнс

MS90 24.03.2019 01:03

Другие вопросы по теме