JavaRush /Blog Jawa /Random-JV /Komparator ing basa Jawa
Viacheslav
tingkat

Komparator ing basa Jawa

Diterbitake ing grup
Mung wong kesed sing durung nulis babagan Comparator lan perbandingan ing Jawa. Aku ora kesed - mula aku njaluk sampeyan tresna lan milih variasi liyane. Muga-muga ora keluwihan. Lan ya, artikel iki minangka jawaban kanggo pitakonan: "Apa sampeyan bisa nulis komparator saka memori?" Muga-muga sawise maca artikel iki kabeh wong bisa nulis komparator saka memori.
Komparator ing basa Jawa - 1
Pambuka Basa Jawa dikenal minangka basa sing berorientasi obyek. Akibaté, ing Jawa iku umum kanggo operate karo obyek. Nanging cepet utawa mengko tugas mbandhingake obyek miturut sawetara prinsip muncul. Dadi, diwenehi: Kita duwe sawetara pesen, sing diterangake dening kelas Pesen:
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;
    }
}
Ayo ditambahake kelas iki menyang Tutorialspoint java compiler . Ayo uga elinga nambah impor:
import java.util.Random;
import java.util.ArrayList;
import java.util.List;
Ing cara utama kita bakal nggawe sawetara pesen:
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);
}
Ayo dipikirake apa sing kudu ditindakake yen kita pengin mbandhingake? Contone, kita pengin ngurutake miturut id. Lan kanggo nggawe urutan, sampeyan kudu piye wae mbandhingake obyek supaya ngerti obyek sing sadurunge (yaiku, luwih cilik) lan sing sabanjure (yaiku, luwih gedhe). Ayo dadi miwiti karo kelas kaya java.lang.Object . Kaya sing kita ngerteni, kabeh kelas entuk warisan kanthi implisit saka kelas Obyek iki. Lan iki logis, amarga Iki ateges konsep: "Kabeh iku obyek" lan menehi prilaku umum kanggo kabeh kelas. Lan kelas iki nemtokake sing saben kelas wis rong cara: → hashCode Metode hashCode ngasilake sawetara numerik (int) perwakilan saka obyek minangka Kayata saka kelas. Iki artine apa? Iki tegese yen sampeyan nggawe rong conto kelas sing beda, mula amarga kedadeyan kasebut beda, kode hash kudu beda. Iki minangka katrangan babagan metode kasebut: "Minangka praktis, metode hashCode sing ditetepake dening Obyek kelas ngasilake integer sing beda kanggo obyek sing beda-beda" Yaiku, yen iki rong kedadeyan sing beda, mula kudu beda. kode hash. Tegese, cara iki ora cocok kanggo perbandingan kita. → equals Metode equals njawab pitakonan "apa obyek padha" lan ngasilake boolean. Cara iki nduweni kode standar:
public boolean equals(Object obj) {
    return (this == obj);
}
Sing, tanpa overriding cara iki ing obyek, cara iki ateges ngandika apa referensi kanggo obyek cocog utawa ora. Iki ora cocok kanggo pesen kita, amarga kita ora kasengsem ing pranala menyang obyek, kita kasengsem ing id pesen. Lan sanajan kita ngilangi metode sing padha, maksimal sing bakal ditindakake yaiku: "Padha padha" utawa "Dheweke ora padha." Nanging iki ora cukup kanggo kita nemtokake urutan kasebut.

Comparator lan Comparable ing Jawa

Apa sing cocog karo kita? Yen kita nerjemahake tembung "bandhingake" menyang basa Inggris ing penerjemah, kita bakal entuk terjemahan "bandhingake". Apik, banjur kita butuh wong sing bakal mbandhingake. Yen mbandhingake iki, sing mbandhingake yaiku Pembanding. Ayo mbukak Java Api lan golek Comparator ing kana . Lan tenan, ana antarmuka kuwi - java.util.Comparator java.util.Comparator lan java.lang.Comparable Nalika sampeyan bisa ndeleng, ana antarmuka kuwi. Kelas sing ngleksanakake ujar manawa "Aku ngetrapake fungsi kanggo mbandhingake obyek." Siji-sijine sing kudu dieling-eling yaiku kontrak komparator, sing ditulis kaya ing ngisor iki:

Comparator возвращает int по следующей схеме: 
  • отрицательный int (первый an object отрицательный, то есть меньше)
  • положительный int (первый an object положительный, хороший, то есть больший)
  • ноль = an objectы равны
Saiki ayo nulis komparator. Kita kudu ngimpor java.util.Comparator . Sawise ngimpor, nambah cara kanggo utama: Comparator<Message> comparator = new Comparator<Message>(); Alamiah, iki ora bisa, amarga Comparator minangka antarmuka. Mulane, sawise kurung kita bakal nambah kriting { }. Ing kurung iki kita bakal nulis cara:
public int compare(Message o1, Message o2) {
    return o1.getId().compareTo(o2.getId());
}
Sampeyan malah ora kudu ngelingi nulis iki. Komparator yaiku wong sing nindakake perbandingan, yaiku nggawe mbandhingake. Kanggo njawab pitakonan saka urutan apa obyek dibandhingake, kita bali int. Iku kabeh, bener. Cukup lan gampang. Minangka kita bisa ndeleng saka conto, saliyane Comparator, ana antarmuka liyane - java.lang.Comparable , ngleksanakake kang kita kudu nemtokake cara compareTo . Antarmuka iki nyatakake yen "Kelas sing ngleksanakake antarmuka ngidini conto kelas bisa dibandhingake." Contone, implementasi Integer saka compareTo katon kaya iki:
(x < y) ? -1 : ((x == y) ? 0 : 1)
Kepiye ngelingi kabeh antarmuka kasebut? Kanggo apa? Kabeh asale saka basa Inggris. Mbandhingake - kanggo mbandhingake, sing mbandhingake yaiku Comparator (minangka registrar, contone. Sing, sing ndhaptar), lan adjective "dibandhingake" yaiku Comparable. Ya, "Bandhingake karo" diterjemahake ora mung dibandhingake karo, nanging uga dibandhingake karo. Iku prasaja. Basa Jawa ditulis dening wong-wong sing nganggo basa Inggris, lan nalika menehi jeneng kabeh ing Jawa padha dituntun nganggo basa Inggris lan ana sawetara logika ing penamaan kasebut. Lan cara compareTo nerangake carane conto kelas kudu dibandhingake karo conto liyane. Contone, strings dibandhingake lexigraphically , lan angka dibandhingake nilai.
Komparator ing basa Jawa - 2
Java 8 nggawa sawetara owah-owahan apik. Yen kita ndeleng kanthi teliti ing antarmuka Comparator, kita bakal weruh yen ana anotasi ing ndhuwur @FunctionalInterface. Nyatane, anotasi iki kanggo informasi lan tegese antarmuka iki fungsional. Iki tegese antarmuka iki mung duwe 1 cara abstrak tanpa implementasine. Apa iki menehi kita? Kita bisa nulis kode komparator saiki kaya iki:
Comparator<Message> comparator = (o1, o2) -> o1.getId().compareTo(o2.getId());
Ing kurung yaiku carane kita menehi jeneng variabel. Jawa dhewe bakal weruh amarga ... Yen mung ana siji cara, banjur cetha apa parameter input sing dibutuhake, pinten, lan jinis apa. Sabanjure, kita ngomong karo panah sing arep ditransfer menyang bagean kode iki. Kajaba iku, thanks kanggo Java 8, cara standar katon ing antarmuka - iki minangka cara sing katon kanthi standar (kanthi standar) nalika kita ngetrapake antarmuka. Ana sawetara iki ing antarmuka Comparator. Contone:
Comparator moreImportant = Comparator.reverseOrder();
Comparator lessImportant = Comparator.naturalOrder();
Ana cara liya sing bakal nggawe kode luwih resik. Ayo ndeleng conto ing ndhuwur, ing ngendi kita nerangake komparator kita. Dheweke nyapo? Iku cukup primitif. Iku mung njupuk obyek lan mbeber sawetara nilai saka iku sing iso dibandhingke. Contone, Integer ngleksanakake iso dibandhingke, supaya kita bisa nindakake compareTo ing pesen id nilai. Fungsi komparator prasaja iki uga bisa ditulis kaya mangkene:
Comparator<Message> comparator = Comparator.comparing(obj -> obj.getId());
Yaiku, secara harfiah, "We have a Comparator sing mbandhingake kaya iki: njupuk obyek, entuk Comparable saka wong-wong mau nggunakake metode getId (), mbandhingake nggunakake compareTo." Lan ora ana desain sing luwih elek. Lan pungkasane, aku pengin nyathet siji fitur liyane. Comparator bisa dirantai bebarengan. Tuladhane:
Comparator<Message> comparator = Comparator.comparing(obj -> obj.getId());
comparator = comparator.thenComparing(obj -> obj.getMessage().length());

Aplikasi

Pranyatan komparator ternyata cukup logis, ta? Saiki kita kudu ndeleng carane nggunakake lan ing panggonan apa. → Collections.sort (java.util.Collections) Mesthi wae, kita bisa ngurutake koleksi kanthi cara iki. Nanging ora kabeh, mung dhaptar. Lan ora ana sing aneh ing kene, amarga ... Iki minangka dhaptar sing mbutuhake akses menyang unsur kanthi indeks. Lan iki ngidini unsur nomer loro diganti karo unsur nomer telu. Mulane, ngurutake kanthi cara iki mung bisa kanggo dhaptar:
Comparator<Message> comparator = Comparator.comparing(obj -> obj.getId());
Collections.sort(messages, comparator);
Arrays.sort (java.util.Arrays) Array uga trep kanggo diurutake. Maneh, kanthi alesan sing padha ngakses unsur kanthi indeks. → Keturunan java.util.SortedSet lan java.util.SortedMap Kaya sing kita eling, Set lan Peta ora njamin urutan nyimpen rekaman. Nanging kita duwe implementasine khusus sing njamin supaya. Lan yen unsur koleksi ora ngleksanakake java.lang.Comparable, banjur kita bisa pass Comparator kanggo konstruktor koleksi kuwi:
Set<Message> msgSet = new TreeSet(comparator);
Stream API Ing Stream Api, sing muncul ing Java 8, komparator ngidini sampeyan nyederhanakake karya ing unsur stream. Contone, kita butuh urutan nomer acak saka 0 nganti 999 kalebu:
Supplier<Integer> randomizer = () -> new Random().nextInt(1000);
Stream.generate(randomizer)
    .limit(10)
    .sorted(Comparator.naturalOrder())
    .forEach(e -> System.out.println(e));
Kita bisa mandheg, nanging ana masalah sing luwih menarik. Contone, sampeyan kudu nyiapake Peta, ing ngendi kuncine yaiku id pesen. Ing wektu sing padha, kita pengin ngurutake kunci kasebut supaya tombol kasebut diurutake, saka sing paling cilik nganti paling gedhe. Ayo miwiti nganggo kode iki:
Map<Integer, Message> collected = Arrays.stream(messages)
                .sorted(Comparator.comparing(msg -> msg.getId()))
                .collect(Collectors.toMap(msg -> msg.getId(), msg -> msg));
Sing bakal bali ing kene yaiku HashMap. Lan kita ngerti, iku ora njamin pesenan sembarang. Mulane, cathetan kita diurutake miturut ID mung metu saka urutan. Ora apik. Kita kudu ngganti kolektor sethithik:
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));
Kode kasebut katon rada creepier, nanging masalah kasebut saiki wis ditanggulangi kanthi bener amarga implementasine TreeMap sing jelas. Sampeyan bisa maca liyane babagan macem-macem klompok ing kene: Sampeyan bisa nggawe kolektor dhewe. Sampeyan bisa maca liyane kene: "Nggawe kolektor adat ing Jawa 8" . Lan migunani kanggo maca diskusi ing kene: "Dhaptar Java 8 kanggo peta karo stream" .
Komparator ing basa Jawa - 3
Comparator lan Comparable rakes apik. Nanging ana siji nuansa sing digandhengake karo wong-wong mau sing kudu dieling-eling. Nalika kelas nindakake ngurutake, ngetung sing bisa matak kelas kanggo Comparable. Yen ora, sampeyan bakal nampa kesalahan ing wektu eksekusi. Ayo ndeleng conto:
SortedSet<Message> msg = new TreeSet<>();
msg.add(new Message(2, "Developer".getBytes()));
Kayane ora ana sing salah ing kene. Nanging nyatane, ing conto kita, bakal kacilakan karo kesalahan: java.lang.ClassCastException: Message cannot be cast to java.lang.Comparable Lan kabeh amarga nyoba ngurutake unsur (Iku SortedSet, sawise kabeh). Lan aku ora bisa. Sampeyan kudu ngelingi iki nalika nggarap SortedMap lan SortedSet. Tambahan Disaranake kanggo ndeleng: Yuri Tkach: HashSet lan TreeSet - Koleksi #1 - Jawa Lanjut
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION