Znalezienie pięciu największych liczb w liście

Znalezienie pięciu największych liczb w liście
KA
  • Rejestracja:ponad 3 lata
  • Ostatnio:około 2 lata
  • Postów:27
0

Hej musze znaleźć 5 największych liczb z listy. List<Integer> może być różna np: wypełniona null-ami, może być pusta, może być za mało liczb, a może też być okey. Poniżej kod - jest okey da się go uprościć coś można ulepszyć jakieś wskazówki ?. Optional i .stream() wykorzystać. jak coś będzie nie tak to zwrócić psutą listę. Z góry dzięki

    List<Integer> firstList = new ArrayList<>();
    firstList.add(null);
    firstList.add(null);
    firstList.add(null);
    firstList.add(null);
    firstList.add(null);

    List<Integer> secondList = new ArrayList<>();
    secondList.add(23);
    secondList.add(null);
    secondList.add(222);
    secondList.add(17);

    List<Integer> thirdList = new ArrayList<>();
    thirdList.add(2);
    thirdList.add(null);
    thirdList.add(3);
    thirdList.add(3);
    thirdList.add(3);
    thirdList.add(3);
    thirdList.add(3);
    thirdList.add(3);

    List<Integer> emptyList = new ArrayList<>();

    System.out.println(fiveBigestNumber(firstList));
    System.out.println(fiveBigestNumber(secondList));
    System.out.println(fiveBigestNumber(thirdList));
    System.out.println(fiveBigestNumber(emptyList));


public static List<Integer> fiveBigestNumber(List<Integer> integerList) { //wywoałenie metody trialClassInteger , musi być >= 5 elementów jak nie to pusta lista
    return Optional.ofNullable(integerList)
            .map(Main2::trialClassInteger)
            .filter(data -> data.size() >= 5)
            .orElseGet(Collections::emptyList);

}

public static List<Integer> trialClassInteger(List<Integer> integerList) { // usuniecie nulli, od największej do najmniejszej, max 5 liczb i do listy 
    return integerList.stream()
            .filter(Objects::nonNull)
            .sorted(Comparator.reverseOrder())
            .limit(5)
            .collect(Collectors.toList());
}
}
edytowany 3x, ostatnio: Riddle
_13th_Dragon
zwrócić psutą listę - String psutaLista=""; return (List<Integer>)psutaLista;? :D
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 miesiące
1

Pierwsza część to można prościej:

Kopiuj
      List<Integer> firstList=Arrays.asList(null,null,null,null,null);
      List<Integer> secondList=Arrays.asList(23,null,222,17);
      List<Integer> thirdList=Arrays.asList(2,null,3,3,3,3,3,3);
      List<Integer> emptyList=Arrays.asList();

Natomiast w drugiej wg mnie jest błąd, bo nie zwróci ci tablicy większej niż 5 elementów, zaś w komentarzu widzę musi być >= 5 elementów


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
ZD
  • Rejestracja:około 3 lata
  • Ostatnio:ponad rok
  • Postów:2310
2

To ja się wypowiem nt dołu :)

Strasznie nierówny ten kod jest. Co jest twoje, a co pożyczone, ale bez kręcenia ?

Kopiuj
public static List<Integer> fiveBigestNumber(List<Integer> integerList) { //wywoałenie metody trialClassInteger , musi być >= 5 elementów jak nie to pusta lista
    return Optional.ofNullable(integerList)
            .map(Main2::trialClassInteger)
            .filter(data -> data.size() >= 5)
            .orElseGet(Collections::emptyList);

}

a) Z zadania nie wynika, ze argument listowy może być null (lista pusta to coś innego niż lista null), a tu idzie energia w sztuczne wytwarzanie Optionala
b) .map(Main2::trialClassInteger) no sorry, ale cały romantyzm upada w jednej chwili, jak widzę ten Main2 ... metoda w Main ... to tak jakby prawie nie metoda, to ani nie OOP, ani funkcyjne.
c) w konsekwencji (chyba) nie przemyślenia a), orElseGet jest warunkiem ustawionym na coś innego niż miało być


If you put a million monkeys at a million keyboards, one of them will eventually write a Java program - the rest of them will write Perl
ZD
Zwłaszcza, że drugą część nie zabezpieczasz Optionalem
KA
A czy nulla można uznać za wartość? Np. wynik działania 22, 12, 6, 7, null
LitwinWileński
  • Rejestracja:prawie 3 lata
  • Ostatnio:15 dni
  • Postów:734
1

nazwy!

KA
  • Rejestracja:ponad 3 lata
  • Ostatnio:około 2 lata
  • Postów:27
0
Kopiuj
List<Integer> list1 = Arrays.asList(2, 0, 3, 12, 122);
List<Integer> list2 = Arrays.asList(2, 0, 3, 122);
List<Integer> list3 = Arrays.asList();
List<Integer> list4 = Arrays.asList(null,null,null,null,null);
List<Integer> list5 = Arrays.asList(12,23,42,42,null,null,32);
System.out.println(integerList(list1));
System.out.println(integerList(list2));
System.out.println(integerList(list3));
System.out.println(integerList(list4));
System.out.println(integerList(list5));

      
public static List<Integer> integerList(List<Integer> integerList) {
    return Optional.ofNullable(integerList)
            .filter(data -> data.size() >= 5)
            .orElseGet(Collections::emptyList)
            .stream()
            .sorted(Comparator.reverseOrder())
            .limit(5)
            .collect(Collectors.toList());
}

Update kodu. Wszystko działa oprócz wyłapania nulli. Jak sobie z tym poradzić ? Lista jest opakowana w Optionala ale i tak nie chce pozbyć się tych nulli; Tak jakby wartość null przechodzą dalej do stream-a. Błąd:

Kopiuj
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.lang.Comparable.compareTo(Object)" because "c2" is null
edytowany 5x, ostatnio: Riddle
Tasmanian Devil
Twój post prawdopodobnie zawiera niesformatowany kod - nie wklejaj bezpośrednio kodu, ale obejmuj go w znaczniki kodu ```! (jestem botem, ten komentarz został dodany automatycznie) /cc @cerrato
LitwinWileński
orelseget nie potrzebujesz
Riddle
@KotAli: Osadzaj kod w znaczniki fragmentów kodu ```java oraz ```.
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 9 godzin
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
1

W treści zadania nie było, że lista może być nullem (było, że pusta, wypełniona nullami itp.).

Uważam, że przy podawaniu nulla jako argument należy zwracać odpowiednią informację, którą to jest NullPointerException. Co fajne - JVM sam to zrobi.
Chodzi o to, żeby nie robić nonsensowenych null checków (wpakowywanie w optionala (ofNullable) też pod to podchodzi).
Inaczej lądujemy z kodem, którego połowa to jakieś sprawdzanie nulli i trudno się przez ten szum przebija.

Oczywiście nie wszędzie można pomijać sprawdzanie null - np. jeśli input pochodzi z zewnątrz (front albo robimy bibliotekę) to wtedy na poziomie fasad takie nadmiarowe sprawdzanie null, walidacja ma jakiś sens.


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 1x, ostatnio: jarekr000000
KA
Okey rozumiem, a co jeśli w liście jakiś element będzie nulem a chciałbym aby program jednak zadziałał i nie wywalał NullPointerException ?
jarekr000000
To akurat było w treści zadania, że elementy mogą być nullami więc obsługujesz te nulle - nie ma pola do dyskusji. Mi chodzi tylko o sprawdzanie czy sama referencja list jest null. (a to jest niedoprecyzowane). Zresztą jak to na uczelnie to może sprawdź tego nulla :-) - wykładowcy często mają słabe pojęcie o temacie i powielają stare dyrdymały - a rypanie null checkami to kiedyś był w javie standard. (moje ulubione if (arg == null) return null; - totalna patola).
KA
  • Rejestracja:ponad 3 lata
  • Ostatnio:około 2 lata
  • Postów:27
0
Kopiuj
    public static void main(String[] args) {
        List<Integer> list1 = new ArrayList<>(Arrays.asList(2, 0, 3, 12, 122));
        List<Integer> list2 = new ArrayList<>(Arrays.asList(2, 0, 3, 122));
        List<Integer> list3 = new ArrayList<>(Arrays.asList(null, null, null, null, null, null));
        List<Integer> list4 = new ArrayList<>(Arrays.asList(null, null, 12, 23, 42, 32));

        System.out.println(integerList(list1));
        System.out.println(integerList(list2));
        System.out.println(integerList(list3));
        System.out.println(integerList(list4));
    }

    public static List<Integer> integerList(List<Integer> integerList) {
        List<Integer> collect = Optional.ofNullable(integerList)
                .filter(data -> data.size() >= 5)  //jeśli lista ma mniej niż 5 elementów to od razu emptyList;
                .orElseGet(Collections::emptyList) 
                .stream()
                .filter(Objects::nonNull) // wywalenie null-i
                .sorted(Comparator.reverseOrder()) //sortowanie od największej do najmniejszej 
                .limit(5) // tylko 5 elementów
                .collect(Collectors.toList()); // do zapisanie do listy
        
        if (collect.size() == 5) { // zabezpieczenie może być tak że jest (2,5,12,null,null) i wtedy przejdzie do streama 
                                      i bez tego wywaliłoby 3 elementy tylko na liście a potrzebujemy 5;
            return collect;
        } else {
            return new ArrayList<>();
        }
    }

result:
fiveBigesstNumber.PNG

Update: Można jeszcze bardziej poprawić/ulepszyć/skrócić ten kod ? Kod działa jednak czy można go ulepszyć ?

edytowany 1x, ostatnio: KotAli
Riddle
@KotAli: Możesz zaznaczyć fragment kodu i wcisnąć Shift+Tab, żeby usunąć niepotrzebne wcięcia.
K5
  • Rejestracja:około 6 lat
  • Ostatnio:dzień
  • Postów:1002
0
KotAli napisał(a):
Kopiuj
        
        if (collect.size() == 5) { // zabezpieczenie może być tak że jest (2,5,12,null,null) i wtedy przejdzie do streama 
                                      i bez tego wywaliłoby 3 elementy tylko na liście a potrzebujemy 5;
            return collect;
        } else {
            return new ArrayList<>();
        }
    }

Ta końcowka i to wytłumaczenie jest dziwne.
Czyli co, jak nie znaleźliśmy 5 liczb, tylko 3 bo lista wejściowa miała 3 elementy to wynikiem będzie pusta lista bo koniecznie musi być 5 liczb w rezultacie? To jest jakieś głupie.

edytowany 1x, ostatnio: kixe52
LitwinWileński
  • Rejestracja:prawie 3 lata
  • Ostatnio:15 dni
  • Postów:734
0

nie ifuj filtrem.
raz wyrzucasz Collections.emptyList() a raz new ArrayList<>()
skoro ma być min. 5 elementów nienullowych to daj ifa, żeby było min. 5 elementów nienulowych, a nie sprawdzasz to po 2 razy: najpierw czy min. 5 elementów i po obliczeniach jeszcze raz sprawdzasz czy nie ma mniej.

edytowany 2x, ostatnio: LitwinWileński
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 miesiące
0
Kopiuj
public class OptionalTest
{
   public static void main(String[] args)
   {
      List<List<Integer>> lists=Arrays.asList
      (
         Arrays.asList(2,0,3,12,122),
         Arrays.asList(2,0,3,122),
         Arrays.asList(null,null,null,null,null,null),
         Arrays.asList(3,null,null,12,23,42,32),
         Arrays.asList(null,null,12,23,42,32)
      );

      for(List<Integer> lst:lists) System.out.println(integerList(lst));
   }

   public static List<Integer> integerList(List<Integer> input)
   {
      //input=(input==null?Arrays.asList():input);
      input=input.stream().filter(Objects::nonNull).sorted(Comparator.reverseOrder()).limit(5).collect(Collectors.toList());
      return input.size()<5?Arrays.asList():input;
   }
}

W zasadzie wiersz 19 należy wywalić bo ma walić wyjątkiem przy null zamiast tablicy, zresztą @jarekr000000 ma takie same zdanie.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 3x, ostatnio: _13th_Dragon
W0
  • Rejestracja:ponad 12 lat
  • Ostatnio:około godziny
  • Postów:3551
1
KotAli napisał(a):
Kopiuj
    public static List<Integer> integerList(List<Integer> integerList) {
        List<Integer> collect = Optional.ofNullable(integerList)
                .filter(data -> data.size() >= 5)  //jeśli lista ma mniej niż 5 elementów to od razu emptyList;
                .orElseGet(Collections::emptyList) 
                .stream()
                .filter(Objects::nonNull) // wywalenie null-i
                .sorted(Comparator.reverseOrder()) //sortowanie od największej do najmniejszej 
                .limit(5) // tylko 5 elementów
                .collect(Collectors.toList()); // do zapisanie do listy
        
        if (collect.size() == 5) { // zabezpieczenie może być tak że jest (2,5,12,null,null) i wtedy przejdzie do streama 
                                      i bez tego wywaliłoby 3 elementy tylko na liście a potrzebujemy 5;
            return collect;
        } else {
            return new ArrayList<>();
        }
    }

Nie ma co bawić się w Optionala.

Kopiuj
List<Integer> result = Stream.of(integerList)
   .filter(Objects::nonNull)
   .flatMap(List::stream)
   .filter(Objects::nonNull)
   .sorted(Comparator.reverseOrder())
   .limit(5)
   .collect(Collectors.toList());

return result.size() < 5 ? Collections.emptyList() : result;
Zobacz pozostałe 16 komentarzy
W0
Wbrew temu co piszesz - mój przykład nie tworzy żadnych klas, a jedynie tworzy obiekty klas z biblioteki standardowej Javy. Stream API to żadna armata, bo tak jak napisałem - dobrze się sprawdza przy prostych przypadkach, przy dłuższych i bardziej skomplikowanych operacjach kolejne operatory albo muszą być zamykane w dodatkowe funkcje, albo trzeba faktycznie tworzyć nowe klasy, albo zostaniesz z kodem totalnie nieczytelnym.
_13th_Dragon
Mda, wykręcasz słowa, klasy się definiuje zaś jak się tworzy to obiekty klasy - normalny skrót myślowy stworzyć klasę => stworzyć obiekt tej klasy. Jeszcze raz (dla niezbyt rozgarniętych językowo) tworzysz 3 obiekty vs operator trójargumentowy. Jak nie dociera to stwórz test i sprawdź różnicę w czasie wykonania.
W0
Ogólnie - bardzo dawno nie słyszałem zwrotu "stwórz klasę" zamiast "stwórz obiekt" lub (częściej) "użyj klasy". Tak dawno, że nie pamiętam, czy kiedykolwiek się to zdarzyło. Natomiast nie rozumiem argumentu o wydajności - według mnie chodziło o to, by napisać prostszy, tj. czytelniejszy kod, a nie wydajniejszy. Ty sam zresztą pytałeś o to, czy coś jest dla mnie prostsze, nie wydajniejsze.
_13th_Dragon
Jak już tłumaczyłem "stwórz obiekt" jest skrótem myślowym zaś "użyj klasy" tu nie pasuje bo użycie klasy niekoniecznie się wiązy z jej stworzeniem. Powiem czy że jak dla kogoś istnieje coś czytelniejszego niż użycie jednego podstawowego operatora oznacza to tylko jedno - brak podstaw.
W0
Widzę, że poszło w poważne tony :D Skoro uważasz, że znajomość podstaw jest tożsama z myśleniem jak ty to ja więcej pytań mieć nie mogę :D
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)