CodeGym /Java Course /मॉड्यूल 1 /Java मध्ये पॅरामीटराइज्ड प्रकार: जेनेरिक्स

Java मध्ये पॅरामीटराइज्ड प्रकार: जेनेरिक्स

मॉड्यूल 1
पातळी 16 , धडा 6
उपलब्ध

1. सर्व वर्ग वारसा घेतातObject

जावा मधील सर्व वर्गांना स्पष्टपणे Objectवर्गाचा वारसा मिळतो.

आम्‍ही जावा कोअर क्वेस्टमध्‍ये वारसा काय आहे आणि ते Java मध्‍ये कसे कार्य करते याचे विश्‍लेषण करू. आत्तासाठी, आम्ही यावरून खालील एका साध्या तथ्याचा विचार करू:

कोणत्याही वर्गातील ऑब्जेक्ट व्हेरिएबलला नियुक्त केले जाऊ शकते Object. उदाहरण:

कोड नोंद
Object o = new Scanner(System.in);
व्हेरिएबल ऑब्जेक्टचा oसंदर्भ संग्रहित करतेScanner
Object o = new String();
व्हेरिएबल ऑब्जेक्टचा oसंदर्भ संग्रहित करतेString
Object o = new Integer(15);
व्हेरिएबल ऑब्जेक्टचा oसंदर्भ संग्रहित करतेInteger
Object o = "Hello";
व्हेरिएबल ऑब्जेक्टचा oसंदर्भ संग्रहित करतेString

इथेच चांगली बातमी संपते. कंपायलर व्हेरिएबलमध्ये सेव्ह केलेल्या ऑब्जेक्टच्या मूळ प्रकाराचा मागोवा ठेवत नाही Object, त्यामुळे तुम्ही क्लासच्या पद्धतींव्यतिरिक्त सेव्ह केलेल्या ऑब्जेक्टवर मेथड कॉल करू शकणार नाही .Object

जर तुम्हाला ऑब्जेक्टच्या मूळ प्रकाराशी संबंधित पद्धतींना कॉल करायचा असेल, तर तुम्हाला प्रथम त्याचा संदर्भ योग्य प्रकारच्या व्हेरिएबलमध्ये सेव्ह करावा लागेल आणि नंतर त्या व्हेरिएबलवरील पद्धतींना कॉल करावा लागेल:

कोड नोंद
Object o = new Scanner(System.in);
int x = o.nextInt();
कार्यक्रम संकलित होणार नाही. वर्गाला पद्धत Objectनाही nextInt().
Object o = new Scanner(System.in);

Scanner console = (Scanner) o;

int x = console.nextInt();
हे चालेल. येथे आपण टाइपकास्ट ऑपरेटर वापरून व्हेरिएबलमध्ये ऑब्जेक्टचा

संदर्भ सेव्ह करतो . ScannerScanner

तुम्ही फक्त जाऊन Objectस्कॅनर व्हेरिएबलला व्हेरिएबल नियुक्त करू शकत नाही, जरी Objectव्हेरिएबलने ऑब्जेक्टचा संदर्भ संग्रहित केला असला तरीही Scanner. परंतु तुम्ही टाइपकास्ट ऑपरेटर वापरत असल्यास हे करू शकता , ज्याबद्दल तुम्हाला आधीच माहिती आहे. हे त्याचे सामान्य स्वरूप आहे:

Type name1 = (Type) name2;

name1व्हेरिएबलचे नाव कुठे आहे Typeआणि name2ते एका व्हेरिएबलचे नाव आहे Objectजे ऑब्जेक्टचा संदर्भ संग्रहित करते Type.

टाइपकास्टिंग

व्हेरिएबलचा प्रकार आणि ऑब्जेक्टचा प्रकार जुळत नसल्यास, a ClassCastExceptionटाकला जाईल. उदाहरण:

कोड नोंद
Object o = new Integer(5);
String s = (String) o;
रनटाइमच्या वेळी एरर येईल:
ClassCastExceptionयेथे टाकले जाईल

Java मध्ये ही त्रुटी टाळण्याचा एक मार्ग आहे: व्हेरिएबलमध्ये संग्रहित केलेल्या ऑब्जेक्टचा प्रकार तपासून आम्ही हे करतो :

name instanceof Type

ऑपरेटर व्हेरिएबल ऑब्जेक्ट आहे instanceofकी नाही हे तपासतो .nameType

उदाहरण म्हणून, विविध वस्तूंच्या अॅरेमध्ये एक स्ट्रिंग शोधूया:

कोड नोंद
Object[] objects = {10, "Hello", 3.14};

for (int i = 0; i < objects.length; i++)
{
   if (objects[i] instanceof String)
   {
      String s = (String) objects[i];
      System.out.println(s);
   }
}
Integerऑटोबॉक्सिंग ही मूल्ये अनुक्रमे , String, आणि , मध्ये रूपांतरित करेल Double.

ऑब्जेक्ट्सच्या अॅरेवर लूप करा जर

ऑब्जेक्ट हे String

व्हेरिएबलमध्ये सेव्ह करा स्क्रीनवर व्हेरिएबल प्रदर्शित करा. String


2. जेनेरिक का दिसू लागले — संग्रह

चला संग्रहांकडे परत जाऊया.

जावा डेव्हलपर्सनी क्लास तयार करताच ArrayList, त्यांना ते सार्वत्रिक बनवायचे होते, जेणेकरून ते कोणत्याही प्रकारची वस्तू साठवू शकेल. Objectम्हणून त्यांनी घटक संग्रहित करण्यासाठी s चा अॅरे वापरला .

या दृष्टिकोनाची ताकद अशी आहे की आपण संग्रहामध्ये कोणत्याही प्रकारची वस्तू जोडू शकता.

अर्थात, अनेक कमकुवतपणा आहेत.

गैरसोय १.

संकलनातून घटक पुनर्प्राप्त करताना एक प्रकार रूपांतरण ऑपरेटर लिहिणे नेहमीच आवश्यक होते:

कोड नोंद
ArrayList numbers = new ArrayList();


for (int i = 0; i < 10; i++)
   numbers.add(i * 10);


int sum = 0;
for (int i = 0; i < 10; i++)
{
   sum = sum + (Integer) numbers.get(i);
}
Objectवस्तूंचे संदर्भ

संग्रहित करण्यासाठी संग्रह तयार करा 10, 20, ... 100;



संकलनातील घटकांची बेरीज


टायपकास्ट करणे आवश्यक आहे

गैरसोय 2.

संग्रहामध्ये विशिष्ट प्रकारचा घटक आहे याची कोणतीही हमी नव्हती

कोड नोंद
ArrayList numbers = new ArrayList();


for (int i = 0; i < 10; i++)
   numbers.add(i * 2.5);


int sum = 0;
for (int i = 0; i < 10; i++)
{
   sum = sum + (Integer) numbers.get(i);
}
Objectऑब्जेक्ट्सचे संदर्भ संग्रहित करण्यासाठी एक संग्रह तयार करा

आम्ही संग्रह Doubleऑब्जेक्ट्स म्हणून दर्शविलेल्या संख्येसह भरतो:
0.0, 2.5, 5.0, ...


संग्रहातील घटकांची बेरीज करा


एक त्रुटी असेल: a Doubleला कास्ट करता येणार नाहीInteger

डेटा कोठेही संग्रहात ठेवला जाऊ शकतो:

  • दुसर्या पद्धतीने
  • दुसर्या कार्यक्रमात
  • फाइलमधून
  • नेटवर्कवर

गैरसोय 3.

संग्रहातील डेटा चुकून बदलला जाऊ शकतो.

तुम्‍ही तुमच्‍या डेटाने भरलेला संग्रह काही पद्धतीने पास करू शकता. ती पद्धत, वेगळ्या प्रोग्रामरने लिहिलेली, तिचा डेटा तुमच्या संग्रहात जोडते.

संग्रहाचे नाव स्पष्टपणे सूचित करत नाही की त्यात कोणत्या प्रकारचा डेटा संग्रहित केला जाऊ शकतो. आणि जरी तुम्ही तुमच्या व्हेरिएबलला स्पष्ट नाव दिले तरी, त्याचा संदर्भ डझनभर पद्धतींना दिला जाऊ शकतो आणि त्या पद्धतींना व्हेरिएबलच्या मूळ नावाबद्दल निश्चितपणे काहीही माहिती नसते.


3. जेनेरिक

जावा मध्ये जेनेरिक

जावामध्ये, या सर्व समस्या जेनेरिक्स नावाच्या थंड गोष्टीमुळे दूर होतात.

Java मध्ये, जेनेरिक्स म्हणजे प्रकारांमध्ये टाइप पॅरामीटर्स जोडण्याची क्षमता. परिणाम एक जटिल संमिश्र प्रकार आहे. अशा संमिश्र प्रकाराचे सामान्य दृश्य हे आहे:

ClassName<TypeParameter>

हा एक सामान्य वर्ग आहे. आणि तुम्ही सामान्यपणे वर्ग वापरता तेथे ते वापरले जाऊ शकते.

कोड वर्णन
ArrayList<Integer> list;
व्हेरिएबल्स तयार करणे
list = new ArrayList<Integer> ();
वस्तू तयार करणे
ArrayList<Integer>[] array;
अॅरे तयार करत आहे

Integerअशा कलेक्शनमध्ये फक्त व्हेरिएबल्स साठवले जाऊ शकतात:

कोड वर्णन
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(new Integer(1));
list.add(2);
list.add("Hello");
ArrayListIntegerघटकांसह संकलन
याला परवानगी आहे
आणि हे देखील कार्य करेल
ऑटोबॉक्सिंग

परंतु याची परवानगी नाही: संकलन त्रुटी

जावा कलेक्शन क्वेस्टमध्ये टाइप पॅरामीटर्ससह तुमचे स्वतःचे वर्ग कसे तयार करायचे ते तुम्ही शिकाल. आत्तासाठी, आम्ही ते कसे वापरायचे आणि ते कसे कार्य करतात ते पाहू.


4. जेनेरिक कसे कार्य करतात

वास्तविक, जेनेरिक्स अत्यंत आदिम आहेत.

कंपाइलर सामान्य प्रकारांसह सामान्य प्रकार बदलतो. पण जेव्हा जेनेरिक प्रकाराच्या पद्धती वापरल्या जातात, तेव्हा कंपाइलर टाईप पॅरामीटर्समध्ये पॅरामीटर्स कास्ट करण्यासाठी टाइपकास्ट ऑपरेटर जोडतो:

कोड कंपाइलर काय करतो
ArrayList<Integer> list = new ArrayList<Integer>();
ArrayList list = new ArrayList();
list.add(1);
list.add( (Integer) 1 );
int x = list.get(0);
int x = (Integer) list.get(0);
list.set(0, 10);
list.set(0, (Integer) 10);

समजा आपल्याकडे पूर्णांकांच्या संग्रहातील संख्यांची बेरीज करणारी पद्धत आहे:

कोड कंपाइलर काय करतो
public int sum(ArrayList<Integer> numbers)
{
   int result = 0;

   for (int i = 0; i < numbers.size(); i++)
      result = result + numbers.get(i);

   return result;
}
public int sum(ArrayList numbers)
{
   int result = 0;

   for (int i = 0; i < numbers.size(); i++)
      result = result + (Integer) numbers.get(i);

   return result;
}

दुसऱ्या शब्दांत, जेनेरिक्स ही एक प्रकारची सिंटॅक्टिक साखर आहे, जसे ऑटोबॉक्सिंग, परंतु थोडे अधिक. ऑटोबॉक्सिंगसह, कंपायलर एक intमध्ये रूपांतरित करण्याच्या पद्धती जोडतो Integerआणि त्याउलट, आणि जेनेरिकसाठी तो टाइपकास्ट ऑपरेटर जोडतो.

कंपाइलरने टाइप पॅरामीटर्ससह तुमचे जेनेरिक वर्ग संकलित केल्यानंतर, ते फक्त सामान्य वर्ग आणि टाइपकास्ट ऑपरेटरमध्ये रूपांतरित केले जातात. जेनेरिक प्रकारांच्या व्हेरिएबल्सना पाठवलेल्या प्रकार वितर्कांबद्दलची माहिती गमावली आहे. या प्रभावाला टाइप इरेजर असेही म्हणतात .

काहीवेळा जेनेरिक क्लासेस (टाईप पॅरामीटर्स असलेले वर्ग) लिहिणाऱ्या प्रोग्रामरना वितर्क म्हणून पास केलेल्या प्रकारांबद्दल खरोखर माहिती आवश्यक असते. Java कलेक्शन क्वेस्टमध्ये, तुम्ही याला कसे सामोरे जावे आणि त्यात काय समाविष्ट आहे ते शिकाल.



5. जेनेरिकबद्दल काही तथ्ये

येथे जेनेरिक्सबद्दल आणखी काही मनोरंजक तथ्ये आहेत.

वर्गांमध्ये अनेक प्रकारचे पॅरामीटर्स असू शकतात. हे असे काहीतरी दिसते:

ClassName<TypeParameter1, TypeParameter2, TypeParameter3>

खरं तर, हे आश्चर्यकारक नाही. कोठेही कंपाइलर एका प्रकारात कास्ट करण्यासाठी ऑपरेटर जोडू शकतो, तो एकाधिक टाइपकास्ट ऑपरेटर जोडू शकतो.

उदाहरणे:

कोड नोंद
HashMap<Integer, String> map = new HashMap<Integer, String>();
map.put(7, "Hello");
map.put(-15, "Hello");
पद्धतीचा putपहिला पॅरामीटर एक आहे Integerआणि दुसरा आहे aString

जेनेरिक प्रकार देखील पॅरामीटर्स म्हणून वापरले जाऊ शकतात . हे असे काहीतरी दिसते:

ClassName<TypeParameter<TypeParameterParameter>>

समजा आपल्याला स्ट्रिंग्सची यादी साठवून ठेवणारी यादी तयार करायची आहे. या प्रकरणात, आम्हाला असे काहीतरी मिळेल:

// List of greetings
ArrayList<String> listHello = new ArrayList<String>();
listHello.add ("Hello");
listHello.add ("Hi");

// List of goodbyes
ArrayList<String> listBye = new ArrayList<String>();
listBye.add("Bye");
listBye.add ("Goodbye");

// List of lists
ArrayList<ArrayList<String>> lists = new ArrayList<ArrayList<String>>();
lists.add(listHello);
lists.add(listBye);

जेनेरिक प्रकार (प्रकार पॅरामीटर्ससह प्रकार) अॅरे प्रकार म्हणून देखील वापरले जाऊ शकतात. हे असे काहीतरी दिसते:

ClassName<TypeParameter>[] array = new ClassName<TypeParameter>[size];

येथे काहीही जादुई घडत नाही: कोन कंस फक्त प्रकाराचे नाव सूचित करतात:

कोड नॉन-जेनेरिक समकक्ष
ArrayList<String>[] list = new ArrayList<String>[10];
StringArrayList[] list = new StringArrayList[10];
ArrayList<Integer>[] list = new ArrayList<Integer>[10];
IntegerArrayList[] list = new IntegerArrayList[10];
ArrayList<Scanner>[] list = new ArrayList<Scanner>[10];
ScannerArrayList[] list = new ScannerArrayList[10];
टिप्पण्या
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION