User Tools

Site Tools


java:inner_classes

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
java:inner_classes [2018/03/21 07:42] gthanosjava:inner_classes [Unknown date] (current) – external edit (Unknown date) 127.0.0.1
Line 1: Line 1:
 ====== Μη στατικές εμφωλευμένες κλάσεις ====== ====== Μη στατικές εμφωλευμένες κλάσεις ======
  
-Οι μη στατικές εμφωλευμένες κλάσεις ή εσωτερικές κλάσεις (inner classes) αποτελούν την γενικότερη περίπτωση εμφώλευσης μίας κλάσης μέσα σε μία άλλη κλάση. Ας υποθέσουμε ότι θέλουμε να κατασκευάσουμε μία διπλά συνδεδεμένη λίστα η οποία μπορεί να αποθηκεύσει οποιονδήποτε τύπο όμοιων αντικειμένων. +Οι μη στατικές εμφωλευμένες κλάσεις ή εσωτερικές κλάσεις (inner classes) αποτελούν την γενικότερη περίπτωση εμφώλευσης μίας κλάσης μέσα σε μία άλλη κλάση. Ένας συνήθης λόγος (αλλα όχι ο μοναδικός) για τον οποίο επιδιώκουμε να χρησιμοποιήσουμε εμφωλευμένες κλάσεις είναι όταν θέλουμε να ορίσουμε επιπλέον κλάσεις των οποίων δεν θέλουμε ή δεν έχουμε λόγο να αποκαλύψουμε ότι υπάρχουν. Για παράδειγμα, ας υποθέσουμε ότι θέλουμε να κατασκευάσουμε μία διπλά συνδεδεμένη λίστα η οποία μπορεί να αποθηκεύσει οποιονδήποτε τύπο όμοιων αντικειμένων. 
-Η λίστα θα χρειαστεί να έχει δύο βοηθητικές κλάσεις +Η λίστα θα χρειαστεί να έχει τις βοηθητικές κλάσεις 
   - την κλάση που περιγράφει τον κόμβο της λίστας και    - την κλάση που περιγράφει τον κόμβο της λίστας και 
   - μία κλάση τύπου //iterator// για την διάτρεξη της λίστας   - μία κλάση τύπου //iterator// για την διάτρεξη της λίστας
-Οι δύο παραπάνω κλάσεις εξυπηρετεί να δηλωθούν ως εσωτερικές κλάσεις αποκρύπτοντας την υλοποίηση των κλάσεων αυτών. Το παραπάνω επιτρέπει η λίστα να είναι συμβατή με τα interfaces [[http://docs.oracle.com/javase/8/docs/api/java/util/List.html|java.util.List]] και [[http://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html|java.util.Iterator]]. Δείτε τον παρακάτω κώδικα που την υλοποιεί.+Οι δύο παραπάνω κλάσεις εξυπηρετεί να δηλωθούν ως εσωτερικές κλάσεις αποκρύπτοντας την ύπαρξη τους. Ο χρήστης της κλάσης απαιτείται μόνο να γνωρίζει την κλάση της λίστας και πως μπορεί να διαχειριστεί ένα αντικείμενο τύπου [[http://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html|java.util.Iterator]]. Όλα τα υπόλοιπα είναι λεπτομέρειες τα οποία δεν αφορούν τον προγραμματιστή-χρήστη της κλάσης.  
 + 
 +Δείτε τον παρακάτω κώδικα που την υλοποιεί.
  
 <code java LinkedList.java> <code java LinkedList.java>
 +/* A linked list with sentinels at head and tail.
 + */
 public class LinkedList<E> { public class LinkedList<E> {
   private Node<E> head, tail;   private Node<E> head, tail;
 +  int size;
      
   public LinkedList() {   public LinkedList() {
Line 15: Line 20:
     tail = new Node<>(null, head, null);     tail = new Node<>(null, head, null);
     head.setNext(tail);     head.setNext(tail);
 +    size = 0;
   }   }
      
Line 27: Line 33:
     }     }
          
-    public Node<E> getNext() {return next;}+    public Node<E> getNext() { return next;}
     public void setNext(Node<E> nxt) { next = nxt; }     public void setNext(Node<E> nxt) { next = nxt; }
     public Node<E> getPrev() {return prev;}     public Node<E> getPrev() {return prev;}
Line 35: Line 41:
   }   }
      
-  private class Iterator<E> implements java.util.Iterator {+  private class Iterator<E> implements java.util.Iterator<E> {
     Node<E> curr;     Node<E> curr;
 +    
     public Iterator(Node<E> c) {     public Iterator(Node<E> c) {
       curr = c;       curr = c;
Line 52: Line 59:
       curr.getPrev().setNext(curr.getNext());       curr.getPrev().setNext(curr.getNext());
       curr.getNext().setPrev(curr.getPrev());       curr.getNext().setPrev(curr.getPrev());
-      curr = null;+      curr = curr.getPrev();
     }     }
   }   }
Line 61: Line 68:
      
   // append in the end   // append in the end
-  public void add(E elem) {+  public boolean add(E elem) {
     Node<E> plus = new Node<E>(tail, tail.getPrev(), elem);     Node<E> plus = new Node<E>(tail, tail.getPrev(), elem);
     tail.getPrev().setNext(plus);     tail.getPrev().setNext(plus);
     tail.setPrev(plus);     tail.setPrev(plus);
 +    size++;
 +    return true;
 +  }
 +  
 +  public boolean add(int index, E elem) {
 +    if(index>size)
 +      return false;
 +    Node<E> curr = head.next;
 +    for(int i=0; curr != tail && i<index; i++) {
 +      curr = curr.next;
 +    }
 +    Node<E> plus = new Node<E>(curr, curr.prev, elem);
 +    curr.prev.next = plus;
 +    curr.prev = plus;
 +    size++;
 +    return true;
   }   }
      
Line 87: Line 110:
     }     }
     return -1;     return -1;
 +  }
 +  
 +  int size() {
 +    return size;
   }   }
 } }
Line 92: Line 119:
  
 Το παρακάτω πρόγραμμα επιχειρεί να δημιουργήσει μία λίστα με 20 τυχαίους αριθμούς και στη συνέχεια να τους εκτυπώσει χρησιμοποιώντας τον Iterator της λίστας. Παρατηρήστε ότι σε κανένα σημείου του προγράμματος δεν αποκαλύπτεται η ύπαρξη των εσωτερικών κλάσεων //Node// και //Iterator//. Η μεταβλητή //it// παραπέμπει στο interface [[http://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html|java.util.Iterator]]. Το παρακάτω πρόγραμμα επιχειρεί να δημιουργήσει μία λίστα με 20 τυχαίους αριθμούς και στη συνέχεια να τους εκτυπώσει χρησιμοποιώντας τον Iterator της λίστας. Παρατηρήστε ότι σε κανένα σημείου του προγράμματος δεν αποκαλύπτεται η ύπαρξη των εσωτερικών κλάσεων //Node// και //Iterator//. Η μεταβλητή //it// παραπέμπει στο interface [[http://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html|java.util.Iterator]].
 +
 +<code java LinkedListUsage.java>
 +import java.util.*;
 +
 +public class LinkedListUsage {
 +  public static final int SIZE = 16;
 +  public static final int RANGE = 8 * SIZE;
 +  
 +  static void print(LinkedList<Integer> list){
 +    Iterator<Integer> it = list.iterator();
 +    
 +    // Print list
 +    while(it.hasNext()) {
 +      System.out.print(it.next()+"  ");
 +    }
 +    System.out.println();
 +  }
 +  
 +  public static void main(String[] args) {
 +    Random rand = new Random( new Date().getTime());
 +    LinkedList<Integer> list = new LinkedList<>();
 +    for(int i=0; i<SIZE; i++) {
 +      int value = rand.nextInt(RANGE);
 +      int pos = rand.nextInt(list.size()+1); 
 +      System.out.format("Adding %d at %d\n", value, pos);
 +      list.add(pos,value);
 +      print(list);
 +    }
 +    print(list);
 +    
 +    // Remove all elements less than RANGE/2
 +    System.out.println("Remove values < "+RANGE/2);
 +    Iterator<Integer> it = list.iterator();
 +    while(it.hasNext()) {
 +      int value = it.next();
 +      //System.out.println("value: "+value);
 +      if(value < RANGE/2) {
 +        //System.out.println("RMV: "+value);
 +        it.remove();
 +      }
 +    }
 +    print(list);
 +    
 +  }
 +}
 +
 +</code>
  
 <WRAP todo center 80% round> **Εργασία για το σπίτι:** Επιχειρήσετε να συμπληρώσετε την κλάση LinkedList ώστε να ικανοποιεί το interface [[http://docs.oracle.com/javase/8/docs/api/java/util/List.html|java.util.List]]. <WRAP todo center 80% round> **Εργασία για το σπίτι:** Επιχειρήσετε να συμπληρώσετε την κλάση LinkedList ώστε να ικανοποιεί το interface [[http://docs.oracle.com/javase/8/docs/api/java/util/List.html|java.util.List]].
java/inner_classes.1521618122.txt.gz · Last modified: 2018/03/21 07:42 by gthanos