KaiquanMah commited on
Commit
731d0fd
·
verified ·
1 Parent(s): 095a473

class Box<TYPE>{private TYPE value; ...}

Browse files
Week 7: Enum, Generic Type, Streams, write to file, class diagram/04A. Generic Type Definition [in Class, Attribute, Param, Return]+++ ADDED
@@ -0,0 +1,264 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ We have previously used "generic type definitions",
2
+ for example, when creating objects from classes 'ArrayList' and 'HashMap', and when writing classes that implement the 'Comparable' interface.
3
+
4
+ public static void main(String[] args) {
5
+ // generic type definition: the list can now store
6
+ // integers
7
+ ArrayList<Integer> numbers = new ArrayList<>();
8
+
9
+ // two generic type definitions: one for the key
10
+ // and one for the value
11
+ HashMap<String, Student> tutors = new HashMap<>();
12
+ }
13
+
14
+
15
+
16
+
17
+ We can also utilise generic type definitions in our own classes and interfaces.
18
+
19
+ As the name suggests, a 'generic type definition' is a 'type definition'.
20
+ Normally, we write a variable that gets a value, for example,
21
+ - when calling a method or
22
+ - when creating an object from a class.
23
+
24
+ In a 'type definition', instead, we write 'a variable that gets a type only when it is used'.
25
+ Thus, we 'generalise the type of the variable' instead of the value.
26
+
27
+ In practice, this means that we can write a class,
28
+ for example, whose attributes are of different types when different objects are formed from the class.
29
+
30
+
31
+
32
+ ==============================
33
+
34
+
35
+
36
+ Generic Type Definition in Own Class
37
+ A 'generic type' can be defined in our own class by writing the type as a variable in connection with the class definition.
38
+ Let's look at the class Box, which stores one value:
39
+
40
+ class Box<TYPE> {
41
+ private TYPE value;
42
+
43
+ public Box(TYPE value) {
44
+ this.value = value;
45
+ }
46
+
47
+ public TYPE getValue() {
48
+ return value;
49
+ }
50
+
51
+ public void setValue(TYPE value) {
52
+ this.value = value;
53
+ }
54
+ }
55
+
56
+
57
+ Instead of defining the type of the stored value, we defined the type with a 'generic type definition'.
58
+ In this context, the variable 'TYPE' means that we 'define the actual type only when an object is created from the class'.
59
+ The same type has also been used in
60
+ - the constructor and
61
+ - in the class's setting and observation methods.
62
+
63
+
64
+
65
+
66
+
67
+
68
+ Let's look at a few usage cases for the class:
69
+
70
+ public static void main(String[] args) {
71
+ // Integer type
72
+ // create Box object, then put in an Integer
73
+ Box<Integer> numberBox = new Box<>(15);
74
+ System.out.println(numberBox.getValue());
75
+ numberBox.setValue(20 + 30);
76
+ System.out.println(numberBox.getValue());
77
+
78
+ // String type
79
+ // create Box object, then put in a String
80
+ Box<String> wordBox = new Box<>("Java");
81
+ System.out.println(wordBox.getValue());
82
+ wordBox.setValue("Hello " + "everyone" + "!!!");
83
+ System.out.println(wordBox.getValue());
84
+
85
+
86
+ // Student type
87
+ // INITIALISE Student object
88
+ Student s = new Student("Oliver", "oliver@example.com", 15);
89
+ // then put inside the 'Box' object u create
90
+ Box<Student> studentBox = new Box<>(s);
91
+ System.out.println(studentBox.getValue().getName());
92
+ }
93
+
94
+
95
+ The program prints:
96
+ 15
97
+ 50
98
+ Java
99
+ Hello everyone!!!
100
+ Oliver
101
+
102
+
103
+
104
+
105
+ ===================================================================
106
+
107
+
108
+ Although the previous example serves its purpose,
109
+ the class Box is no more beneficial in practice than a single variable.
110
+
111
+ Therefore, let's consider a genuinely more useful case, i.e. a class that combines two values.
112
+
113
+ class KeyAndValue<KEYTYPE, VALUETYPE> {
114
+ private KEYTYPE key;
115
+ private VALUETYPE value;
116
+
117
+ // constructor
118
+ public KeyAndValue(KEYTYPE key, VALUETYPE value) {
119
+ this.key = key;
120
+ this.value = value;
121
+ }
122
+
123
+
124
+
125
+
126
+ public KEYTYPE getKey() {
127
+ return key;
128
+ }
129
+
130
+ public void setKey(KEYTYPE key) {
131
+ this.key = key;
132
+ }
133
+
134
+
135
+
136
+
137
+ public VALUETYPE getValue() {
138
+ return value;
139
+ }
140
+
141
+ public void setValue(VALUETYPE value) {
142
+ this.value = value;
143
+ }
144
+ }
145
+
146
+
147
+ The types of values are given only when an object is created from the class:
148
+ public static void main(String[] args) {
149
+ KeyAndValue<Integer, Double> kv = new KeyAndValue<>(10, 100.0);
150
+ System.out.println(kv.getKey());
151
+ System.out.println(kv.getValue());
152
+ }
153
+
154
+ The program prints:
155
+ 10
156
+ 100.0
157
+
158
+
159
+
160
+
161
+
162
+
163
+
164
+ ===================================================================
165
+
166
+ Let's consider 1 more example.
167
+
168
+ The class 'Stack' defines a data structure
169
+ where values are added and removed from the top of the stack.
170
+ As a point of comparison, you can think of a stack of papers.
171
+ https://ville.utu.fi/static_resources/erkki/stack.png
172
+
173
+
174
+
175
+ We use a list to store the stack's values.
176
+ We utilise generality again in defining the class,
177
+ so we can conveniently 'store any type of values in the stack':
178
+
179
+ class Stack<T> {
180
+ private ArrayList<T> elements;
181
+
182
+ public Stack() {
183
+ elements = new ArrayList<>();
184
+ }
185
+
186
+ // Always add to the end of the list
187
+ public void add(T element) {
188
+ elements.add(element);
189
+ }
190
+
191
+
192
+ // ArrayList remove()
193
+ // => pops/removes the element => then retrieves it
194
+ // Likewise, always remove from the end of the list
195
+ public T remove() {
196
+ return elements.remove(elements.size() - 1);
197
+ }
198
+
199
+ public boolean hasElements() {
200
+ return !elements.isEmpty();
201
+ }
202
+ }
203
+
204
+
205
+
206
+
207
+ An example of using the Stack class:
208
+ class Stack<T> {
209
+ public static void main(String[] args) {
210
+ Stack<String> stringStack = new Stack<>();
211
+ stringStack.add("first");
212
+ stringStack.add("second");
213
+ stringStack.add("third");
214
+
215
+ while(stringStack.hasElements()) {
216
+ System.out.println(stringStack.remove());
217
+ }
218
+ }
219
+
220
+
221
+ The program prints:
222
+ third
223
+ second
224
+ first
225
+
226
+
227
+
228
+
229
+
230
+
231
+ =========
232
+
233
+
234
+ // recap
235
+ // ArrayList remove()
236
+ // => pops/removes the element => then retrieves it
237
+
238
+
239
+ import java.util.ArrayList;
240
+
241
+ public class Main {
242
+ public static void main(String[] args) {
243
+ ArrayList<Integer> list = new ArrayList<Integer>(); // Change to Integer type
244
+ list.add(5);
245
+ list.add(8);
246
+ list.add(9);
247
+ list.add(1);
248
+
249
+ //list.remove(Integer.valueOf(1)); // Remove by object
250
+ //list.remove(1); // Remove by index
251
+
252
+ System.out.println(list);
253
+ int element = list.remove(2);
254
+ System.out.println(element);
255
+ System.out.println(list);
256
+ }
257
+ }
258
+
259
+
260
+ Output:
261
+ [5, 8, 9, 1]
262
+ 9 <= pop/remove idx 2
263
+ [5, 8, 1]
264
+