హాయ్! ఈ రోజు మనం వస్తువులను పోల్చడం గురించి మాట్లాడబోతున్నాం. అయ్యో... అయితే మనం ఇప్పటికే ఈ టాపిక్ ఒకటి కంటే ఎక్కువ సార్లు మాట్లాడుకోలేదా? :/
==
ఆపరేటర్ ఎలా పనిచేస్తుందో, అలాగే పద్ధతులు equals()
మరియు hashCode()
పద్ధతులు మాకు తెలుసు. పోలిక కొద్దిగా భిన్నంగా ఉంటుంది. మునుపు, మేము చాలావరకు "సమానత్వం కోసం వస్తువులను తనిఖీ చేయడం" అని అర్థం. కానీ వస్తువులను ఒకదానితో ఒకటి పోల్చడానికి కారణాలు పూర్తిగా భిన్నంగా ఉంటాయి! వీటిలో అత్యంత స్పష్టమైనది క్రమబద్ధీకరణ. మీకు సంఖ్యలు లేదా స్ట్రింగ్లను క్రమబద్ధీకరించమని చెప్పినట్లయితే ArrayList<>
, మీరు దీన్ని ఎటువంటి సమస్యలు లేకుండా నిర్వహించగలరని నేను భావిస్తున్నాను:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static void main(String[] args) {
String name1 = "Masha";
String name2 = "Sasha";
String name3 = "Dasha";
List<String> names = new ArrayList<>();
names.add(name1);
names.add(name2);
names.add(name3);
Collections.sort(names);
System.out.println(names);
}
}
కన్సోల్ అవుట్పుట్:
[Dasha, Masha, Sasha]
Collections
మీరు తరగతి మరియు దాని పద్ధతిని గుర్తుంచుకుంటే sort()
, బాగా చేసారు! మీకు సంఖ్యలతో కూడా ఇబ్బంది ఉండదని నేను భావిస్తున్నాను. మీ కోసం మరింత సవాలుతో కూడిన పని ఇక్కడ ఉంది:
public class Car {
private int manufactureYear;
private String model;
private int maxSpeed;
public Car(int manufactureYear, String model, int maxSpeed) {
this.manufactureYear = manufactureYear;
this.model = model;
this.maxSpeed = maxSpeed;
}
// ...getters, setters, toString()
}
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Car> cars = new ArrayList<>();
Car ferrari = new Car(1990, "Ferrari 360 Spider", 310);
Car lambo = new Car(2012, "Lamborghini Gallardo", 290);
Car bugatti = new Car(2010, "Bugatti Veyron", 350);
cars.add(ferrari);
cars.add(bugatti);
cars.add(lambo);
}
}
పని నిజానికి సులభం. Car
మాకు తరగతి మరియు 3 కార్ వస్తువులు ఉన్నాయి . మీరు జాబితాలోని కార్లను దయతో క్రమబద్ధీకరిస్తారా? మీరు బహుశా "వాటిని ఎలా క్రమబద్ధీకరించాలి?" పేరు చేత? తయారీ సంవత్సరం ద్వారా? గరిష్ట వేగంతో? అద్భుతమైన ప్రశ్న. ప్రస్తుతానికి, వస్తువులను ఎలా క్రమబద్ధీకరించాలో మాకు తెలియదు Car
. మరియు, చాలా సహజంగా, జావాకు అది కూడా తెలియదు! Car
మేము ఆబ్జెక్ట్ల జాబితాను పద్ధతికి పంపడానికి ప్రయత్నించినప్పుడు Collections.sort()
, మనకు లోపం వస్తుంది:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Car> cars = new ArrayList<>();
Car ferrari = new Car(1990, "Ferrari 360 Spider", 310);
Car lambo = new Car(20012, "Lamborghini Gallardo", 290);
Car bugatti = new Car(2010, "Bugatti Veyron", 350);
cars.add(ferrari);
cars.add(bugatti);
cars.add(lambo);
// Compilation error!
Collections.sort(cars);
}
}
మరియు నిజానికి, మీరు వ్రాసిన తరగతుల వస్తువులను ఎలా క్రమబద్ధీకరించాలో భాషకు ఎలా తెలుస్తుంది? ఇది మీ ప్రోగ్రామ్ ఏమి చేయాలనే దానిపై ఆధారపడి ఉంటుంది. ఈ వస్తువులను పోల్చడానికి మనం ఏదో ఒకవిధంగా జావాకు నేర్పించాలి. మరియు వాటిని మనకు కావలసిన విధంగా పోల్చడానికి. జావా దీని కోసం ఒక ప్రత్యేక యంత్రాంగాన్ని కలిగి ఉంది: Comparable
ఇంటర్ఫేస్. మా వస్తువులను ఏదో ఒకవిధంగా సరిపోల్చడానికి మరియు క్రమబద్ధీకరించడానికి Car
, తరగతి ఈ ఇంటర్ఫేస్ని అమలు చేయాలి, ఇందులో ఒకే పద్ధతి ఉంటుంది: compareTo()
:
public class Car implements Comparable<Car> {
private int manufactureYear;
private String model;
private int maxSpeed;
public Car(int manufactureYear, String model, int maxSpeed) {
this.manufactureYear = manufactureYear;
this.model = model;
this.maxSpeed = maxSpeed;
}
@Override
public int compareTo(Car o) {
return 0;
}
// ...getters, setters, toString()
}
దయచేసి గమనించండిమేము Comparable<Car>
ఇంటర్ఫేస్ను పేర్కొన్నాము, కేవలం Comparable
. ఇది పారామీటర్ చేయబడిన ఇంటర్ఫేస్, అంటే, మనం నిర్దిష్ట అనుబంధిత తరగతిని తప్పనిసరిగా పేర్కొనాలి. <Car>
సూత్రప్రాయంగా, మీరు ఇంటర్ఫేస్ నుండి తీసివేయవచ్చు , కానీ అప్పుడు పోల్చడం Object
డిఫాల్ట్గా వస్తువులపై ఆధారపడి ఉంటుంది. పద్ధతికి బదులుగా compareTo(Car o)
, మా తరగతి వీటిని కలిగి ఉంటుంది:
@Override
public int compareTo(Object o) {
return 0;
}
వాస్తవానికి, దానితో పని చేయడం మాకు చాలా సులభం Car
. పద్ధతి లోపల compareTo()
, మేము కార్లను పోల్చడానికి మా లాజిక్ను అమలు చేస్తాము. మేము వాటిని తయారు చేసిన సంవత్సరం వారీగా క్రమబద్ధీకరించాలని అనుకుందాం. మీరు బహుశా ఈ compareTo()
పద్ధతిని తిరిగి ఇస్తుందని గమనించవచ్చు int
, a కాదు boolean
. ఇది మీకు ఆశ్చర్యం కలిగించవద్దు. మేము రెండు వస్తువులను పోల్చినప్పుడు, 3 అవకాశాలు ఉన్నాయి:
а < b
a > b
a == b
.
boolean
కేవలం 2 విలువలను కలిగి ఉంది: ఒప్పు మరియు తప్పు, ఇది వస్తువులను పోల్చడానికి సరిగ్గా పని చేయదు. తో int
, ప్రతిదీ చాలా సులభం. రిటర్న్ విలువ అయితే > 0
, అప్పుడు a > b
. యొక్క ఫలితం అయితే compareTo
, < 0
అప్పుడు a < b
. మరియు, ఫలితం అయితే == 0
, రెండు వస్తువులు సమానంగా ఉంటాయి: a == b
. తయారీ సంవత్సరం వారీగా కార్లను క్రమబద్ధీకరించడానికి మా తరగతికి బోధించడం చాలా సులభం:
@Override
public int compareTo(Car o) {
return this.getManufactureYear() - o.getManufactureYear();
}
అయితే ఇక్కడ ఏం జరుగుతోంది? మేము ఒక కార్ ఆబ్జెక్ట్ ( this
) తీసుకుంటాము, ఈ కారు తయారీ సంవత్సరాన్ని పొందండి మరియు దాని నుండి మరొక కారు తయారీ సంవత్సరాన్ని (వస్తువుతో పోల్చబడినది) తీసివేస్తాము. మొదటి కారు తయారీ సంవత్సరం ఎక్కువగా ఉంటే, పద్ధతి ఒక int > 0
. దీని అర్థం this car >
కారు o
. దీనికి విరుద్ధంగా, రెండవ కారు ( ) తయారీ సంవత్సరం о
ఎక్కువగా ఉంటే, అప్పుడు పద్ధతి ప్రతికూల సంఖ్యను అందిస్తుంది, అంటే o > this
. చివరగా, అవి సమానంగా ఉంటే, అప్పుడు పద్ధతి తిరిగి వస్తుంది 0
. వస్తువుల సేకరణలను క్రమబద్ధీకరించడానికి ఈ సాధారణ యంత్రాంగం ఇప్పటికే సరిపోతుంది Car
! మీరు ఇంకేమీ చేయనవసరం లేదు. దీన్ని తనిఖీ చేయండి:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Car> cars = new ArrayList<>();
Car ferrari = new Car(1990, "Ferrari 360 Spider", 310);
Car lambo = new Car(2012, "Lamborghini Gallardo", 290);
Car bugatti = new Car(2010, "Bugatti Veyron", 350);
cars.add(ferrari);
cars.add(bugatti);
cars.add(lambo);
// There was previously an error here
Collections.sort(cars);
System.out.println(cars);
}
}
కన్సోల్ అవుట్పుట్:
[Car{manufactureYear=1990, model='Ferrari 360 Spider', maxSpeed=310},
Car{manufactureYear=2010, model='Bugatti Veyron', maxSpeed=350},
Car{manufactureYear=2012, model='Lamborghini Gallardo', maxSpeed=290}]
కార్లు మనకు కావలసిన విధంగా క్రమబద్ధీకరించబడ్డాయి! :) నేను ఎప్పుడు ఉపయోగించాలి Comparable
? లో అమలు చేయబడిన పోలిక పద్ధతిని Comparable
సహజ క్రమం అంటారు. ఈ పద్ధతిలో compareTo()
మీరు ఈ తరగతికి చెందిన వస్తువులను పోల్చడానికి అత్యంత సాధారణమైన లేదా సహజమైన మార్గాన్ని నిర్వచించారు. జావా ఇప్పటికే సహజమైన క్రమాన్ని కలిగి ఉంది. ఉదాహరణకు, తీగలను చాలా తరచుగా అక్షర క్రమంలో మరియు సంఖ్యల విలువను పెంచడం ద్వారా సంఖ్యలు క్రమబద్ధీకరించబడతాయని జావాకు తెలుసు. అందువల్ల, మీరు sort()
సంఖ్యలు లేదా స్ట్రింగ్ల జాబితాలో పద్ధతిని కాల్ చేస్తే, అవి క్రమబద్ధీకరించబడతాయి. Comparable<Car>
మా ప్రోగ్రామ్ సాధారణంగా కార్లను తయారు చేసిన సంవత్సరం వారీగా పోల్చి, క్రమబద్ధీకరించినట్లయితే, మేము ఇంటర్ఫేస్ మరియు కార్ల కోసం సహజ క్రమబద్ధీకరణను నిర్వచించాలిcompareTo()
పద్ధతి. అయితే ఇది మనకు సరిపోకపోతే? మన కార్యక్రమం అంత సులభం కాదని ఊహించుకుందాం. చాలా సందర్భాలలో, కార్ల సహజ క్రమబద్ధీకరణ (తయారీ సంవత్సరం ద్వారా నిర్వహించబడాలని మేము సెట్ చేసాము) మాకు సరిపోతుంది. కానీ కొన్నిసార్లు మా కస్టమర్లు వేగంగా డ్రైవింగ్ చేయడానికి ఇష్టపడతారు. వాటిని పరిశీలించడానికి మేము కార్ల జాబితాను సిద్ధం చేస్తున్నట్లయితే, కార్లు గరిష్ట వేగంతో క్రమబద్ధీకరించబడాలి. ఉదాహరణకు, మనం 15% సమయాన్ని ఇలా క్రమబద్ధీకరించాలని అనుకుందాం. Car
తరగతి సహజ క్రమబద్ధీకరణను తయారు చేసిన సంవత్సరానికి బదులుగా వేగంతో సెట్ చేయడానికి ఇది స్పష్టంగా సరిపోదు . కానీ మేము మా కస్టమర్లలో 15% మందిని విస్మరించలేము. కాబట్టి మనం ఏమి చేయాలి? మరొక ఇంటర్ఫేస్ ఇక్కడ మా సహాయానికి వస్తుంది: Comparator
. లాగానే Comparable
, ఇది పారామీటర్ చేయబడిన ఇంటర్ఫేస్. తేడా ఏమిటి? Comparable
మన వస్తువులను "పోలిపించదగినదిగా" చేస్తుంది మరియు వాటి అత్యంత సహజమైన క్రమాన్ని నిర్వచిస్తుంది, అంటే చాలా సందర్భాలలో ఉపయోగించే క్రమబద్ధీకరణ క్రమాన్ని. Comparator
ఒక ప్రత్యేక "పోలిక" ఇంటర్ఫేస్. మనం ఏదైనా ప్రత్యేక క్రమబద్ధీకరణ క్రమాన్ని అమలు చేయవలసి వస్తే, మేము తరగతిలోకి వెళ్లి Car
లాజిక్ని మార్చాల్సిన అవసరం లేదు compareTo()
. బదులుగా, మేము కంపారేటర్ను అమలు చేసే ప్రత్యేక తరగతిని సృష్టించవచ్చు మరియు మనకు అవసరమైన సార్టింగ్ను ఎలా నిర్వహించాలో నేర్పించవచ్చు!
import java.util.Comparator;
public class MaxSpeedCarComparator implements Comparator<Car> {
@Override
public int compare(Car o1, Car o2) {
return o1.getMaxSpeed() - o2.getMaxSpeed();
}
}
మీరు చూడగలిగినట్లుగా, మాది Comparator
చాలా సులభం. మేము ఒక ఇంటర్ఫేస్ పద్ధతిని మాత్రమే అమలు చేయాలి: compare()
. ఇది రెండు Car
వస్తువులను ఇన్పుట్లుగా తీసుకుంటుంది మరియు వాటి గరిష్ట వేగాన్ని సాధారణ మార్గంలో (వ్యవకలనం ద్వారా) పోలుస్తుంది. లైక్ compareTo()
, ఇది aని తిరిగి ఇస్తుంది int
మరియు పోలిక సూత్రం ఒకటే. మేము దీన్ని ఎలా ఉపయోగిస్తాము? ఇదంతా సూటిగా ఉంటుంది:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Car> cars = new ArrayList<>();
Car ferrari = new Car(1990, "Ferrari 360 Spider", 310);
Car lambo = new Car(2012, "Lamborghini Gallardo", 290);
Car bugatti = new Car(2010, "Bugatti Veyron", 350);
cars.add(ferrari);
cars.add(bugatti);
cars.add(lambo);
Comparator speedComparator = new MaxSpeedCarComparator();
Collections.sort(cars, speedComparator);
System.out.println(cars);
}
}
కన్సోల్ అవుట్పుట్:
[Car{manufactureYear=2012, model='Lamborghini Gallardo', maxSpeed=290},
Car{manufactureYear=1990, model='Ferrari 360 Spider', maxSpeed=310},
Car{manufactureYear=2010, model='Bugatti Veyron', maxSpeed=350}]
Collections.sort()
మేము కేవలం కంపారిటర్ ఆబ్జెక్ట్ను సృష్టించి, క్రమబద్ధీకరించాల్సిన జాబితాతో పాటు పద్ధతికి పంపుతాము . పద్ధతి కంపారిటర్ను స్వీకరించినప్పుడు, అది తరగతి sort()
పద్ధతిలో నిర్వచించిన సహజ క్రమబద్ధీకరణను ఉపయోగించదు . బదులుగా, దానికి పంపిన కంపారిటర్ ద్వారా నిర్వచించబడిన సార్టింగ్ అల్గారిథమ్ని ఇది వర్తిస్తుంది. ఇలా చేయడం వల్ల కలిగే ప్రయోజనాలు ఏమిటి? ముందుగా, ఇప్పటికే ఉన్న కోడ్తో అనుకూలత. మేము కొత్త, ప్రత్యేక క్రమబద్ధీకరణ పద్ధతిని సృష్టించాము, అయితే ఎక్కువ సమయం ఉపయోగించబడుతుంది. మేము తరగతిని అస్సలు ముట్టుకోలేదు . ఇది ఒక , కాబట్టి ఇది మిగిలి ఉంది: Car
compareTo()
Car
Comparable
public class Car implements Comparable<Car> {
private int manufactureYear;
private String model;
private int maxSpeed;
public Car(int manufactureYear, String model, int maxSpeed) {
this.manufactureYear = manufactureYear;
this.model = model;
this.maxSpeed = maxSpeed;
}
@Override
public int compareTo(Car o) {
return this.getManufactureYear() - o.getManufactureYear();
}
// ...getters, setters, toString()
}
రెండవది, వశ్యత. మనకు నచ్చినన్ని సార్టింగ్ అల్గారిథమ్లను జోడించవచ్చు. ఉదాహరణకు, మేము కార్లను రంగు, వేగం, బరువు లేదా బ్యాట్మ్యాన్ సినిమాల్లో ఎన్నిసార్లు ఉపయోగించారు అనే దాని ఆధారంగా క్రమబద్ధీకరించవచ్చు. మనం చేయాల్సిందల్లా అదనంగా సృష్టించడం Comparator
. అంతే! ఈ రోజు మీరు పనిలో నిజమైన ప్రాజెక్ట్లలో తరచుగా ఉపయోగించే రెండు ముఖ్యమైన యంత్రాంగాలను అధ్యయనం చేసారు. కానీ, మీకు తెలిసినట్లుగా, అభ్యాసం లేని సిద్ధాంతం ఏమీ లేదు. ఇప్పుడు మీ జ్ఞానాన్ని ఏకీకృతం చేయడానికి మరియు కొన్ని పనులను పూర్తి చేయడానికి ఇది సమయం!
GO TO FULL VERSION