遍历列表以搜索重复项

Iterating through a list searching for duplicates

所以我有这个任务,我必须做一个掷骰子,然后搜索某个组合,如果它被掷出。我有一个覆盖的 equals 方法,它检查组合并且它工作正常。 class Dice 中的每个对象都有自己的字符串数组,其中包含关于哪个卷是组合滚动的信息。例如,两个掷骰子的组合 (2, 4) 在第 5 次掷出 5 个骰子时掷出,因此其数组具有:[.., .., .., .., 5] 然后 class Dice 中的每个对象存储在 List<Dice> 中另一方面,它与每个骰子的字符串数组一起放入哈希图中。 我的挣扎是我无法理解如何遍历骰子列表并检查每个组合是否被掷出不止一次并将有关它在哪个掷骰上的信息放入第一个然后删除重复项。

例如,假设组合 (4, 1) 已在第一卷和第四卷上滚动...它的字符串数组应如下所示:[1, .., .., 4, ..],而不是打印hashmap 显示 2 个具有 (4, 1) 组合的元素和它们自己的数组:

[1, .., .., .., ..], [.., .., .., 4, ..].

希望你理解我的挣扎。

public class Dice {
  private int firstDice;
  private int secondDice;
  public String[] rollArray;
  public int roll;
  public int duplicate = 1; 

  /**
   * Constructor for the class Dice.
   * @param first first dice
   * @param second second dice
   */
  public Dice(int first, int second) {
    firstDice = first;
    secondDice = second;
  }

  @Override
  public String toString() {
    return "(" + firstDice + ", " + secondDice + ")";
  }

  /**
   * Method equals used for comparing two objects from the class Dice.
   * @param obj object from dice class
   * @return returns true/false if conditions are matched.
   */
  public boolean equals(Dice obj) {
    return (obj.firstDice == firstDice && obj.secondDice == secondDice);
  }
}



import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

/**
 * Created by leo on 6/10/15. Class which contains all methods that realize the rolling of two dices
 * and storing the information about them in a hash map.
 */
public class DiceRoller {

  public List<Dice> diceList = new LinkedList<>();
  public List<String> rollingList = new LinkedList<>();

  /**
   * A method which rolls two dices a number of times with random values.
   *
   * @param numberOfRolls number of rolls
   */
  public void rollDice(int numberOfRolls) {
    Random rand = new Random();
    for (int i = 0; i < numberOfRolls; i++) {
      diceList.add(i, new Dice(rand.nextInt(7 - 1) + 1, rand.nextInt(7 - 1) + 1));
      diceList.get(i).rollArray = new String[numberOfRolls];
      diceList.get(i).roll = i + 1;
      diceList.get(i).rollArray[i] = diceList.get(i).roll + "";
      rollingList.add("" + (i + 1));
      checkDuplicateDice(diceList, diceList.get(i));
    }
  }


  private void checkDuplicateDice(List<Dice> listOfDice, Dice tempDice) {
    /*
     * for (int i = 0; i < listOfDice.size(); i++) { for (int j = i + 1; j < listOfDice.size(); j++)
     * { if (listOfDice.get(i).toString().equals(listOfDice.get(j).toString())) {
     * listOfDice.get(i).duplicate++; } } } for (int i = 0; i < listOfDice.size(); i++) {
     * System.out.println(listOfDice.get(i).toString() + listOfDice.get(i).duplicate); }
     */
    Iterator<Dice> iter = listOfDice.iterator();
    while (iter.hasNext()) {
      Dice elem = iter.next();
      if (elem.toString().equals(tempDice.toString())) {
        elem.duplicate++;
      }
      System.out.println(elem.toString() + elem.duplicate);
    }
  }

  /**
   * A method which checks if the combination entered is rolled.
   *
   * @param first first dice
   * @param second second dice
   */

  public void checkCombination(int first, int second) {
    Dice checker = new Dice(first, second);
    int index = 1;
    boolean flag = false;
    for (Dice diceObject : diceList) {
      diceObject.rollArray = new String[diceList.toArray().length];
      diceObject.rollArray[index - 1] = index + "";
      for (int i = 0; i < diceList.size(); i++) {
        if (diceObject.rollArray[i] == null) {
          diceObject.rollArray[i] = "..";
        }
      }

      if (diceObject.equals(checker)) {
        System.out.println("Combination: (" + first + ", " + second + ") rolled on roll No: "
            + index);
        flag = true;
      }
      index++;
    }
    if (!flag) {
      System.out.println("Combination not rolled.");
    }
  }

  /**
   * A method which stores the data of the dice and each dice'.
   */
  public void hashMapThingy() {
    System.out.print("Roll: ");
    for (int i = 0; i < rollingList.size(); i++) {
      System.out.print((i + 1) + " ");
    }

    System.out.print("\n");
    System.out.println("Comb:");
    HashMap<Dice, String[]> hm = new HashMap<>();
    for (Dice diceObject : diceList) {
      hm.put(diceObject, diceObject.rollArray);
    }

    Set<Map.Entry<Dice, String[]>> set = hm.entrySet();
    for (Map.Entry<Dice, String[]> me : set) {
      System.out.println(me.getKey() + " " + Arrays.toString(printArray(me.getValue())));
    }
  }

  /**
   * Printer method.
   * 
   * @param array array that contains the roll number
   * @return returns the array string
   */
  public String[] printArray(String[] array) {
    return array;
  }
}


public class Test {
  /**
   * Main function.
   * 
   * @param args arguments
   */
  public static void main(String[] args) {
    int number = 5;
    DiceRoller diceRoller = new DiceRoller();
    diceRoller.rollDice(number);
//    Dice.fillDiceList();

//    Dice.printListDices();
    diceRoller.checkCombination(3, 2);
    diceRoller.checkCombination(1, 3);
    diceRoller.checkCombination(6, 3);
    diceRoller.hashMapThingy();
  }
}

当前控制台输出:

(5, 1)2
(5, 1)2
(1, 1)2
(5, 1)3
(1, 1)2
(5, 1)2
(5, 1)3
(1, 1)2
(5, 1)2
(1, 5)2
(5, 1)3
(1, 1)2
(5, 1)2
(1, 5)2
(4, 4)2
Combination not rolled.
Combination not rolled.
Combination not rolled.
Roll: 1 2 3 4 5 
Comb:
(1, 1) [.., 2, .., .., ..]
(1, 5) [.., .., .., 4, ..]
(5, 1) [1, .., .., .., ..]
(5, 1) [.., .., 3, .., ..]
(4, 4) [.., .., .., .., 5]

问题出在你的 checkDuplicateDice 方法上

  private void checkDuplicateDice(List<Dice> listOfDice, Dice tempDice) {
  boolean duplicate = false;
  for (Dice elem : listOfDice) {
      if (elem.roll != tempDice.roll && elem.toString().equals(tempDice.toString())) {
            elem.duplicate++;
            elem.rollArray[tempDice.roll-1] = tempDice.roll + "";
            duplicate = true;
        }
  }
  if(duplicate)
      listOfDice.remove(tempDice.roll -1);

}

像上面一样,您需要更新您的 rollArray 并将其发回,以便 rollArray 得到更新。

这样做不是最好的方法,但按上面的方法改变会得到你想要的答案

我想知道我是否可以遵循 Sujit Chaitanya 的逻辑,我想为什么不使用方法 return 来自 class 骰子的对象,而不是 void 然后使用该对象安全地删除它而没有例外.. 我稍微修改了一下,结果还不错。

private Dice checkDuplicateDice(List<Dice> listOfDice, Dice tempDice) {

boolean duplicate = false;
for (Dice elem : listOfDice) {
  if (elem.roll != tempDice.roll && elem.toString().equals(tempDice.toString())) {
    elem.rollArray[tempDice.roll - 1] = tempDice.roll + "";
    duplicate = true;
  }
}
if (duplicate) {
  return tempDice;
}
return null;

}

rollDice 方法中,我在第一个循环之后插入了一个新的 for 循环:

for (int j = 0; j < diceList.size(); j++) {
  if (checkDuplicateDice(diceList, diceList.get(j)) != null) {
    diceList.remove(j);
  }
}

我还修改了 checkCombination 方法以不覆盖数组。我添加了一个新的全局变量 listSize ,它在所有骰子都被掷出后立即获取 diceList.size() ,这样它就不会在一个骰子被移除后改变。我在循环中使用 listSize 以正确标记字符串数组中不包含值的那些元素(null

public void checkCombination(int first, int second) {
Dice checker = new Dice(first, second);
int index = 1;
boolean flag = false;
for (Dice diceObject : diceList) {

  for (int i = 0; i < listSize; i++) {
    if (diceObject.rollArray[i] == null) {
      diceObject.rollArray[i] = "..";
    }
  }

  if (diceObject.equals(checker)) {
    System.out.println("Combination: (" + first + ", " + second + ") rolled on roll No: "
        + index);
    flag = true;
  }
  index++;
}
if (!flag) {
  System.out.println("Combination not rolled.");
}

}

然后输出如下:

Roll: 1 2 3 4 5 
Comb:
(2, 1) [.., .., 3, .., ..]
(3, 6) [.., 2, .., 4, 5]
(6, 5) [1, .., .., .., ..]