【问题标题】:Issue with using hashmap使用哈希图的问题
【发布时间】:2017-09-23 12:32:04
【问题描述】:
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;
            }
        }
    }
}

这是我大学作业的简单图书馆管理程序,我只能使用HashMap。 我的问题是,当我尝试加载到目前为止我输入的每一本书时,标题、作者和出版商只来自我注册的第一本书。

所以,澄清一下,例如当我进入了两本书这样的时候,

书 1 标题:一个 作者:A 发布者:A

书2 标题:乙 作者:乙 发布者:B

当我尝试加载到目前为止我输入的每一本书时,结果是这样的,

书 1 标题:一个 作者:A 发布者:A

书2 标题:一个 作者:A 发布者:A

【问题讨论】:

  • 在 for 循环外分配迭代器。

标签: java hashmap


【解决方案1】:

看在怜悯的份上,请用单数命名你的班级!即Book,而不是Books

每个循环都打开一个新的迭代器。相反,使用 foreach 循环:

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
}

或者更好的是迭代这些值:

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

并完全避免查找。

【讨论】:

    【解决方案2】:

    在 Books 中实现 hashCode() 方法,可能是这样的 -

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

    你也应该实现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);
    }
    

    【讨论】:

    • 我是否正确地说不需要Value类来实现hashcode和equals?(在这种情况下是书籍)只有键类(这里是String)应该实现它们。
    • @boxed__l 甚至键类(这里)必须实现它们(重复的哈希只会退化为列表)。这仍然是一个非常非常好的主意。否则我们的代码会很脆弱,请考虑将 Books 添加到 Set 中。
    【解决方案3】:

    当您调用set.iterator() 时,您将创建新的迭代器,它引用第一个元素。因此iter.next() 每次都返回第一个元素。

    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());
        }
    }
    

    【讨论】:

      【解决方案4】:

      正如已经指出的,迭代器不应该在每个循环中重新初始化。它应该只在循环之前初始化一次。

      否则,每次循环执行时,都会从地图的第一项开始。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-21
        • 2018-01-16
        • 2013-03-30
        • 1970-01-01
        相关资源
        最近更新 更多