我应该使用HashMap,List还是其他什么?

时间:2017-01-07 16:25:25

标签: java list arraylist linked-list hashmap

我正在写一个程序

  1. 存储键值对列表(scenario,listOfResults)
  2. 随机模拟新场景,找到结果
  3. 检查方案是否在键值对列表中
  4. 如果是,请更新键值对,以便将新结果添加到列表中
  5. 否则,将场景结果对添加到键值对列表
  6. 重复步骤#2-5
  7. 目前我使用的是HashMap,因为它的键值系统是有意义的。但是,计算似乎需要很长时间,我正在考虑不同的数据结构是否更合适。

    模拟100个场景需要8.623秒,并使HashMap保留4,600个键值对。

    模拟200个场景需要42.690秒,并使HashMap保留9,431个键值对。

    似乎键值对的数量呈线性增长,而时间呈指数增长,很快就会失控。我可能能够进一步优化程序,但我是否完全使用了错误的数据结构?

    更新:我怀疑问题出在我的hashcode()方法上。这是:

    @Override
    public int hashCode() {
        int result = 31 + legalBoard;
        result = result*31 + playerToMove;
        result = result*31 + Arrays.hashCode(getSmallestFieldConfiguration());
        //System.out.println("Hashcode: " + result + " ---------- " + Arrays.toString(field));
        return result;
    }
    

    legalBoard是介于-1和8之间的int。playerToMove是-1或1. field是一个int [81],其值为-1,0和1。 getSmallestConfiguration()方法从数组的每个可能的反射/旋转中找到最小的数组,如下所示:

    public int[] getSmallestFieldConfiguration(){       
        int[] smallestConfig = field;
        for(int[] config : getAllOtherFieldConfigurations()){
            if(isGreater(smallestConfig, config)){
                smallestConfig = config;
            }
        }
        return smallestConfig;
    }
    
    public int[][] getAllOtherFieldConfigurations(){
        int[][] configs = new int[7][];
        int[][] twoDimensionalField = new int[][]{
            {field[0],field[1],field[2],field[3],field[4],field[5],field[6],field[7],field[8]},
            {field[9],field[10],field[11],field[12],field[13],field[14],field[15],field[16],field[17]},
            {field[18],field[19],field[20],field[21],field[22],field[23],field[24],field[25],field[26]},
            {field[27],field[28],field[29],field[30],field[31],field[32],field[33],field[34],field[35]},
            {field[36],field[37],field[38],field[39],field[40],field[41],field[42],field[43],field[44]},
            {field[45],field[46],field[47],field[48],field[49],field[50],field[51],field[52],field[53]},
            {field[54],field[55],field[56],field[57],field[58],field[59],field[60],field[61],field[62]},
            {field[63],field[64],field[65],field[66],field[67],field[68],field[69],field[70],field[71]},
            {field[72],field[73],field[74],field[75],field[76],field[77],field[78],field[79],field[80]},
        };
        /*for(int i=0; i<81; i++){
            twoDimensionalField[i%9][i/9] = field[i];
        }*/
    
        //Reflections
        configs[0] = getFieldFromMatrix(MatrixTransformations.reflectVertical(twoDimensionalField));
        configs[1] = getFieldFromMatrix(MatrixTransformations.reflectHorizontal(twoDimensionalField));
        //Rotations
        int[][] singleRotation = MatrixTransformations.rotate(twoDimensionalField);
        configs[2] = getFieldFromMatrix(singleRotation);
        int[][] doubleRotation = MatrixTransformations.rotate(twoDimensionalField);
        configs[3] = getFieldFromMatrix(doubleRotation);
        configs[4] = getFieldFromMatrix(MatrixTransformations.rotate(doubleRotation));
        //Transpositions
        configs[5] = getFieldFromMatrix(MatrixTransformations.transpose(twoDimensionalField));
        configs[6] = getFieldFromMatrix(MatrixTransformations.transpose(doubleRotation));
    
        return configs;
    }
    

    MatrixTransformations方法如下所示:

    公共类MatrixTransformations {     public MatrixTransformations(){}

    public static int[][] reflectVertical(int[][] arr){
        for(int j=0; j<9; j++){
            for(int k=0; k<4; k++){
                int temp = arr[j][k];
                arr[j][k] = arr[j][3-k];
                arr[j][8-k] = temp;
            }
        }
        return arr;
    }
    public static int[][] reflectHorizontal(int[][] arr){
        for(int j=0; j<4; j++){
            for(int k=0; k<9; k++){
                int temp = arr[j][k];
                arr[j][k] = arr[8-j][k];
                arr[8-j][k] = temp;
            }
        }
        return arr;
    }
    public static int[][] transpose (int[][] array) {
          if (array == null || array.length == 0)//empty or unset array, nothing do to here
            return array;
    
          int width = array.length;
          int height = array[0].length;
    
          int[][] array_new = new int[height][width];
    
          for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
              array_new[y][x] = array[x][y];
            }
          }
          return array_new;
        }
    
    public static int[][] rotate(int[][] arr){
        int[][] newArr = new int[9][9];
        for (int i = 0; i < 9; ++i) {
            for (int j = 0; j < 9; ++j) {
                newArr[i][j] = arr[8 - j][i];
            }
        }
        return newArr;
    }
    }
    

1 个答案:

答案 0 :(得分:0)

可能你应该坚持使用地图。除非你的密钥是连续的1,2,3使用9K的随机数可能会让你没有足够的内存问题。