【问题标题】:How to get random string value without duplicate?如何获得不重复的随机字符串值?
【发布时间】:2017-01-17 12:42:33
【问题描述】:

我只想获取一个公司名称,而且我只想获取一次。因此,如果它已经被提取,则不应再次提取它。

代码如下:

private static String[] billercompanies = { 
    "1st",      
    "TELUS Communications",
    "Rogers Cablesystems",
    "Shaw Cable",
    "TELUS Mobility Inc",
    "Nanaimo Regional District of",
    "Credit Union MasterCard",
    }; 



public static String GetBillerCompany(){
    String randomBillerComp = "";
    randomBillerComp = (billercompanies[new Random().nextInt(billercompanies.length)]);
    return randomBillerComp;
}

【问题讨论】:

  • 随机排列数组,然后按顺序迭代。当你想重新开始时(忘记重复),再次随机播放
  • 像@AxelH 提到的那样做。或者开始删除您已经使用的元素并在该范围内生成一个新索引。但这会比 AxelH 解决方案花费更多的性能。所以我更喜欢他的。

标签: java arrays random


【解决方案1】:

在 List 中创建一个副本,并在已获取元素时将其删除。

Arrays.asList(array) 不可修改,但您可以将其包装在一个功能齐全的列表中。

List<String> billercompaniesList = new ArrayList<>(Arrays.asList(billercompanies));

String randomBillerComp = "";

Random random = new Random();
// first retrieval
int index = random.nextInt(billercompaniesList.size()); 
randomBillerComp = billercompaniesList.get(index);
billercompaniesList.remove(index);  


// second retrieval
index = random.nextInt(billercompaniesList.size()); 
randomBillerComp = billercompaniesList.get(index);
billercompaniesList.remove(index);  

// and so for    

【讨论】:

  • 你让我想到了我使用 remove 的第二个解决方案 :)
  • 我们不会重新发明轮子 :) @AxelH
  • 我认为通用解决方案确实存在;)
【解决方案2】:

只需使用 Collections 打乱您想要的数组

Collections.shuffle(List);

所以只需从您的数组中创建一个列表

List<E> list = Arrays.asList(array);

然后用上面的方法洗牌

Collections.shuffle(list);

您的列表可以从左到右阅读,因为它是随机的。 所以只需保存索引

int currentIndex = 0;

public E getRandom(){
    //If at the end, start over
    if(++currentIndex == list.size()) { 
         currentIndex = 0;
         shuffle(list);
    }

    return list.get(currentIndex);
}

每次你想忘记你已经使用过的重复列表时,只需再次随机排列数组

Collections.shuffle(list);

无索引

您可以简单地每次删除第一个值,一旦列表为空,使用原始数组重新创建它。作为 Ole V.V.指针指向,Arrays.asList(E[]) 生成的 List 不支持 remove 方法,因此需要从中生成一个新实例。

这是一个使用此解决方案的快速简单的课程:

public class RandomList<E>{
    E[] array;
    List<E> list;

    public RandomList(E[] array){
        this.array = array;
        buildList(array);
    }
    
    public E getRandom(){
        if(list.isEmpty()) buildList(array);
        return list.remove(0);
    }

    public void buildList(E[] array){
        list = new ArrayList<E>(Arrays.asList(array));
        Collections.shuffle(list);
    }
}

测试是用这个小代码完成的:

Integer[] array = {1,2,3,4,5};
RandomList<Integer> rl = new RandomList(array);
int i = 0;
while(i++ < 10)
        System.out.println(rl.getRandom());

【讨论】:

  • 最后一个 sn-p 将不起作用。 Arrays.asList() 返回的列表是固定大小的(由数组支持),因此不支持 remove()。我相信修复是list = new ArrayList(Arrays.asList(array));。你也不想使用原始的List,给它一个类型参数。
  • @OleV.V.对了,我记得这个。确实这应该可行,但我会在一些测试后对其进行编辑,但目前我无法访问我的系统。对于原始类型,起初我试图避免类型,但忘记指定一个而不是 Object ......我已经用一些通用性快速编辑了它。在我运行了一些测试(以及回家的时间)后,我将在几个小时内再次编辑它。感谢您对此的意见。
  • @OleV.V.完成了,确实在构造函数中复制 List 就足够了。记住这一点总是很好。
猜你喜欢
  • 2020-05-13
  • 2019-07-16
  • 1970-01-01
  • 2019-04-01
  • 2010-12-19
  • 2015-12-18
  • 2021-03-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多