比较存储在哈希表java中的对

时间:2010-10-03 04:23:47

标签: java hashtable compare

起初我有一个存储许多数字的2d数组然后我使用了一组hushtables来存储由2d数组的每一行的数字组成的对。 例如,在2d阵列的第一行中,数字是1 2 3 4 5 那么对应该是1,2 1,3 1,4,1,5等。 用于生成对和存储在哈希表中的代码是

     Hashtable [] table=new Hashtable [lineCounter];
    int [] pairCounter=new int[lineCounter];
    for(int i=0;i<lineCounter;i++)
  {
     table[i]=new Hashtable();
     for (int j=0;j<lineitem2[i]-1;j++)
     {
         for(int t=j+1;t<lineitem2[i];t++)
         {
             int firstnum=freItem[i][j];
             int secnum=freItem[i][t];
             String value=firstnum+":"+secnum;
             //System.out.println(firstnum+"``"+secnum);
             table[i].put(pairCounter[i],value);
             pairCounter[i]++;
             //System.out.println(i+":::"+table[i].get(firstnum));
         }
     }
 }

存储每对每行之后,我想比较每一行中的每一对与其他行,以查找该对显示的次数,代码是

Hashtable resulttable=new Hashtable();
   int [] pairresult=new int [lineCounter];

   for(int i=0;i<lineCounter;i++)
   {
           //Set set1 = table[i].entrySet();
        //Iterator it1 = set1.iterator();
        Enumeration keys = table[i].keys();


       //for(int j=i+1;j<lineCounter;j++)
       //{


         while (keys.hasMoreElements())
             {
                int pairs=0;
               //Map.Entry entry1 = (Map.Entry) it1.next();
               int key = (Integer)keys.nextElement();
               String curvalue = (String)table[i].get( key );

               for(int j=i+1;j<lineCounter;j++)
               {

                 //Set set2 = table[j].entrySet();
                 //Iterator it2 = set2.iterator();
                 Enumeration keys2 = table[j].keys();

                 while (keys2.hasMoreElements())
                 {

                   //Map.Entry entry2 = (Map.Entry) it2.next();
                   //System.out.println(entry2.getKey() + " and " + entry2.getValue());
                   int key2 = (Integer)keys2.nextElement();
                   String curvalue2 = (String)table[j].get( key2 );
                   if(curvalue.equals(curvalue2))
                   {
                       pairs++;
                       table[j].remove(key2);
                   }
                 }

                 }
                if(pairs>=0.02*lineCounter)
                {
                  resulttable.put(curvalue,pairs);
                }







            }


   //    }


   }

但是在用输入文件运行之后,我收到了错误:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.lang.StringBuilder.toString(StringBuilder.java:430)

我的比较对的方法有什么问题吗?为什么我得到那个错误 请帮助谢谢。

2 个答案:

答案 0 :(得分:2)

好的,假设您有一个Pair课程如下:

public class Pair {

    private final int value1;
    private final int value2;

    public Pair(int value1, int value2) {
        this.value1 = value1;
        this.value2 = value2;
    }

    public int value1() {
        return value1;
    }

    public int value2() {
        return value2;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + value1;
        result = prime * result + value2;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Pair other = (Pair) obj;
        if (value1 != other.value1)
            return false;
        if (value2 != other.value2)
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "(" + value1 + ", " + value2 + ")";
    }

}

请注意,如果期望Pair类的实例在基于哈希的数据结构中使用时表现正常,则正确实现equals(Object)hashCode()方法很重要(例如: HashtableHashMapHashSetHashMultimapHashMultiset)。

现在,此代码将读入文件(需要Guava libraries

    File file = ...;

    final Map<Pair, Collection<Integer>> lineNumbersByPair = new HashMap<Pair, Collection<Integer>>();

    /*
     * Step 1: Read in the lines, one by one.
     */
    Reader reader = new FileReader(file);
    try {
        BufferedReader bufferedReader = new BufferedReader(reader);
        try {
            String line;

            int lineNumber = 0;
            while ((line = bufferedReader.readLine()) != null) {
                lineNumber++;

                String[] tokens = line.split("\\s+");
                int[] values = new int[tokens.length];

                for (int i = 0; i < tokens.length; i++) {
                    values[i] = Integer.parseInt(tokens[i]);
                }

                for (int i = 0; i < values.length; i++) {
                    for (int j = i + 1; j < values.length; j++) {
                        Pair pair = new Pair(values[i], values[j]);

                        Collection<Integer> lineNumbers;
                        if (lineNumbersByPair.containsKey(pair)) {
                            lineNumbers = lineNumbersByPair.get(pair);
                        } else {
                            lineNumbers = new HashSet<Integer>();
                            lineNumbersByPair.put(pair, lineNumbers);
                        }
                        lineNumbers.add(lineNumber);
                    }
                }
            }
        } finally {
            bufferedReader.close();
        }
    } finally {
        reader.close();
    }

    /*
     * Step 2: Identify the unique pairs. Sort them according to how many lines they appear on (most number of lines to least number of lines).
     */
    List<Pair> pairs = new ArrayList<Pair>(lineNumbersByPair.keySet());
    Collections.sort(
            pairs,
            new Comparator<Pair>() {
                @Override
                public int compare(Pair pair1, Pair pair2) {
                    Integer count1 = lineNumbersByPair.get(pair1).size();
                    Integer count2 = lineNumbersByPair.get(pair2).size();
                    return count1.compareTo(count2);
                }
            }
        );
    Collections.reverse(pairs);

    /*
     * Step 3: Print the pairs and their line numbers.
     */
    for (Pair pair : pairs) {
        Collection<Integer> lineNumbers = lineNumbersByPair.get(pair);
        if (lineNumbers.size() > 1) {
            System.out.println(pair + " appears on the following lines: " + lineNumbers);
        }
    }

在测试中,代码读取的文件包含20,000行,每行包含10个数字,范围介于0到1000之间。

答案 1 :(得分:0)

如果您的代码在较小的数据集上工作,那么可能只是JVM使用的默认64Mb是不够的,当您将-Xmx512m作为参数传递给Java命令行时它是否有效?