【问题标题】:Scrabblecheater in Java: How to correctly write to a nested ArrayListJava 中的 Scrabblecheater:如何正确写入嵌套的 ArrayList
【发布时间】:2011-01-08 16:12:21
【问题描述】:

我们必须编写一个基本程序,它应该从文件中读取一个单词表,找到单词的排列,并将所有具有相同规范化版本的单词一起存储在一个链中。标准化版本始终位于链的顶部。 规范化的单词应用作索引键,而单词的排列应作为给定 hsah 位置的字符串数组返回。

我们尝试使用嵌套的 ArrayList 来实现索引键的存储和排列。

 private File testfile = new File("wordlist.txt");
 private ArrayList<ArrayList<String>>[] table;
 int entries = 0;

 public Dictionary(int size) {
  table = new ArrayList[size];
  for (int i = 0; i < size; i++)
   table[i] = new ArrayList<ArrayList<String>>(99);
 }

 public void newDictionary() {
  for (int i = 0; i < table.length; i++)
   table[i] = new ArrayList<ArrayList<String>>(99);
 }

我们的哈希函数如下所示:

    public void hash(String word) {

  word = word.toLowerCase();
  String id = normalize(word);
  int hashValue = 0;
  char[] chars = word.toCharArray();

  for (int i = 0; i < chars.length; i++) {
   int e = chars[i] - 97;
   hashValue += e * 26 ^ i;
  }

  if (hashValue < 0)
   hashValue = hashValue * (-1);
  ArrayList<ArrayList<String>> chain = table[hashValue];


  boolean newList = true;
  boolean cB = chain.isEmpty();

  if (chain.size() > 0) {
   for (int i = 0; i < chain.size(); i++) {
    ArrayList<String> currentChain = chain.get(i);

    try {
     String a = currentChain.get(0);
     System.out.println(a);
    } catch (Exception e) {
     System.out.println("ERROR!");
    }

   }
  }
  if (newList == true || chain.size() == 0) {
   chain.add(new ArrayList<String>());
   chain.get(0).add(0, id);
   chain.get(0).add(word);
  }
 }

我们假设我们正确实现了嵌套的 ArrayList,但是在尝试访问 ArrayList&lt;ArrayList&lt;String&gt;&gt; chain = table[hashValue]; 时,例如通过调用boolean cB = chain.isEmpty();,我们的程序崩溃了。

除此之外,我们无法打印出currentChain 中索引 0 处的所有值。 我们用 try-catch 块包围了各自的打印方法,否则我们的程序会崩溃;现在,我们的程序运行了,但很少输出一个字符串,而是在运行打印方法时抛出一个异常:

 try {
     String a = currentChain.get(0);
     System.out.println(a);
    } catch (Exception e) {
     e.printStackTrace();
    }

stacktrace 输出如下错误:

java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
    at java.util.ArrayList.RangeCheck(ArrayList.java:547)
    at java.util.ArrayList.get(ArrayList.java:322)
    at Dictionary.hash(Dictionary.java:78)
    at Dictionary.readFromFile(Dictionary.java:32)
    at Main.main(Main.java:9)

我们对以下Index: 0, Size: 0感到很困惑

我们是否正确实现了嵌套的ArrayLists? 大多数时候我们无法在 ArrayList 中正确存储字符串的原因可能是什么?

【问题讨论】:

  • 这是实现异常“处理”的一种非常糟糕的方式。通过添加那些无用的 try/catch 块,你会让事情变得更难。如果您坚持添加它们,那么您应该至少打印堆栈跟踪。但是最好捕获你不能做有用的事情的异常。
  • Stacktrace 可能是个好主意,谢谢
  • 好的,我添加了堆栈跟踪的输出。
  • 异常告诉你你正在尝试访问一个空列表(大小为 0)的第一个元素(索引为 0 的元素)。

标签: java arraylist hashtable


【解决方案1】:

Mutimap 是您要查找的数据结构。

类似于地图的集合,但 可能关联多个值 用一把钥匙。如果你调用 put(K, V) 两次,使用相同的密钥,但 不同的值,多​​图 包含从键到两者的映射 价值观。

【讨论】:

    【解决方案2】:

    如果您想修复您的代码,那么您需要知道数组列表的元素在未初始化时是未初始化的。

    改变构造函数和newDictionary()方法:

      public Dictionary(int size) {
            //noinspection unchecked
            table = new ArrayList[size];
    
            newDictionary();
        }
    
        public void newDictionary() {
            for (int i = 0; i < table.length ; i++) {
                table[i] = new ArrayList<List<String>>(99);
    
                for ( int j = 0; j < 99; j++ ) {
                    table[i].add(new ArrayList<String>());
                }
            }
        }
    

    我还将表成员的声明更改为:

    private List<List<String>>[] table;
    

    这意味着也将链变量的 decalration 从哈希方法更新为 this

    List<List<String>> chain = table[hashValue];
    

    享受吧。

    【讨论】:

      猜你喜欢
      • 2022-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-09
      • 1970-01-01
      • 2016-01-21
      • 1970-01-01
      • 2021-12-14
      相关资源
      最近更新 更多