简体   繁体   中英

HashTable of Array of LinkList

im trying to make a linked list of generic objects. i have the linked list made now i have to load a file of movies(in movie class i have genre,rating, title).first i need to load a CVS file of movies the create Hash Table Object which contains an array of Linked List objects which in turn stores the Movies. so for example in a movie class i will have genre and genre can be many. i want to get hash code of genre and then store that in a hash table of arrayed linked list. that's what im using the LoadingMovie class for.

i dont know what im doing as it my first time working with hash tables and link list etc.this is what i have so far:

    public class List<T> {
    private Node<T> head;

    private Node<T> tail;
    private int count;

    public void append(T d) {
        if (head == null) {
            head = tail = new Node<T>(d);
        } else {
            tail.insertAfter(d);
            tail = tail.getNext();
            count++;
        }
    }

    public void prepend(T d) {
        if (head == null) {
            head = tail = new Node<T>(d);
        } else {
            head.insertBefore(d);

            head = head.getPrevious();

            count++;
        }
    }

    public void removeHead() {
        if (head == null) {
            return;
        } else if (head == tail) {
            head = tail = null;
            count--;
            return;
        }
        head = head.getNext();
        count--;
    }

    public ListIterator<T> getIterator() {
        return new ListIterator<T>(this, head);
    }

    public void add(ListIterator<T> iter, T data) {
        if (iter.getList() != this) {
            return;
        }
        if (!iter.isValid()) {
            append(data);
        } else {
            iter.getCurrentNode().insertAfter(data);
            count++;
            if (iter.getCurrentNode() == tail) {
                tail = iter.getCurrentNode().getNext();
            }
        }
    }

    public void remove(ListIterator<T> iter) {
        if (iter.getList() != this) {
            return;
        }
        Node<T> node = iter.getCurrentNode();
        if (node == null) {
            return;
        } else if (node == head) {
            removeHead();
        } else if (node == tail) {
            removeTail();
        } else {
            Node<T> ptn = node.getPrevious();
            ptn.setNext(node.getNext());
            node.getNext().setPrevious(ptn);
            iter.advance();
            count--;
        }
    }

    public void removeTail() {
        if (head == null) {

        } else if (head == tail) {
            head = tail = null;
            count--;
        } else {
            Node<T> node = head;
            while (node.getNext() != tail) {
                node = node.getNext();

            }

            tail = node;
            tail.setNext(null);
            count--;

        }
    }

    public void display() {
        ListIterator<T> iter = getIterator();

        do {
            System.out.println(iter.item()+ " , ");
            iter.advance();
        } while (iter.isValid());
    }

    public void displayReverse() {
        ListIterator<T> iter = getIterator();
        iter.end();

        do {
            System.out.print(iter.item() + " , ");
            iter.previous();
        } while (iter.isValid());
    }


    public Node<T> getHead() {
        return head;
    }

    public Node<T> getTail() {
        return tail;
    }

    public int getCount() {
        return count;
    }

    public void setHead(Node<T> head) {
        this.head = head;
    }

    public void setTail(Node<T> tail) {
        this.tail = tail;
    }

    public void setCount(int count) {
        this.count = count;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 89 * hash + Objects.hashCode(this.head);
        hash = 89 * hash + Objects.hashCode(this.tail);
        hash = 89 * hash + this.count;
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final List<?> other = (List<?>) obj;
        if (!Objects.equals(this.head, other.head)) {
            return false;
        }
        if (!Objects.equals(this.tail, other.tail)) {
            return false;
        }
        if (this.count != other.count) {
            return false;
        }
        return true;
    }

this is the node class :

    public class Node<T> {

    T anElement;
    Node<T> next;
    Node<T> previous;

    public Node() {
        anElement = null;
        next = null;
    }

    public Node(T elem) {
        anElement = elem;
        next = null;
    }

    public T getAnElement() {
        return anElement;
    }

    public void setAnElement(T anElement) {
        this.anElement = anElement;
    }

    public Node<T> getNext() {
        return next;
    }

    public void setNext(Node<T> next) {
        this.next = next;
    }

    public Node<T> getPrevious() {
        return previous;
    }

    public void setPrevious(Node<T> previous) {
        this.previous = previous;
    }

    @Override
    public String toString() {
        return "MyNode{" + "anElement=" + anElement + ", next=" + next + '}';
    }

    public void insertAfter(T nextData) {
        if (nextData == null) {
            return;
        }
        Node s = new Node(nextData);
        s.setNext(next);
        s.setPrevious(this);
        if (next != null) {
            next.setPrevious(s);
        }

        next = s;

    }

    public void insertBefore(T data) {
        if (data == null) {
            return;
        }
        Node s = new Node(data);
        s.setNext(this);
        s.setPrevious(previous);

        if (previous != null) {
            previous.setNext(s);
        }

        previous = s;

    }

}

this is the load file class :

    public class LoadingMovies {

    private static final int size = 127;
    private static HashMap<String, Movies> hash = new HashMap(size);
    public static void loadMovies(String filename) {
        String split = ","; //split with comma

        try {

            Scanner in = new Scanner(new File(filename));

            String wordIn;


            //List<Movies> linked = new List<>();

            while (in.hasNextLine()) {
                wordIn = in.nextLine();
                String splitter[] = wordIn.split(split);

                String movieTitle = splitter[0];
                String movieGenre = splitter[1];
                String ageRating = splitter[2];
                double scoreRating = Double.parseDouble(splitter[3]);

                Movies movie = new Movies();
                movie.setTitle(movieTitle);
                movie.setGenre(movieGenre);
                movie.setAgeRating(ageRating);
                movie.setScoreRating(scoreRating);

                hash.find(movie.getGenre()); 
                hash.insert(movie.getGenre(), movie);
                hash.display();

            }

        } catch (FileNotFoundException e) {
            System.out.println("Exception occured in the loadMovies() method in the Loadingovies class");
        }

    }

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);

        String filename = input.next();
        loadMovies(filename);
    }

this is the hash map method:

    public class HashMap<KeyType,DataType>
{
    private int count;
    private int size;
    private List<HashEntry<KeyType,DataType>> [] table;

    public HashMap() {
    }

    public HashMap(int num)
    {
        size = num;
        table = new List[num];
        for(int i = 0; i < num; i++){
            table[i] = new List<HashEntry<KeyType,DataType>>();
        }
    }

    public void insert(KeyType key, DataType data){
        if(key != null && data != null){
            int hash = key.hashCode() % size;
            HashEntry<KeyType, DataType> obj = new HashEntry(key, data);
            table[hash].append(obj);
            count++;
        }
    }

    public void display(){
      for(int i = 0 ; i < size; i++){
          System.out.println("tables" + i + " ");
          table[i].display();
      }
    }

    public DataType find(KeyType key){
        int hash = key.hashCode() % size;
        List<HashEntry<KeyType,DataType>> list = table[hash];
        ListIterator <HashEntry<KeyType, DataType>> iter = list.getIterator();

        while(iter.isValid()){
            if(iter.item().getKey().equals(key)){
                return iter.item().getData();
            }
            iter.advance();
        }
        return null;
    }

   public void remove(KeyType key){
        int hash = key.hashCode() % size;
        List<HashEntry<KeyType,DataType>> list = table[hash];
        ListIterator <HashEntry<KeyType, DataType>> iter = list.getIterator();

        while(iter.isValid()){
            if(iter.item().getKey().equals(key)){
                list.remove(iter);
            }
            iter.advance();
        }
    }
}

and this is what i have for movie class:

    public class Movies {

    private String title;
    private String genre;
    private String ageRating;
    private double scoreRating;

    public Movies() {
        title = "";
        genre = "";
        ageRating = "";
        scoreRating = 0;
    }

    public Movies(String title, String genre, String ageRating, double scoreRating) {
        this.title = title;
        this.genre = genre;
        this.ageRating = ageRating;
        this.scoreRating = scoreRating;
    }

    public String getTitle() {
        return title;
    }

    public String getGenre() {
        return genre;
    }

    public String getAgeRating() {
        return ageRating;
    }

    public double getScoreRating() {
        return scoreRating;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public void setGenre(String genre) {
        this.genre = genre;
    }

    public void setAgeRating(String ageRating) {
        this.ageRating = ageRating;
    }

    public void setScoreRating(double scoreRating) {
        this.scoreRating = scoreRating;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Movies other = (Movies) obj;
        if (!Objects.equals(this.title, other.title)) {
            return false;
        }
        if (!Objects.equals(this.genre, other.genre)) {
            return false;
        }
        if (!Objects.equals(this.ageRating, other.ageRating)) {
            return false;
        }
        if (Double.doubleToLongBits(this.scoreRating) != Double.doubleToLongBits(other.scoreRating)) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 11;

        hash = (int) ((hash * 10) + scoreRating);

        if (this.title != null) {
            hash = (hash * 10) + title.hashCode();
        }
        if (this.genre != null) {
            hash = (hash * 10) + genre.hashCode();
        }
        if (this.ageRating != null) {
            hash = (hash * 10) + ageRating.hashCode();
        }

        return hash;
    }

    @Override
    public String toString() {
        String statement = "Movie Title:" + title + "\n" + "Movie Genre:" + genre + "\n" + "Age Rating: " + ageRating + "\n" + "User Score: " + scoreRating + "\n";
        return statement;
    }

what am i doing wrong please :( i get null pointer exceptions arrayoutofboundexceptions some movies printing and i get loads of tables thatare null :'(

The problem here is in mapping objects to buckets. This line of code...

int hash = key.hashCode() % size;

is capable of producing a negative value. key.hashCode() can be a negative number, and the result of the % operator on a negative number is a negative number. That's what causes your ArrayIndexOutOfBounds exception. The simplest solution is to use the absolute value of the hashCode...

int hash = Math.abs(key.hashCode()) % size;

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