简体   繁体   中英

Returning a generic type in Java Hashtables

We're currently studying hashtables in our Java course.

The lecturer has set out a few methods for us to construct. The first two are fine but I'm struggling with "public E max()". Most stuff I have read seems to indicate you can't instantiate a generic type, so I'm struggling to see how I can write this method for a hashtable.

The objective is of course to return the largest value in the hashtable, which I think I could do if the type wasn't generic, but in this case it is.

Apologies if my code is a bit hard to read.

import java.lang.reflect.Array;
import java.util.*;

public class Assignment6_2015 {
public static void main(String[] args){

//=======================================================
// Question 1, test Point class by creating a hashlist of Point instances       

    HashList<Point> h1 = new HashList<Point>(5);
    h1.add(new Point(1,2));
    h1.add(new Point(2,4));
    h1.add(new Point(2,4));
    h1.add(new Point(2,4));
    h1.add(new Point(3,8));
    h1.add(new Point(3,8));
    h1.add(new Point(7,3));
    h1.add(new Point(9,10));
    h1.add(new Point(9,10));
    h1.add(new Point(9,10));
    h1.add(new Point(9,10));
    h1.add(new Point(9,10));
    h1.displayLists();

//=======================================================
// Question 2, testing new methods

    // ----- Frequency Method Test -----
    System.out.println();
    System.out.print("Frequency of Points (9,10): ");
    System.out.println(h1.freq(new Point(9,10)));

    System.out.println();
    System.out.print("Frequency of Points (2,4): ");
    System.out.println(h1.freq(new Point(2,4)));

    System.out.println();
    System.out.print("Frequency of Points (1,2): ");
    System.out.println(h1.freq(new Point(1,2)));
    // ----- End Frequency Method Test -----

    System.out.println();
    System.out.print("Table Size: ");
    System.out.println(h1.tableSize());
    System.out.print("All used?: ");
    System.out.println(h1.allUsed());
    System.out.print("Percentage used?: ");
    System.out.println(h1.percentUsed());
    }
    }

    //=======================================================
    // class Point
    class Point implements Comparable<Point>{
    private int x,y;
    Point(int a, int b){x = a; y = b;}
    public int x(){return x;}
    public int y(){return y;}
    public String toString(){return "("+x+","+y+")";}

    public boolean equals(Object ob){
    Point p = (Point)ob;
    if(x == p.x() && y == p.y()){
        return true;
    }
    else{
        return false;
    }
}

public int compareTo(Point p){
    if(x > p.x() && y > p.y()){
        return 0;
    }
    else{
        return -1;
    }
}

public int hashCode(){
    return x*y*31;
    }
}
   //End class Point
  //=======================================================
  //HashTable class
  class HashList<E extends Comparable<E>>{
  private GLinkedList<E> data[];
  public HashList(int n){
    data = (GLinkedList<E>[])(new GLinkedList[n]);
    for(int j = 0; j < data.length;j++)
        data[j] = new GLinkedList<E>();
}
private int hashC(E x){
    int k = x.hashCode();
    //an alternative is to mask the minus using
    //int k = x.hashCode() & 0x7fffffff;

    int h = Math.abs(k % data.length);
    return(h);
}

public void add(E x){
    int index = hashC(x);
    data[index].add(x);
}

public boolean contains(E x){
    int index = hashC(x);
    return(data[index].contains(x));
}
public void displayLists(){
    for(GLinkedList<E> k : data){
     if(k.length() > 0)
          k.display();
    }
}
public void display(){
    System.out.print("<");
    int ind = 0;
    while(ind < data.length){
        Iterator<E> it = data[ind].iterator();
        while(it.hasNext())
            System.out.print(it.next()+" ");
        ind++;
    }
    System.out.println(">");
}
public int tableSize(){
    return data.length;
}
//===================================================================
//Add new methods for assignment here

public int freq(E x){
    int freq = 0;
    int index = hashC(x);
    for(int j = 0; j < data[index].length();j++){
        if(data[index].contains(x)){
            freq++;
        }
    }
        return freq;
}

public boolean allUsed(){
    int total = data.length;
    int inuse = 0;
    for(int j = 0; j < data.length;j++){
        if(data[j].length() >= 1){
            inuse++;
        }
    }

    if(inuse == total){return true;}
    else{return false;}
}

public E max(){
    int j = 0;
    E y = // ???;
    Iterator<E> it = data[j].iterator();
        while(j<data.length){
            it = data[j].iterator();
            E x = it.next();
            while(it.hasNext()){
                if(data[j].iterator().next().compareTo(x) == 0){
                    x = it.next();
                    y = x;
                }
            }
        j++;
        }
    return y;
}

//int x = (it.next().compareTo(largest));
//if(x == 0){largest = it.next();}




//====================================================================
public double percentUsed(){
    int count = 0;
    for(int j = 0; j < data.length; j++){
        if(data[j].length() > 0)
          count++;
    }
    double p = count *100.0 / data.length;
    return p;
}
public int largestBucket(){
    int max = 0;
    for(int j = 0; j < data.length; j++)
        if(data[j].length() > max) max = data[j].length();
    return max;
}
public int smallestBucket(){
    int min = data[0].length();
    for(int j = 1; j < data.length; j++)
        if(data[j].length() < min) min = data[j].length();
    return min;
}
public int[] listSizes(){
    int n = this.largestBucket();
    int d[] = new int[n+1];
    for(int j = 0; j < d.length; j++) d[j] = 0;
    for(int j = 0; j < data.length; j++){
        int m = data[j].length();
        d[m] = d[m] + 1;
    }
    return d;
}
public int empty(){
    int count = 0;
    for(int j = 0; j < data.length; j++)
        if(data[j].length() == 0) count++;
    return count;
}
public Iterator<E> iterator(){
  ArrayList<E> items = new ArrayList<E>();
  int ind = 0;
  while(ind < data.length){
        Iterator<E> it = data[ind].iterator();
        while(it.hasNext())
            items.add(it.next());
        ind++;
   }
   return items.iterator();
}
}
class GLinkedList<E extends Comparable<E>>{
private Node<E> head = null;//empty list
private int size = 0;
public void add(E x){ //add at head
    Node<E> nw = new Node<E>(x);
    nw.setNext(head);
    head = nw;
    size++;
}

public boolean contains(E x){
    Node<E> k = head;
    boolean found = false;
    while(k != null && !found){
        E kk = k.data();
        if(kk.compareTo(x) == 0) found = true;
        else k = k.next();
    }
    return found;
}

public void remove(E x){
    Node<E> k = head; Node<E> bk = head;
    boolean found = false;
    while(k != null && !found){
        if(k.data().compareTo(x) == 0) found = true;
        else{ bk = k; k = k.next();}
    }
    if(found)
        if(k == head)
            head = k.next();
        else
          bk.setNext(k.next());
}

public int length(){
    return size;
}
public void display(){
    Node<E> k = head;
    System.out.print('[');
    while(k != null){
        if(k.next != null)
           System.out.print(k.data()+", ");
        else
           System.out.print(k.data());
        k = k.next();
    }
    System.out.println(']');
}
public Iterator<E> iterator(){
    return new GIterator<E>(head, size);
}
     private static class GIterator<E extends Comparable<E>> implements Iterator<E>{
    private Node <E> head;
    private int size;
    private int index = 0;
    GIterator(Node<E> h, int s){
        head = h; size = s;
    }
    public boolean hasNext(){
        return index < size;
    }
    public E next(){
        if(index == size) throw new NoSuchElementException();
        E item = head.data();
        head = head.next(); index++;
        return item;
    }
    public void remove(){}
}
}
class Node<E extends Comparable<E>>{
E data;
Node<E> next;
public Node(E  x){
    data = x; next = null;
}
public Node<E> next(){return next;}
public void setNext(Node<E> p){
    next = p;
}
public void set(E x){data = x;}
public E data(){return data;}
}

Currently at the moment, the max() method doesn't work, I've tried out a few things in it but I can't seem to get it to return a generic type no matter what way I approach it.

你为什么不写这个

E y=null;

To clean up your code a little, help reduce complexity and avoid errors, you could use this snippet to iterate over all elements

for ( GLinkedList<E> d : data ) {
  final Iterator<E> it = d.iterator();
  while ( it.hasNext() ) {
    final E currentElement = it.next();

    // Insert logic here!

  }
}

The Point class implements Comparable and since the HashList is composed of objects that are Comparable , you can use this property to compare each Point seen as a Comparable .

The logic of max() is something like:

declare max as a `Comparable` 
for each linked-list `ll` in `data`
   for each element `c` in `ll`
      if `c.compareTo(max) >= 0` then
         max <- c
      endif
   endfor
endfor
return max

You have to handle max initialisation either to null or to a first point in the hashlist, or to some point value that will be always inferior to any point, like Point(Integer.MIN_VALUE, Integer.MIN_VALUE) .

You can edit these two lines in max method in a manner as follows:

E y = (E)data[0]; // ???;
int j = 1;

Above code change will resolve your problem. Also you have to put other null checks and etc. which are mentioned above in comments. like

if(y==null) return null; //since there is no element in the array

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM