வணக்கம்! இன்று நாம் பொருட்களை ஒப்பிடுவது பற்றி பேசுவோம். ம்ம்ம்... ஆனால் நாம் ஏற்கனவே இந்த தலைப்பை ஒன்றுக்கு மேற்பட்ட முறை பேசவில்லையா? :/
==
ஆபரேட்டர் எப்படி வேலை செய்கிறார் என்பதும், முறைகள் 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()
இந்த முறை a 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()
. மாறாக, Comparator ஐச் செயல்படுத்தும் ஒரு தனி வகுப்பை உருவாக்கி, நமக்குத் தேவையான வரிசையாக்கத்தை எப்படிச் செய்வது என்று கற்றுக்கொடுக்கலாம்!
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()
, இது an ஐத் தருகிறது 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
. அவ்வளவுதான்! வேலையில் உண்மையான திட்டங்களில் நீங்கள் அடிக்கடி பயன்படுத்தும் இரண்டு மிக முக்கியமான வழிமுறைகளை இன்று நீங்கள் படித்திருக்கிறீர்கள். ஆனால், உங்களுக்குத் தெரிந்தபடி, நடைமுறை இல்லாத கோட்பாடு ஒன்றும் இல்லை. இப்போது உங்கள் அறிவை ஒருங்கிணைத்து சில பணிகளை முடிக்க வேண்டிய நேரம் இது!