У меня есть 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]++;
});
Пожалуйста, отредактируйте в вопросе минимальный код, демонстрирующий, что вы уже пытались сделать.
@forpas ой, мой плохой.
@KevinO я добавил код
Ваш код чрезвычайно трудно читать, вероятно, и вам по нескольким причинам. Вы используете бессмысленные имена (строки arrayListSrc). Вы везде используете магические числа. Вы используете строки для представления целых чисел. Вы не должны иметь дело со List<String[]>. Вы должны иметь дело с List<Address>, где Address — это класс с городом, улицей, номером и счетчиком. Именование вещей и использование правильных типов значительно упрощает задачу.
Что представляют собой последние два числа в вашем массиве? @ВиталийКалмык
@ MS90 первое число - это номер улицы, а второе - количество
Я не думаю, что вы поняли причину замечания @forpas. Брэнфорд указан дважды с числом 3. Как обрабатывать записи с одинаковым числом для одного и того же города?




У меня было что-то вроде этого:
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]
Это тот результат, который вам нужен? У вас есть проблема, заключающаяся в том, что у вас есть записи с одинаковым количеством просмотров.
Да, именно этого результата я и добивался. Большое спасибо за ваше объяснение
@VitaliyKalmyk Пожалуйста, используйте кнопки «Принять ответ» и «Проголосовать за», чтобы передать это.
Прежде всего, попробуйте в следующий раз сопоставить свой 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));
});
Что ж, у вас правильный подход, но почему бы не внести его в список? @Глейнс
Почему бы и нет
Branford, Paddock Lane, 42, 3?