资讯专栏INFORMATION COLUMN

如何对两个列表进行乱序处理,同时保持它们的一一对应的关系?

ashe / 3661人阅读

摘要:如何对两个列表进行乱序处理,同时保持它们的一一对应的关系已知我们有两个列表其中和中的元素是一一对应的。现在我们希望对两个列表进行随机排序,要求排序后它们依旧是一一对应的。

如何对两个列表进行乱序处理,同时保持它们的一一对应的关系?

已知我们有两个列表

public class RandomizeTwoList {
    public static String [] file = {"H1.txt","H2.txt","H3.txt","M4.txt","M5.txt","M6.txt"};
    public static ArrayList fileList = new ArrayList(Arrays.asList(file));

    public static String [] img = {"e1.jpg","e2.jpg","e3.jpg","e4.jpg","e5.jpg","e6.jpg"};
    public static ArrayList imgList = new ArrayList(Arrays.asList(img));
}

其中fileList和imgList中的元素是一一对应的。

现在我们希望对两个列表进行随机排序,要求排序后它们依旧是一一对应的。

提示: java.util.Collections可以使得一个列表乱序,但是下面的写法是不可以的:

import java.util.Collections;

public class RandomizeTwoListTest {
   @Test
   public void wrongRandomize(){
        Collections.shuffle(fileList);
        Collections.shuffle(imgList);

        System.out.println(fileList);
        System.out.println(imgList);

        // [H3.txt, M5.txt, H2.txt, H1.txt, M6.txt, M4.txt]
        // [e6.jpg, e3.jpg, e4.jpg, e1.jpg, e2.jpg, e5.jpg]
    }
}

我们可以看到java.util.Collections确实可以使得一个列表乱序,但是上面两次乱序后列表之间失去了一一对应的关系,所以是不行的。

那我们怎么解决呢?

方案一: 把它们绑定起来

我们之前的演示用例失败的原因是两次随机化的规则不一样,导致结果不能一一对应,那么我们现在可以

让它们一一绑定起来,构造出一个list(当然也可以是map、onject)容纳它们,然后再随机排序。

    @Test
    public void randomTogether(){
        List> compoundList = new ArrayList();
        for (int i = 0; i < fileList.size(); i++) {
            List listItem = new ArrayList();
            listItem.add(fileList.get(i));
            listItem.add(imgList.get(i));
            compoundList.add(listItem);
        }

        System.out.println(compoundList);
        // [[H1.txt, e1.jpg], [H2.txt, e2.jpg], [H3.txt, e3.jpg], [M4.txt, e4.jpg], [M5.txt, e5.jpg], [M6.txt, e6.jpg]]
        
        Collections.shuffle(compoundList);
        
        System.out.println(compoundList);
        // [[M5.txt, e5.jpg], [H2.txt, e2.jpg], [M4.txt, e4.jpg], [H3.txt, e3.jpg], [H1.txt, e1.jpg], [M6.txt, e6.jpg]]

        for (int i = 0; i < fileList.size(); i++) {
            fileList.set(i, compoundList.get(i).get(0));
            imgList.set(i, compoundList.get(i).get(1));
        }

        System.out.println(fileList);
        // [M5.txt, H2.txt, M4.txt, H3.txt, H1.txt, M6.txt]
        
        System.out.println(imgList);
        // [e5.jpg, e2.jpg, e4.jpg, e3.jpg, e1.jpg, e6.jpg]
    }

参考这样的代码。看起来很复杂,其实思路很简单。

先把fileList第i个元素的值和imgList第i个元素的值绑定起来,构造出新的数组

然后对着数组进行乱序,乱序完成后原理的两个list的对应依旧保持一致

将list整理还原

方案2: 采取同样的方式随机化

我们来说一下Collections.shuffle 的原理。

当我们调用Collections.shuffle(List list)的时候,它其实做了这件事

    public static void shuffle(List list) {
        Random rnd = r;
        if (rnd == null)
            r = rnd = new Random(); // harmless race.
        shuffle(list, rnd);
    }

那么void shuffle(List list, Random rnd) 又做了什么呢?

简单的来说,它就是对传进来的list做一次i递减的for循环,然后在每次循环的时候把第i个元素和rnd.nextInt(i)的值互换,这样我们最终的list就是随机乱序的了。

这里大家明白了吧,如果每次产生的随机值一致,那么它们就随机排序的结果就是一致的。

好了,有的同学就开始写代码了,写出这样的代码了

    @Test
    public void randomize(){
        long seed = System.nanoTime();

        Random random = new Random(seed);
        Collections.shuffle(fileList, random);
        Collections.shuffle(imgList, random);

        System.out.println(fileList);
        System.out.println(imgList);

    }

注意这样是不行的哦,因为虽然是同一个Random,但是每次调用nextInt的结果是不一样的。

应该这样写:

    @Test
    public void randomize2(){
        long seed = System.nanoTime();

        Collections.shuffle(fileList, new Random(seed));
        Collections.shuffle(imgList, new Random(seed));

        System.out.println(fileList);
        System.out.println(imgList);

        // [M5.txt, M4.txt, H1.txt, H2.txt, H3.txt, M6.txt]
        // [e5.jpg, e4.jpg, e1.jpg, e2.jpg, e3.jpg, e6.jpg]
    }

两个Random的随机种子一样,那么他们第i次的nextInt的值也是相等的。

https://github.com/fish-bugs/...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/74521.html

相关文章

  • 流式统计几个难点

    摘要:如果到齐了,就可以开始统计出这个时间窗口内的指标了。这种里会遇到两个难题多个流的速度不一样,如何判断一个时间窗口内的都到齐了。 在本文发出之后不久,老外就写了一篇类似内容的。人家比我写得好,推荐大家读这篇http://radar.oreilly.com/2015/08/the-world-beyond-batch-streaming-101.... 流式统计听着挺容易的一个事...

    tianlai 评论0 收藏0
  • Kafka原理你真知道吗?

    摘要:而在服务器中应该充分利用多线程来处理执行逻辑。能保证所在的失效,该消息仍然可以从新选举的中获取,不会造成消息丢失。这意味着无需等待来自的确认而继续发送下一批消息。 showImg(https://segmentfault.com/img/remote/1460000018373147?w=702&h=369); 1.概述 Apache Kafka最早是由LinkedIn开源出来的分布式...

    n7then 评论0 收藏0

发表评论

0条评论

ashe

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<