CodeGym /Blog Java /Random-PL /Sortowanie kolekcji Java ()
Autor
Vasyl Malik
Senior Java Developer at CodeGym

Sortowanie kolekcji Java ()

Opublikowano w grupie Random-PL
Jedną z najczęstszych funkcji, których potrzebujemy jako programiści zajmujący się danymi, jest sortowanie — dzięki możliwości sortowania naszych danych możemy zoptymalizować nasze algorytmy, aby działały znacznie szybciej i znajdowały potrzebne dane w ułamku czasu, w jakim przyjąłby inaczej. W dzisiejszej lekcji omówimy kolekcje Java sort(). Jako szybki eksperyment myślowy: wyobraź sobie, że szukasz nazwiska na liście studentów uniwersytetu. W tej szkole mogą być dziesiątki tysięcy uczniów. Jeśli lista, którą otrzymałeś, nie była ułożona w porządku alfabetycznym, musiałbyś przejrzeć każdą stronę i bardzo uważnie przyjrzeć się, aby upewnić się, że nigdzie nie pominąłeś ani jednego nazwiska, aż w końcu znajdziesz nazwisko, którego szukasz. Z drugiej strony, jeśli lista była ułożona alfabetycznie, nie tylko musisz być mniej rygorystyczny w swoich poszukiwaniach, ale możesz łatwo przejść do sekcji listy z tą samą pierwszą literą i dalej przeskakiwać między stronami dużymi skokami, aż trafisz na osobę, której szukałeś. Im więcej danych przetwarzasz, tym ważniejsze jest, abyś używał ich tak skutecznie i wydajnie, jak to tylko możliwe. W tym artykule omówimy, jak sortować dowolną implementację List w Javie (w tym ArrayList) przy użyciu metody sortowania Collections.

Jak sortować ArrayList w Javie przy użyciu metody sortowania Java Collections

Porozmawiajmy o metodzie Java Collections.sort. Pakiet java.util zawiera wiele przydatnych narzędzi i pakietów, które są często używane przez programistów, w tym ArrayList. Załóżmy, że masz następujący prosty program:

import java.util.*;
import java.io.*;
class Main{
     public static void main(String[] args){
          List<String> colors = new ArrayList<String>();
          colors.add("Red    ");
          colors.add("Orange");
          colors.add("Green");
          colors.add("Blue");
    }
}
Chcesz mieć możliwość wydrukowania listy kolorów, ale w porządku alfabetycznym. Jak możesz to zrobić? Korzystając z java.util.Collections, sortowanie jest tak proste, jak jedna linijka:

Collections.sort(colors);
Ta-da! Twoja lista kolorów została teraz posortowana na miejscu. Gdybyś miał wydrukować listę jako taką:

System.out.println(colors);
Wtedy otrzymasz następujące dane wyjściowe:

[Blue, Green, Orange, Red]
Jakie to było łatwe?! Równie łatwo byłoby użyć Collections.sort() do sortowania w porządku rosnącym listy liczb całkowitych, liczb zmiennoprzecinkowych lub dowolnego innego prostego typu danych. Ale co, jeśli chcesz posortować w kolejności malejącej? Zdecydowanie są przypadki, w których ma to sens - wyobraź sobie, że masz listę wyników testu dla określonej klasy i chcesz dowiedzieć się, kto jest najlepszym uczniem. O wiele bardziej sensowne byłoby posortowanie listy w kolejności malejącej (najpierw najwyższe wyniki), tak aby odpowiedzi, których szukasz, znajdowały się na samej górze. Na szczęście metoda Collections.sort() jest nadpisywana opcjonalnym drugim parametrem, który umożliwia wykonanie następujących czynności:

sort(List l, Comparator c)
Ale co to jest komparator? Cóż, komparator to po prostu funkcja, która porównuje dwa dane wejściowe i zwraca liczbę reprezentującą to, które wejście jest pierwsze. Jeśli sortujesz ArrayList prymitywnych typów danych, to Java Collections zapewnia już komparator reverseOrder(). Można to nazwać tak:

Collections.sort(colors, Collections.reverseOrder());
Teraz kolory zostały odwrócone na miejscu, więc jeśli je wydrukujesz, otrzymasz następujący wynik:

[Red, Orange, Green, Blue]

Jak używać kolekcji do sortowania nieprymitywnych typów danych w Javie

Do tej pory przekonałeś się, że sortowanie ArrayLists ciągów znaków lub liczb typu int w Javie przy użyciu metody Collections.sort() jest tak proste, jak jedna linia kodu. Ale często twoje ArrayLists będą przechowywać nieprymitywne typy danych. Kiedy pracujesz z danymi, które mają bardziej złożone atrybuty, będziesz chciał napisać klasy reprezentujące te obiekty i sposób, w jaki będą one porównywane ze sobą przy użyciu ich atrybutów. Aby zbadać ten przykład, wróćmy do przykładu sortowania listy kolorów, ale tym razem zamiast sortowania łańcuchów będziemy sortować obiekty Color. Nasza podstawowa klasa Color może wyglądać mniej więcej tak:

public class Color{
	private int r;
	private int g;
	private int b;
	private String name;

	Color(String name, int red, int green, int blue){
   	this.name = name;
    	this.r = red;
   	this.g = green;
   	this.b = blue;
	}
}
Aby uczynić naszą klasę Color kompatybilną z Collections.sort(), tak aby Collections mogła zrozumieć, jak porównywać i sortować obiekty Color, musimy wprowadzić dwie małe modyfikacje:
  1. uczyń Color obiektem porównywalnym (dodaj narzędzia Comparable<Object>)
  2. zastąp metodę CompareTo w klasie (zastąp public int CompareTo(Object o))
Dzięki tym modyfikacjom nasza klasa wygląda teraz tak:

public class Color implements Comparable<Object>{
	private int r;
	private int g;
	private int b;
	private String name;

	Color(int red int green, int blue, String name){
    	this.r = red;
   	this.g = green;
   	this.b = blue;
   	this.name = name;
	}

	@Override
	public int compareTo(Object o) {
    	Color c = (Color) o;
    	return this.name.compareTo(c.name);
	}
}
Zauważ, że metoda CompareTo klasy Color po prostu wywołuje metodę CompareTo klasy String; sortowanie odbywa się w porządku alfabetycznym. Gdybyśmy na przykład chcieli posortować według wartości czerwonej w porządku rosnącym, moglibyśmy zastąpić instrukcję return instrukcją return this.r - cr; (gdybyśmy chcieli posortować malejąco według zielonej wartości, byłoby to return cg - this.g;). Teraz, jeśli zadzwonimy

Collections.sort(colors);
na ArrayList of Colours, a nie tylko Strings, zadziałałoby, ponieważ Collections rozumie, jak porównywać obiekty Color. Jeśli nie chcesz, aby Twój obiekt implementował Comparable<Object>, możesz alternatywnie napisać komparator dla swojej klasy i przekazać go do 2-parametrowej metody Collections.sort() . Komparator zastępuje metodę public int Compare(Object one, Object two), a metoda Collections.sort() używa jej do porównywania obiektów podczas sortowania. Poniżej zaimplementowano przykład komparatorów SortByName i SortByRed:

class SortByName implements Comparator<Color>
{
	public int compare(Color a, Color b)
	{
    	return a.name.compareTo(b.name);
	}
}

class SortByRGB implements Comparator<Color>
{
	public int compare(Color a, Color b)
	{
    	return a.r - b.r;
	}
}
Dzięki temu możesz teraz dzwonić

Collections.sort(colors, new SortByName());
bez klasy Color faktycznie implementującej Comparable i nadal będzie działać. Czasami zobaczysz, że robi się to w linii, używając funkcji lambda. Funkcja lambda jest zasadniczo bezimienną funkcją, którą można zdefiniować w wierszu kodu, który ją wywołuje. Są przydatne, gdy potrzebujesz wywołać funkcję tylko dla jednej konkretnej instancji i nie chcesz definiować całej oddzielnej funkcji w innym miejscu. Komparator SortByName można zdefiniować w linii, używając funkcji lambda, takiej jak ta:

Collections.sort(colors, (a, b)-> {
          return a.name.compareTo(b.name)});
Jak można się domyślić, (a, b) reprezentuje parametry funkcji lambda (dwa obiekty do porównania). Znak -> oznacza, że ​​następuje definicja funkcji lambda. O to chodzi! Poznałeś już najpopularniejsze metody sortowania ArrayLists w Javie przy użyciu pakietu Collections.
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION