Java Tutorial/Generics/Generic Class

Материал из Java эксперт
Перейти к: навигация, поиск

Defining a Generic Class Type

import java.awt.Point;
class ListItem {
  public ListItem(Object item) {
    this.item = item;
    next = null;
  }
  public String toString() {
    return "ListItem " + item;
  }
  ListItem next;
  Object item;
}
class LinkedList<T> {
  public LinkedList() {
  }
  public LinkedList(T item) {
    if (item != null) {
      current = end = start = new ListItem(item);
    }
  }
  public LinkedList(T[] items) {
    if (items != null) {
      for (int i = 0; i < items.length; i++) {
        addItem(items[i]);
      }
      current = start;
    }
  }
  public void addItem(T item) {
    ListItem newEnd = new ListItem(item);
    if (start == null) {
      start = end = newEnd;
    } else {
      end.next = newEnd;
      end = newEnd;
    }
  }
  public T getFirst() {
    current = start;
    return start == null ? null : start.item;
  }
  public T getNext() {
    if (current != null) {
      current = current.next;
    }
    return current == null ? null : current.item;
  }
  private ListItem start = null;
  private ListItem end = null;
  private ListItem current = null;
  private class ListItem {
    public ListItem(T item) {
      this.item = item;
      next = null;
    }
    public String toString() {
      return "ListItem " + item;
    }
    ListItem next;
    T item;
  }
}
public class MainClass {
  public static void main(String[] a) {
    LinkedList<Point> polyline = new LinkedList<Point>();
    polyline.addItem(new Point(1, 2));
    polyline.addItem(new Point(2, 3));
    Point p = polyline.getFirst();
    System.out.println(p);
  }
}



java.awt.Point[x=1,y=2]


Generic class Stack

class Stack<E> {
  private final int size;
  private int top;
  private E[] elements;
  public Stack() {
    this(10);
  }
  public Stack(int s) {
    size = s > 0 ? s : 10;
    top = -1;
    elements = (E[]) new Object[size]; // create array
  }
  public void push(E pushValue) {
    if (top == size - 1) // if stack is full
      throw new FullStackException(String.format("Stack is full, cannot push %s", pushValue));
    elements[++top] = pushValue; // place pushValue on Stack
  }
  public E pop() {
    if (top == -1) // if stack is empty
      throw new EmptyStackException("Stack is empty, cannot pop");
    return elements[top--]; // remove and return top element of Stack
  }
}
class EmptyStackException extends RuntimeException {
  public EmptyStackException() {
    this("Stack is empty");
  }
  public EmptyStackException(String exception) {
    super(exception);
  }
}
class FullStackException extends RuntimeException {
  public FullStackException() {
    this("Stack is full");
  }
  public FullStackException(String exception) {
    super(exception);
  }
}
public class MainClass {
  public static void main(String args[]) {
    double[] doubleElements = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6 };
    int[] integerElements = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
    Stack<Double> doubleStack = new Stack<Double>(5);
    Stack<Integer> integerStack = new Stack<Integer>(10);
    // test Push Double
    try {
      System.out.println("\nPushing elements onto doubleStack");
      for (double element : doubleElements) {
        System.out.printf("%.1f ", element);
        doubleStack.push(element);
      }
    } catch (FullStackException fullStackException) {
      System.err.println();
      fullStackException.printStackTrace();
    }
    // test Pop Double
    try {
      System.out.println("\nPopping elements from doubleStack");
      double popValue;
      while (true) {
        popValue = doubleStack.pop(); // pop from doubleStack
        System.out.printf("%.1f ", popValue);
      }
    } catch (EmptyStackException emptyStackException) {
      System.err.println();
      emptyStackException.printStackTrace();
    }
    // test push method with integer stack
    try {
      System.out.println("\nPushing elements onto integerStack");
      for (int element : integerElements) {
        System.out.printf("%d ", element);
        integerStack.push(element);
      }
    } catch (FullStackException fullStackException) {
      System.err.println();
      fullStackException.printStackTrace();
    }
    // test pop method with integer stack
    try {
      System.out.println("\nPopping elements from integerStack");
      int popValue; // store element removed from stack
      // remove all elements from Stack
      while (true) {
        popValue = integerStack.pop();
        System.out.printf("%d ", popValue);
      }
    } catch (EmptyStackException emptyStackException) {
      System.err.println();
      emptyStackException.printStackTrace();
    }
  }
}





Raw type test for a generic Stack

class Stack<E> {
  private final int size;
  private int top;
  private E[] elements;
  public Stack() {
    this(10);
  }
  public Stack(int s) {
    size = s > 0 ? s : 10;
    top = -1;
    elements = (E[]) new Object[size]; // create array
  }
  public void push(E pushValue) {
    if (top == size - 1) // if stack is full
      throw new FullStackException(String.format("Stack is full, cannot push %s", pushValue));
    elements[++top] = pushValue; // place pushValue on Stack
  }
  public E pop() {
    if (top == -1) // if stack is empty
      throw new EmptyStackException("Stack is empty, cannot pop");
    return elements[top--]; // remove and return top element of Stack
  }
}
class EmptyStackException extends RuntimeException {
  public EmptyStackException() {
    this("Stack is empty");
  }
  public EmptyStackException(String exception) {
    super(exception);
  }
}
class FullStackException extends RuntimeException {
  public FullStackException() {
    this("Stack is full");
  }
  public FullStackException(String exception) {
    super(exception);
  }
}
public class MainClass {
  private static Double[] doubleElements = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6 };
  private static Integer[] integerElements = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
  // generic method pushes elements onto stack
  public static <T> void testPush(String name, Stack<T> stack, T[] elements) {
    try {
      System.out.printf("\nPushing elements onto %s\n", name);
      for (T element : elements) {
        System.out.printf("%s ", element);
        stack.push(element);
      }
    } catch (FullStackException fullStackException) {
      System.out.println();
      fullStackException.printStackTrace();
    }
  }
  // generic method testPop pops elements from stack
  public static <T> void testPop(String name, Stack<T> stack) {
    try {
      System.out.printf("\nPopping elements from %s\n", name);
      T popValue;
      while (true) {
        popValue = stack.pop();
        System.out.printf("%s ", popValue);
      }
    } catch (EmptyStackException emptyStackException) {
      System.out.println();
      emptyStackException.printStackTrace();
    }
  }
  public static void main(String args[]) {
    Stack rawTypeStack1 = new Stack(5);
    Stack rawTypeStack2 = new Stack<Double>(5);
    Stack<Integer> integerStack = new Stack(10);
    testPush("rawTypeStack1", rawTypeStack1, doubleElements);
    testPop("rawTypeStack1", rawTypeStack1);
    testPush("rawTypeStack2", rawTypeStack2, doubleElements);
    testPop("rawTypeStack2", rawTypeStack2);
    testPush("integerStack", integerStack, integerElements);
    testPop("integerStack", integerStack);
  }
}





The Run-Time Types of Generic Type Instances

import java.util.LinkedList;
public class MainClass {
  public static void main(String[] args) {
    LinkedList<String> proverbs = new LinkedList<String>();
    LinkedList<Double> numbers = new LinkedList<Double>();
    System.out.println("numbers class name " + numbers.getClass().getName());
    System.out.println("proverbs class name " + proverbs.getClass().getName());
    System.out.println("Compare Class objects: " + numbers.getClass().equals(proverbs.getClass()));
  }
}



numbers class name java.util.LinkedList
proverbs class name java.util.LinkedList
Compare Class objects: true


Use generic method to test generic Stack

// Generic class Stack.
class Stack<E> {
  private final int size;
  private int top;
  private E[] elements;
  public Stack() {
    this(10);
  }
  public Stack(int s) {
    size = s > 0 ? s : 10;
    top = -1;
    elements = (E[]) new Object[size]; // create array
  }
  public void push(E pushValue) {
    if (top == size - 1) // if stack is full
      throw new FullStackException(String.format("Stack is full, cannot push %s", pushValue));
    elements[++top] = pushValue; // place pushValue on Stack
  }
  public E pop() {
    if (top == -1) // if stack is empty
      throw new EmptyStackException("Stack is empty, cannot pop");
    return elements[top--]; // remove and return top element of Stack
  }
}
class EmptyStackException extends RuntimeException {
  public EmptyStackException() {
    this("Stack is empty");
  }
  public EmptyStackException(String exception) {
    super(exception);
  }
}
class FullStackException extends RuntimeException {
  public FullStackException() {
    this("Stack is full");
  }
  public FullStackException(String exception) {
    super(exception);
  }
}
public class MainClass {
  private static Double[] doubleElements = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6 };
  private static Integer[] integerElements = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
  private static Stack<Double> doubleStack = new Stack<Double>(5); // Stack of
                                                                    // Doubles
  private static Stack<Integer> integerStack = new Stack<Integer>(10); // Stack
                                                                        // of
                                                                        // Integers
  // generic method testPush pushes elements onto a Stack
  public static <T> void testPush(String name, Stack<T> stack, T[] elements) {
    try {
      System.out.printf("\nPushing elements onto %s\n", name);
      for (T element : elements) {
        System.out.printf("%s ", element);
        stack.push(element);
      }
    } catch (FullStackException fullStackException) {
      System.out.println();
      fullStackException.printStackTrace();
    }
  }
  // generic method testPop pops elements from a Stack
  public static <T> void testPop(String name, Stack<T> stack) {
    try {
      System.out.printf("\nPopping elements from %s\n", name);
      T popValue;
      while (true) {
        popValue = stack.pop();
        System.out.printf("%s ", popValue);
      }
    } catch (EmptyStackException emptyStackException) {
      System.out.println();
      emptyStackException.printStackTrace();
    }
  }
  public static void main(String args[]) {
    testPush("doubleStack", doubleStack, doubleElements);
    testPop("doubleStack", doubleStack);
    testPush("integerStack", integerStack, integerElements);
    testPop("integerStack", integerStack);
  }
}





Using Primitive Type Wrapper Class Types as Arguments

class ListItem {
  public ListItem(Object item) {
    this.item = item;
    next = null;
  }
  public String toString() {
    return "ListItem " + item;
  }
  ListItem next;
  Object item;
}
class LinkedList<T> {
  public LinkedList() {
  }
  public LinkedList(T item) {
    if (item != null) {
      current = end = start = new ListItem(item);
    }
  }
  public LinkedList(T[] items) {
    if (items != null) {
      for (int i = 0; i < items.length; i++) {
        addItem(items[i]);
      }
      current = start;
    }
  }
  public void addItem(T item) {
    ListItem newEnd = new ListItem(item);
    if (start == null) {
      start = end = newEnd;
    } else {
      end.next = newEnd;
      end = newEnd;
    }
  }
  public T getFirst() {
    current = start;
    return start == null ? null : start.item;
  }
  public T getNext() {
    if (current != null) {
      current = current.next;
    }
    return current == null ? null : current.item;
  }
  private ListItem start = null;
  private ListItem end = null;
  private ListItem current = null;
  private class ListItem {
    public ListItem(T item) {
      this.item = item;
      next = null;
    }
    public String toString() {
      return "ListItem " + item;
    }
    ListItem next;
    T item;
  }
}
public class MainClass {
  public static void main(String[] args) {
    LinkedList<Double> temperatures = new LinkedList<Double>();
    // Insert 6 temperature values 0 to 25 degress Centigrade
    for (int i = 0; i < 6; i++) {
      temperatures.addItem(25.0 * Math.random());
    }
    System.out.printf("%.2f degrees Fahrenheit%n", toFahrenheit(temperatures.getFirst()));
    Double value = null;
    while ((value = temperatures.getNext()) != null) {
      System.out.printf("%.2f degrees Fahrenheit%n", toFahrenheit(value));
    }
  }
  // Convert Centigrade to Fahrenheit
  public static double toFahrenheit(double temperature) {
    return 1.8 * temperature + 32.0;
  }
}



69.27 degrees Fahrenheit
51.55 degrees Fahrenheit
59.97 degrees Fahrenheit
35.82 degrees Fahrenheit
41.28 degrees Fahrenheit
37.99 degrees Fahrenheit