Muon
Muon

Reputation: 71

Issue with using hashmap

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;

class Books {
    private String title, author, publisher;

    public Books(String title, String author, String publisher) {
        this.title = title;
        this.author = author;
        this.publisher = publisher;
    }

    public String toString() {
        return "\nTitle: " + title + "\nAuthor: " + author + "\nPublisher: " + publisher + "\n";
    }
}

class Collections {
    private String title, author, publisher;

    Scanner sc = new Scanner(System.in);

    static Map<String, Books> hashmap = new LinkedHashMap<String, Books>();

    void reg() {

        System.out.println(">>Please input the Title = ");
        title = sc.nextLine();
        System.out.println(">>Please input Author = ");
        author = sc.nextLine();
        System.out.println(">>Please input Publisher = ");
        publisher = sc.nextLine();

        hashmap.put(title, new Books(title, author, publisher));

        System.out.println();
    }

    Set<String> set = hashmap.keySet();

    void load() {
        for (int i = 0; i < set.size(); i++) {
            System.out.println("Book" + (i + 1) + "\n");

            Iterator<String> iter = set.iterator();

            Books b = hashmap.get(iter.next());

            System.out.println(b.toString());
        }
    }

    void search() {
        System.out.println("Please enter title: ");
        title = sc.nextLine();

        Books b = hashmap.get(title);
        System.out.println(b.toString());
        System.out.println();
    }
}

public class LibraryManage1 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        Collections collections = new Collections();
        boolean run = true;
        int select;

        while (run) {
            System.out.println("--------------------Library Management Program----------------------");
            System.out.printf("1. Book collections\n2. Register new books\n3. Search a book\n4. Exit");
            System.out.println("--------------------------------------------------------------------");
            System.out.println(">>Please select menu : ");

            select = sc.nextInt();

            switch (select) {
                case 1:
                    collections.load();
                    break;
                case 2:
                    collections.reg();
                    break;
                case 3:
                    collections.search();
                    break;
                case 4:
                    System.out.println(">>Thank you for running my program!");
                    run = false;
                    break;
            }
        }
    }
}

This is my simple library management program for my college homework, and I can only use HashMap. My problem is that when I try to load every books that I have entered so far, titles, authors and publishers only come out from the first book I've registered.

So, to clarify myself, for example when I've entered two books like this,

Book1 Title: A Author: A Publisher: A

Book2 Title: B Author: B Publisher: B

when I try to load every books I've entered so far, the result comes out like this,

Book1 Title: A Author: A Publisher: A

Book2 Title: A Author: A Publisher: A

Upvotes: 1

Views: 769

Answers (4)

Sergey Morozov
Sergey Morozov

Reputation: 4608

When you call set.iterator() you create new iterator, that refer on first element. Thus iter.next() return first element every time.

Iterator<String> iter = set.iterator() ;
void load(){
    for(int i = 0 ; i<set.size();i++){
        System.out.println("Book"+(i+1)+"\n");
        //Iterator<String> iter = set.iterator() ;
        Books b = hashmap.get(iter.next());
        System.out.println(b.toString());
    }
}

Upvotes: 2

Bohemian
Bohemian

Reputation: 424953

For mercy's sake, name your class in the singular! ie Book, not Books!

You are opening a new iterator every loop. Instead, use a foreach loop:

int count = 0;
for (String title : set) {
    System.out.println("Book"+(++count)+"\n");
    Books b = hashmap.get(title);
    System.out.println(b); // don't to call `toString()` - println does that for you
}

or better yet iterate over the values:

int count = 0;
for (Book b : hashmap.values()) {
    System.out.println("Book"+(++count)+"\n");
    System.out.println(b);
}

And avoid the lookup altogether.

Upvotes: 4

PNS
PNS

Reputation: 19895

As already pointed out, the iterator should not be re-initialized on every loop. It should only be initialized once, before the loop.

Otherwise, every time the loop is executed, it starts from the first item of the map.

Upvotes: 1

Elliott Frisch
Elliott Frisch

Reputation: 201399

Implement the hashCode() method in Books, something like this perhaps -

public int hashCode() {
  return author.hashCode() ^ title.hashCode() ^ publisher.hashCode();
}

You should also implement equals

public boolean equals(Books in) {
  if (this == in) return true;
  return this.author.equals(in.author) && this.title.equals(in.title) // 
           && this.publisher.equals(in.publisher);
}

Upvotes: 2

Related Questions