Mam Listę, która przechowuje różne liczby, maksimum z nich to elementy pod indeksami: 2; 4. Chcę wydrukować te 2 elementy do konsoli - jako maksymalne liczby w tablicy, ale ...

3
Arina Aznauryan 23 czerwiec 2021, 10:06

5 odpowiedzi

Najlepsza odpowiedź

Nie ma domyślnie żadnej funkcji, która to robi. Możesz więc przefiltrować tę listę pod kątem podanej wartości. Spowoduje to 2 iteracje, ale będzie prosty w kodzie. Jeśli robisz to we własnej pętli, to jest to bardziej kod, ale bardziej wydajne.

W zależności od ilości danych należy wybrać sposób efektywny lub czytelny.

// 2 iterations - 1st for finding max , 2nd for filter
int maxValue = Collections.max(numbers);
List<Integer> maxValues = numbers.stream().filter(number -> number == max).collect(Collectors.toList()); // only need size? Add .size() at the end

// efficient - just 1 iteration, but not pretty to read.
int currentMax = numbers[0];
int counter = 0;
for(Integer number in numbers) {
    if(currentMax == number) {
        counter++;
    } else if(currentMax < number) {
        counter = 1;
        currentMax = number;
    }
}
2
LenglBoy 23 czerwiec 2021, 07:25

To wykorzystuje jedną iterację, aby je znaleźć

List<Integer> numbers = new ArrayList<Integer>();
    numbers.add(5);
    numbers.add(9);
    numbers.add(50);
    numbers.add(12);
    numbers.add(50);
    int max = Integer.MIN_VALUE;
    int count = 1;
    for(int number : numbers){
        if(number > max){
            max = number;
            count = 1;
        } else if(number == max){
            count++;
        }
    }
    for(int i=0; i<count; i++){
        System.out.println(max);
    }
3
Roophie 23 czerwiec 2021, 07:19

max zawsze znajdzie maksymalną wartość, a nie zdarzenia. To, czego chcesz, zawsze musi być zrobione w 2 krokach.

// If you start from a List
List<Integer> numbers = Arrays.asList(5, 9, 50, 12, 50);
IntSummaryStatistics numberStats = numbers.stream().collect(Collectors.summarizingInt(Integer::intValue));
numbers.stream().filter(number -> number == numberStats.getMax()).forEach(System.out::println);

// But you can also start from the stream itself
IntSummaryStatistics numberStats = IntStream.of(5, 9, 50, 12, 50).summaryStatistics();
numbers.stream().filter(number -> number == numberStats.getMax()).forEach(System.out::println);

/*
 * You can also use the plain max number instead of the summaryStatistics, which is 
 * more performant but the stream cannot be reuse for e.g. min or average.
 * Note here we use equals because we don't use primitive int but Object Integer as it's not an IntSteam
 */
Integer maxInt = numbers.stream().max(Comparator.naturalOrder()).orElseThrow();
numbers.stream().filter(number -> number.equals(maxInt)).forEach(System.out::println);

Comparator.naturalOrder() oznacza, że ​​nie dostarczasz komparatora, ale pozwalasz Javie używać domyślnego komparatora, który ma dla wszystkich prymitywów, prymitywów w ramkach i łańcuchów. Sortowanie słów i liczb jest rzeczą naturalną, dobrze znaną i niewymagającą implementacji.

2
Nico Van Belle 23 czerwiec 2021, 07:36

Możesz najpierw przejść przez listę w pętli, aby znaleźć maksymalną wartość, a następnie ponownie zapętlić listę, aby umieścić maksymalną wartość i ich indeks na mapie.

    Map map = new HashMap();
    int curMax = 0;
    for (int i = 0; i < numbers.size(); i++) {
        if (numbers.get(i)>=curMax){
            curMax = numbers.get(i);
        }
    }
    for (int i = 0; i < numbers.size(); i++) {
        if (numbers.get(i) == curMax){
            map.put(i, numbers.get(i));
        }
    }

    System.out.println(map.toString());

Wynik:

{2}=50, 4=50}

1
Chengjun Guo 23 czerwiec 2021, 07:35

maksymalne elementy znajdziesz na podnoszenie najpierw wartości całkowitych do listy i zmniejszanie tej listy:

    List<Integer> max = numbers.stream()
        .collect(Collectors.reducing(
            Collections.singletonList(Integer.MIN_VALUE),
            Collections::singletonList,
            (l1, l2) -> {
                if (l1.get(0) > l2.get(0)) {
                    return l1;
                } else if (l2.get(0) > l1.get(0)) {
                    return l2;
                } else {
                    List<Integer> l = new ArrayList<>(l1);
                    l.addAll(l2);
                    return l;
                }
            }));
1
michid 24 czerwiec 2021, 08:40