Ένας γενικός τύπος είναι μια γενική κλάση ή διεπαφή που παραμετροποιείται με τύπους. Αυτό επιτρέπει στον μεταγλωττιστή να επιβάλλει ασφάλεια τύπων στην κλάση ή τη διεπαφή.
Δες αυτή τη μη γενική διεπαφή Container:
class Container {
private Object object;
public void set(Object object) { this.object = object; }
public Object get() { return object; }
}
Επειδή δέχεται και επιστρέφει τύπους Object, λειτουργεί με οποιονδήποτε μη πρωτόγονο τύπο.
Ωστόσο, αυτό έχει κόστος, γιατί κάποιος κώδικας μπορεί να καλέσει το get περιμένοντας Integer, ενώ άλλος κώδικας καλεί το set προσθέτοντας String, με αποτέλεσμα μια εξαίρεση κατά τον χρόνο εκτέλεσης.
Μια γενική κλάση και μια γενική διεπαφή έχουν τις ακόλουθες μορφές:
class ClassName<T1, T2, ..., Tn> { ... }
interface InterfaceName<T1, T2, ..., Tn> { ... }
Η ενότητα παραμέτρων τύπου, που οριοθετείται από γωνιακές αγκύλες (<>) και ακολουθεί το όνομα της κλάσης ή της διεπαφής, καθορίζει τις παραμέτρους τύπου (που ονομάζονται και μεταβλητές τύπου) T1, T2, ..., και Tn.
Αυτές μπορούν να χρησιμοποιηθούν μέσα στο σώμα της κλάσης ή της διεπαφής για να έχουμε ασφάλεια γενικών τύπων.
Ακολουθεί η γενική έκδοση του Container:
class Container<E> {
private E object;
public void set(E object) { this.object = object; }
public E get() { return object; }
}
Όταν δημιουργείται, πλέον πρέπει να δηλώσουμε ποιον τύπο περιέχει και ο μεταγλωττιστής θα επιβάλει αυτόν τον περιορισμό:
// empty <> can infer from context
Container<String> stringContainer = new Container<>();
// compiler knows this is a String, so it is allowed
stringContainer.set("Some string");
// no cast needed, compiler knows it is a String
String result = stringContainer.get();
// this causes a compiler error:
stringContainer.set(42);
Οι λίστες είναι η συλλογή διατεταγμένης ακολουθίας στη Java.
Σε αντίθεση με τους πίνακες, μια List μπορεί να αυξηθεί σε μέγεθος για να χωρέσει οποιονδήποτε αριθμό στοιχείων.
Μια τυπική υλοποίηση είναι η ArrayList, η οποία βασίζεται σε έναν πίνακα που μπορεί να αλλάξει μέγεθος.
Άλλη τυπική υλοποίηση είναι η κλάση LinkedList, η οποία βασίζεται σε μια διπλά συνδεδεμένη λίστα.
Οι List μπορούν να είναι κενές ή να περιέχουν οποιονδήποτε αριθμό στοιχείων (συμπεριλαμβανομένων των διπλότυπων).
Οι List είναι μια γενική διεπαφή με τύπο που δηλώνει ποιου τύπου αντικείμενα μπορούν να περιέχουν.
Για παράδειγμα:
List<String> emptyListOfStrings = List.of();
List<Integer> singleInteger = List.of(1);
List<Boolean> threeBooleans = List.of(true, false, true);
List<Object> listWithMultipleTypes = List.of("hello", 1, true);
Οι List έχουν διάφορες χρήσιμες μεθόδους για προσθήκη, αφαίρεση, λήψη και έλεγχο αν υπάρχει ένα στοιχείο:
List<Character> vowels = new ArrayList<>(List.of('a', 'e', 'i', 'o', 'i', 'e', 'a'));
int startingSize = vowels.size(); // 7
vowels.add('u'); // vowels is now ['a', 'e', 'i', 'o', 'i', 'e', 'a', 'u']
char a = vowels.get(0); // 'a'
boolean hadI = vowels.remove('i'); // true and vowels is now ['a', 'e', 'o', 'i', 'e', 'a', 'u']
boolean hasI = vowels.contains('i'); // true (still have one more left)
Ο Karl θέλει να κρατάει μια λίστα με τις γλώσσες που θέλει να μάθει στην ιστοσελίδα Exercism. Ο Karl πρέπει να μπορεί να προσθέτει νέες γλώσσες, να αφαιρεί παλιές και να ελέγχει αν κάποιες γλώσσες βρίσκονται στη λίστα. Θα ήταν πολύ συναρπαστικό αν ο Karl ήθελε να μάθει Java ή Kotlin!
Ο Karl πρέπει να ξέρει αν η λίστα με τις γλώσσες του αδειάσει ποτέ, ώστε να μπορεί να πάει να βρει κι άλλες για να μάθει!
Όρισε μια μέθοδο με το όνομα isEmpty που επιστρέφει true αν δεν υπάρχουν γλώσσες στη λίστα.
if (languageList.isEmpty()) {
findMoreLanguagesToLearn();
}
Ο Karl ανυπομονεί να μάθει Kotlin και Python!
Βοήθησε τον Karl να ξεκινήσει ορίζοντας μια μέθοδο με το όνομα addLanguage, η οποία παίρνει τη γλώσσα που θέλει να μάθει και την προσθέτει στη λίστα.
languageList.addLanguage("Kotlin");
languageList.addLanguage("Python");
Ο Karl αποφάσισε ότι δεν θέλει να μάθει Scala αυτή τη στιγμή.
Βοήθησε τον Karl να τη βγάλει από τη λίστα ορίζοντας μια μέθοδο με το όνομα removeLanguage, η οποία παίρνει τη γλώσσα που αφαιρεί και τη βγάζει από τη λίστα.
languageList.removeLanguage("Scala");
Ο Karl θέλει να θυμάται την πρώτη γλώσσα που πρόσθεσε στη λίστα (αυτή που βρίσκεται ακόμα στη λίστα).
Όρισε μια μέθοδο με το όνομα firstLanguage που επιστρέφει την πρώτη γλώσσα στη λίστα.
String kotlin = languageList.firstLanguage(); // "Kotlin"
Ο Karl πρέπει να ξέρει πόσες γλώσσες προσπαθεί να μάθει.
Βοήθησε τον Karl να βρει την απάντηση ορίζοντας μια μέθοδο με το όνομα count, η οποία επιστρέφει τον αριθμό των γλωσσών στη λίστα.
int two = languageList.count(); // 2
Ο Karl προσπαθεί να θυμηθεί αν ήθελε να μάθει Python ή Ruby.
Όρισε μια μέθοδο με το όνομα containsLanguage που παίρνει τη γλώσσα για την οποία ρωτάει, για να μάθει ο Karl!
boolean learningPython = languageList.containsLanguage("Python"); // true
boolean learningRuby = languageList.containsLanguage("Ruby"); // false
Αν ο Karl θέλει να μάθει Java ή Kotlin, αυτό είναι πολύ συναρπαστικό!
Όρισε μια μέθοδο με το όνομα isExciting που επιστρέφει αληθής αν ο Karl θέλει να μάθει Java ή Kotlin.
javaLanguageList.isExciting() // true
neitherKotlinNorJavaLanguageList.isExciting() // false
Γράψου στο Exercism για να μάθεις και να κατακτήσεις Java με 26 έννοιες158 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.