Java 洗牌数组,使每个值都有不同的索引

Java 洗牌数组,使每个值都有不同的索引,java,arrays,shuffle,Java,Arrays,Shuffle,我已经编写了一个方法来洗牌字符串数组 因此,任务是为给定的名称列表字符串数组实现WhiteElephant概念。应生成与原始元素匹配的赋值。 我编写了一个方法来选择一个随机数,并使用一个映射来存储这些值,这样每个值都有一个不同的索引。但这只打印出5个值。我现在很困惑 public static String[] generateAssignments(final String[] participants) { Random r = new Random(); int size

我已经编写了一个方法来洗牌
字符串
数组 因此,任务是为给定的名称列表字符串数组实现WhiteElephant概念。应生成与原始元素匹配的赋值。 我编写了一个方法来选择一个随机数,并使用一个映射来存储这些值,这样每个值都有一个不同的索引。但这只打印出5个值。我现在很困惑

public static String[] generateAssignments(final String[] participants) {

    Random r = new Random();
    int size = participants.length;
    HashMap val = new HashMap();
    int change = 0;
    String[] assignments = new String[6];
    System.out.println("Using arrays");


    for(int i=0; i<size;i++){
        for(int j =0; j<size; j++){
            change = r.nextInt(size);
            if(val.containsValue(change) || change==i){
                continue;
            }
            else val.put(i, change);
            assignments[i] = participants[change];
            System.out.println(assignments[i]);
            break;
        }   

    }

    return assignments;
}
公共静态字符串[]生成指定(最终字符串[]参与者){
随机r=新随机();
int size=参与者的长度;
HashMap val=新的HashMap();
int change=0;
字符串[]赋值=新字符串[6];
System.out.println(“使用数组”);

对于(int i=0;i您的
shuffle()
方法似乎总是返回相同的结果。因此,给定一个包含测试中多少元素的输入测试数组,只需指定您期望的确切输出数组即可


看起来您正试图编写一个非常通用的测试。相反,您的测试应该非常具体:给定一个特定的输入a,然后您期望一个特定的输出B。

看起来您的
shuffle()
方法将始终返回相同的结果。因此,给定测试中包含多少元素的输入测试数组,只需指定您期望的确切输出数组即可


看起来您正在尝试编写一个非常通用的测试。相反,您的测试应该非常具体:给定一个特定的输入a,那么您期望一个特定的输出B。

如果您的随机方法是随机(或伪随机)单元测试几乎是不可能的,因为输出是不确定的。如果您允许植入一个随机数生成器,那么您可以确保给定相同种子的输出是一致的,尽管这不会显示随机性


您还可以多次运行洗牌方法,并检查每张牌在每个索引上的显示次数是否大致相等。在足够多的模拟中,这将有助于说明随机性。

如果您的洗牌方法是随机的(或伪随机的)单元测试几乎是不可能的,因为输出是不确定的。如果您允许植入一个随机数生成器,那么您可以确保给定相同种子的输出是一致的,尽管这不会显示随机性


您还可以多次运行洗牌方法,并检查每张卡在每个索引上的显示次数是否大致相等。在足够多的模拟中,这将有助于说明随机性。

FYI-您的
洗牌()中都存在一些逻辑错误
代码和测试。我在这里不讨论这些问题;希望有一个好的测试可以让您找出问题所在


围绕
随机
数据编写测试很难。
最好的选择是将
Random
的实例传递给您的
shuffle()
方法或它包含
。然后在测试使用中,您可以传入一个带有已知值的
随机
实例。假设
随机
代码每次的行为都相同,并且您控制输入数组,您的测试将是确定的;您可以自信地
断言
继续已排序集合中的每个对象

这种方法唯一的缺点是,您不会有一个测试阻止您重新编写
shuffle()
方法来简单地将元素每次重新排序到指定的顺序。但这可能是过虑了;通常我们可以相信未来的自己


另一种方法是假设在一个随机的世界中,给定足够的时间,所有数据的可能性都会实现

我在测试6面模具的
roll()时使用了这种方法
方法。我需要确保从1-6中获取所有值是可能的。我不想让方法签名或
Die
构造函数复杂化,以获取
Random
的实例。对于使用已知种子并总是断言
3
(即)的测试,我也没有信心

相反,我假设给定足够的滚动次数,1-6中的所有值最终都会滚动。我编写了一个测试,无限调用
roll
,直到返回1-6中的所有值。然后我在测试中添加了一个
timeout
,这样如果不满足上述条件,它将在1秒后失败

@Test(timeout = 1000)
public void roll_shouldEventuallyReturnAllNumbersBetweenOneAndSixInclusively() {
    Die die = new Die();
    Set<Integer> rolledValues = new HashSet<Integer>();
    int totalOfUniqueRolls = 0;
    while (rolledValues.size() < Die.NUM_SIDES) {
        if (rolledValues.add(die.roll())) {
            totalOfUniqueRolls += die.getFaceValue();
        }
    }
    assertEquals(summation(1, Die.NUM_SIDES), totalOfUniqueRolls);
}
@测试(超时=1000)
公共作废登记簿最终应返回介于1和6之间的所有编号(包括(){
模具=新模具();
Set rolled values=new HashSet();
int totalOfUniqueRolls=0;
while(rolled values.size()

最坏的情况是,它在1秒后失败(这还没有发生),但通常会在20毫秒后消失。

仅供参考-您的
shuffle()
代码和测试中都存在一些逻辑错误。我在这里不讨论这些错误;希望有一个好的测试可以让您找出问题


围绕
随机
数据编写测试很难。
最好的选择是将
Random
的实例传递给您的
shuffle()
方法或它包含
。然后在测试使用中,您可以传入一个带有已知值的
随机
实例。假设
随机
代码每次的行为都相同,并且您控制输入数组,您的测试将是确定的;您可以自信地
断言
继续已排序集合中的每个对象

这种方法唯一的缺点是,您不会有一个测试阻止您重新编写
shuffle()
方法,只需每隔一段时间对元素重新排序