JavaRush /Java Blog /Random-TK /Java-da deňeşdiriji
Viacheslav
Dereje

Java-da deňeşdiriji

Toparda çap edildi
Diňe ýalta adamlar Java-da Deňeşdiriji we deňeşdirme hakda ýazmadylar. Men ýalta däl - şonuň üçin ýene bir üýtgeşikligi söýmegiňizi we goldamagyňyzy haýyş edýärin. Artykmaç bolmaz diýip umyt edýärin. Hawa, bu makala: "memoryadyndan deňeşdiriji ýazyp bilersiňizmi?" Diýen soraga jogap. Bu makalany okanyňyzdan soň, her kim ýatdan bir deňeşdiriji ýazyp biler diýip umyt edýärin.
Java-da deňeşdiriji - 1
Giriş Java obýekte gönükdirilen dil hökmünde bilinýär. Netijede, Java-da obýektler bilen işlemek adaty zat. Emma iru-giç obýektleri haýsydyr bir prinsip boýunça deňeşdirmek meselesi ýüze çykýar. Şeýlelikde, berlen: Habar synpy bilen düşündirilýän käbir habarymyz bar:
public static class Message {
    private String message;
    private int id;

    public Message(String message) {
        this.message = message;
        this.id = new Random().nextInt(1000);
    }
    public String getMessage() {
        return message;
    }
    public Integer getId() {
        return id;
    }
    public String toString() {
        return "[" + id + "] " + message;
    }
}
Geliň, bu synpy Tutorialspoint java düzüjisine goşalyň . Import goşmagy hem ýatdan çykaralyň:
import java.util.Random;
import java.util.ArrayList;
import java.util.List;
Esasy usulda birnäçe habar dörederis:
public static void main(String[] args){
    List<Message> messages = new ArrayList();
    messages.add(new Message("Hello, World!"));
    messages.add(new Message("Hello, Sun!"));
    System.out.println(messages);
}
Deňeşdirmek islesek näme etmelidigimiz hakda pikir edeliň? Mysal üçin, id boýunça tertiplemek isleýäris. Tertibi döretmek üçin haýsy obýektiň öňki (ýagny has kiçi) we haýsysynyň indiki (ýagny has uly) düşünmek üçin obýektleri nädip deňeşdirmeli. Java.lang.Object ýaly synpdan başlalyň . Bilşimiz ýaly, ähli synplar bu Obýekt synpyndan doly miras alýarlar. Bu mantykly, sebäbi Bu, "Hemme zat bir zat" düşünjesini aňladýar we ähli synplar üçin umumy häsiýeti üpjün edýär. Bu synp her synpyň iki usulynyň bardygyny kesgitleýär: → hashCode HashCode usuly synpyň mysaly hökmünde obýektiň san (int) görnüşini görkezýär. Bu näme many berýär? Diýmek, synpyň iki dürli mysalyny döreden bolsaňyz, mysallar başga bolansoň, hashCode başgaça bolmaly. Usulyň beýanynda şeýle diýilýär: “Näçe amatly bolsa, synp obýekti bilen kesgitlenen hashCode usuly aýratyn obýektler üçin aýratyn bitewi sanlary yzyna gaýtaryp berýär”, agny, bu iki dürli mysal bolsa, onda başgaça bolmaly hashCodes. .Agny, bu usul deňeşdirmek üçin amatly däl. → deňdir Deňdir usuly “obýektler deňdir” diýen soraga jogap berýär we bir many berýär. Bu usulyň deslapky kody bar:
public boolean equals(Object obj) {
    return (this == obj);
}
.Agny, bu usuly obýektiň üstünde goýman, bu usul, esasan, obýekte salgylanmalaryň gabat gelýändigini ýa-da ýokdugyny aýdýar. Bu habarlarymyz üçin amatly däl, sebäbi obýekt bilen baglanyşyklar bilen gyzyklanamzok, habar ID-si bilen gyzyklanýarys. Deňdir usuly ýok etsek-de, iň köp aljak zadymyz: "Olar deňdir" ýa-da "Deň däl". Emma buýrugy kesgitlemek üçin bu ýeterlik däl.

Java-da deňeşdiriji we deňeşdirme

Bize näme laýyk? “Deňeşdir” sözüni terjimeçide iňlis diline terjime etsek, “deňeşdir” terjimesini alarys. Gowy, onda deňeşdirjek biri gerek. Bu deňeşdirmäni deňeşdirseňiz, deňeşdiren biri Deňeşdiriji. Java Api açalyň we şol ýerde Deňeşdiriji tapalyň . Hakykatdanam, şeýle interfeýs bar - java.util.Comparator java.util.Comparator we java.lang.Comparable Görşüňiz ýaly, şeýle interfeýs bar. Ony ýerine ýetirýän synp, "Obýektleri deňeşdirmek funksiýasyny ýerine ýetirýärin" diýýär. Hakykatdanam ýatda saklamaly zat, aşakdaky ýaly beýan edilýän deňeşdiriji şertnama:

Comparator возвращает int по следующей схеме: 
  • отрицательный int (первый an object отрицательный, то есть меньше)
  • положительный int (первый an object положительный, хороший, то есть больший)
  • ноль = an objectы равны
Indi deňeşdiriji ýazalyň. Java.util.Comparator import etmeli bolarys . Importdan soň esasy usuly goşuň: Comparator<Message> comparator = new Comparator<Message>(); Elbetde, bu işlemez, sebäbi Deňeşdiriji interfeýsdir. Şonuň üçin, gabygyň yzyndan egrem-bugram goşarys { }. Bu ýaýlarda usuly ýazarys:
public int compare(Message o1, Message o2) {
    return o1.getId().compareTo(o2.getId());
}
Muny ýazmagy ýatdan çykarmaly dälsiňiz. Deňeşdiriji deňeşdirme ýerine ýetirýän, ýagny deňeşdirýän adamdyr. Deňeşdirilen obýektleriň haýsy tertipdedigi baradaky soraga jogap bermek üçin int. Aslynda bularyň hemmesi. Plyönekeý we aňsat. Mysaldan görnüşi ýaly, Deňeşdiriji bilen birlikde başga bir interfeýs bar - java.lang.Comparable , deňeşdirme usulyny kesgitlemeli . Bu interfeýs, "Interfeýsi amala aşyrýan synp synpyň mysallaryny deňeşdirmäge mümkinçilik berýär" diýilýär. Mysal üçin, “Integer” -iň “ToToTo” -y durmuşa geçirmegi şuňa meňzeýär:
(x < y) ? -1 : ((x == y) ? 0 : 1)
Bu interfeýsleriň hemmesini nädip ýatda saklamaly? Näme üçin? Hemme zat iňlis dilinden gelýär. Deňeşdiriň - deňeşdiriň, deňeşdiren biri Deňeşdiriji (mysal üçin registrator hökmünde. Registeragny, bellige alýan) we “deňeşdirilen” sypaty deňeşdirilýär. Dogrusy, “Deňeşdir” diňe bir deňeşdirilmän, eýsem deňeşdirilende hem terjime edilýär. Bu ýönekeý. Java dili iňlis dilinde gürleýän adamlar tarapyndan ýazylypdy we Java-da hemme zady atlandyrmakda diňe iňlis dili ugrukdyryldy we at dakmakda haýsydyr bir logika bardy. Deňeşdirmek usuly synpyň mysalyny beýleki mysallar bilen nädip deňeşdirmelidigini düşündirýär. Mysal üçin, setirler leksigrafiki taýdan , sanlar bolsa baha bilen deňeşdirilýär.
Java-da deňeşdiriji - 2
Java 8 käbir gowy üýtgeşmeler getirdi. Deňeşdiriji interfeýsine ýakyndan göz aýlasak, ýokarsynda düşündirişiň bardygyny göreris @FunctionalInterface. Aslynda, bu düşündiriş maglumat üçin bolup, bu interfeýsiň işleýändigini aňladýar. Bu, bu interfeýsiň durmuşa geçirilmezden diňe 1 abstrakt usulynyň bardygyny aňladýar. Bu bize näme berýär? Deňeşdiriji kody indi şeýle ýazyp bileris:
Comparator<Message> comparator = (o1, o2) -> o1.getId().compareTo(o2.getId());
Gaplaňda üýtgeýjileri nädip atlandyrýandygymyz. Java-yň özi muny görer, sebäbi ... Diňe bir usul bar bolsa, haýsy giriş parametrleriniň gerekdigi, näçesi we haýsy görnüşleri belli. Ondan soň, kod bilen bu bölüme geçirmek isleýändigimizi ok bilen aýdýarys. Mundan başga-da, Java 8-iň kömegi bilen, interfeýslerde deslapky usullar peýda boldy - bular interfeýsi durmuşa geçirenimizde deslapky görnüşde (adaty tertipde) ýüze çykýan usullar. Deňeşdiriji interfeýsde bularyň birnäçesi bar. Mysal üçin:
Comparator moreImportant = Comparator.reverseOrder();
Comparator lessImportant = Comparator.naturalOrder();
Koduňyzy has arassa etjek başga bir usul bar. Aboveokardaky mysala seredeliň, deňeşdirijimizi beýan etdik. Ol näme edýär? Bu gaty ýönekeý. Diňe bir obýekt alýar we deňeşdirip boljak birneme bahany alýar. Mysal üçin, “Integer” deňeşdirip bolýar, şonuň üçin habar id bahalarynda deňeşdirme ýerine ýetirip bildik. Bu ýönekeý deňeşdiriji funksiýa hem şeýle ýazylyp bilner:
Comparator<Message> comparator = Comparator.comparing(obj -> obj.getId());
.Agny, sözüň doly manysynda: "Bizde şuňa meňzeş deňeşdiriji bar: obýektleri alýar, getId () usuly bilen deňeşdirilýär, deňeşdirme bilen deňeşdirýär." Indi elhenç dizaýn ýok. Ahyrynda ýene bir aýratynlygy belläsim gelýär. Deňeşdirijiler bilelikde zynjyrlanyp bilner. Mysal üçin:
Comparator<Message> comparator = Comparator.comparing(obj -> obj.getId());
comparator = comparator.thenComparing(obj -> obj.getMessage().length());

Arza

Deňeşdiriji beýannama gaty mantykly bolup çykdy, şeýlemi? Indi ony nädip ulanmalydygyny we haýsy ýerlerde görmelidigini görmeli. → Kolleksiýalar.sort (java.util.Collections) Elbetde, kolleksiýalary şu görnüşde tertipläp bileris. Emma hemme zat däl, diňe sanawlar. Bu ýerde üýtgeşik zat ýok, sebäbi ... Indeks boýunça bir elemente girmegi talap edýän sanaw. Bu bolsa, iki belgili elementi üçünji element bilen çalyşmaga mümkinçilik berýär. Şonuň üçin bu görnüşde tertiplemek diňe sanawlar üçin mümkindir:
Comparator<Message> comparator = Comparator.comparing(obj -> obj.getId());
Collections.sort(messages, comparator);
Arrays.sort (java.util.Arrays) massiwleri hem tertiplemek amatly. Againene-de, elementlere indeks boýunça girmegiň şol bir sebäbi üçin. Java java.util.SortedSet we java.util.SortedMap nesilleri Rememberadymyzda saklaýşy ýaly, Set we Map ýazgylary saklamagyň tertibini kepillendirmeýär. UTöne sargyt kepillendirýän ýörite amallarymyz bar. Kolleksiýa elementleri java.lang.Comparable ýerine ýetirmeýän bolsa, deňeşdirijini şeýle kolleksiýalaryň konstruktoryna geçirip bileris:
Set<Message> msgSet = new TreeSet(comparator);
Stream API Java 8-de peýda bolan “Stream Api” -de deňeşdiriji akym elementleriniň üstünde işlemegi aňsatlaşdyrmaga mümkinçilik berýär. Mysal üçin, 0-dan 999-a çenli tötänleýin sanlaryň yzygiderliligi gerek:
Supplier<Integer> randomizer = () -> new Random().nextInt(1000);
Stream.generate(randomizer)
    .limit(10)
    .sorted(Comparator.naturalOrder())
    .forEach(e -> System.out.println(e));
Durup bilerdik, ýöne has gyzykly meseleler bar. Mysal üçin, açar habar ID-si bolan Kartany taýýarlamaly. Şol bir wagtyň özünde, bu düwmeleri kiçijikden ulusyna tertipli bolar ýaly tertiplemek isleýäris. Geliň şu koddan başlalyň:
Map<Integer, Message> collected = Arrays.stream(messages)
                .sorted(Comparator.comparing(msg -> msg.getId()))
                .collect(Collectors.toMap(msg -> msg.getId(), msg -> msg));
Bu ýere gaýdyp geljek zadymyz aslynda “HashMap”. Bilşimiz ýaly, bu hiç hili sargyt kepillendirmeýär. Şonuň üçin şahsyýetnama boýunça tertiplenen ýazgylarymyz diňe tertipden çykdy. Gowy däl. Kollektorymyzy azajyk üýtgetmeli bolarys:
Map<Integer, Message> collected = Arrays.stream(messages)
                .sorted(Comparator.comparing(msg -> msg.getId()))
                .collect(Collectors.toMap(msg -> msg.getId(), msg -> msg, (oldValue, newValue) -> oldValue, TreeMap::new));
Kod birneme sypaýy görünýärdi, ýöne TreeMap-yň aç-açan durmuşa geçirilmegi netijesinde bu mesele dogry çözüldi. Dürli toparlar hakda has giňişleýin maglumaty şu ýerden okap bilersiňiz: Kollektory özüňiz döredip bilersiňiz. Bu ýerde has köp okap bilersiňiz: "Java 8-de ýörite kollektor döretmek" . Ara alyp maslahatlaşmagy şu ýerde okamak peýdaly: "Akym bilen karta etmek üçin Java 8 sanawy" .
Java-da deňeşdiriji - 3
Deňeşdiriji we deňeşdirip boljak taýaklar gowy. Themöne ýatda saklamaly bir nuans bar. Haçan-da bir synp tertipleşdirilende, synpyňyzy deňeşdirip boljakdygyny hasaplaýar. Bu beýle bolmasa, ýerine ýetiriş wagtynda ýalňyşlyk alarsyňyz. Bir mysala seredeliň:
SortedSet<Message> msg = new TreeSet<>();
msg.add(new Message(2, "Developer".getBytes()));
Bu ýerde hiç hili ýalňyşlyk ýok ýaly. Inöne aslynda, mysalymyzda ýalňyşlyk bilen ýykylar: java.lang.ClassCastException: Message cannot be cast to java.lang.Comparable Hemmesi elementleri tertiplemäge synanyşandygy sebäpli (Bu ahyrsoňy SortedSet). Men edip bilmedim. SortedMap we SortedSet bilen işleýän wagtyňyz muny ýadyňyzdan çykarmaly dälsiňiz. Goşmaça görmek üçin maslahat berilýär: uriuri Tkaç: HashSet we TreeSet - Kolleksiýalar # 1 - Advanced Java
Teswirler
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION