shuffle multidimensional List,ArrayList,LinkedList

时间:2017-12-27 16:39:52

标签: java list arraylist collections

我们知道可以使用方法ArrayList来改变Collections.shuffle

但是,如何使用多维顺序集合?

如果我的模式如下:

1,2,3
4,5,6
7,8,9

我想实现这样的目标:

1,5,7
2,3,8
9,4,6

Collection.shuffle()只交换行或列,但我想完全独立地交换所有元素。

我不想:

1,3,2
5,6,4
7,9,8

2 个答案:

答案 0 :(得分:1)

如果你只是在多维列表上调用Collection.shuffle,它将改变该列表中子列表的顺序。

如果您想要随机播放所有子列表,则必须为每个子列表调用Collection.shuffle

final List<List<String>> list = Arrays.asList(
        Arrays.asList("A", "B", "C"),
        Arrays.asList("X", "Y", "Z"),
        Arrays.asList("1", "2", "3")

);

// 1. Will shuffle the order of the sub-lists
Collections.shuffle(list);

// 2.a. Will shuffle all the sub-lists
list.forEach(sublist -> Collections.shuffle(sublist));

// 2.b. Or the same, with method reference instead of lambda
list.forEach(Collections::shuffle);

编辑问题后编辑

如果要求真的要洗牌所有子列表的所有元素,甚至在子列表之间混合元素,那么上面的代码就不够了。

以下代码将按您的要求执行,但会假设所有子列表具有相同的大小(在本例中为3):

// 1. Add all values in single dimension list    
List<String> allValues = list.stream()
        .flatMap(List::stream)
        .collect(toList());

// 2. Shuffle all those values
Collections.shuffle(allValues);

// 3. Re-create the multidimensional List
List<List<String>> shuffledValues = new ArrayList<>();
for (int i = 0; i < allValues.size(); i = i + 3) {
    shuffledValues.add(allValues.subList(i, i+3));
}

答案 1 :(得分:0)

如果你想进行深度洗牌,我会推荐一种方法,检查列表中的每个项目是否是另一个列表,并递归地对该列表进行洗牌。像这样:

public static void deepShuffle(List<?> mutliDimensionList) {
    for (Object item : mutliDimensionList) {
        if (item instanceof List) {
            deepShuffle((List<?>)item);
        }
    }
    Collections.shuffle(mutliDimensionList);
}

您可以使用ForkJoinPool或类似功能添加多线程以提高性能。这完全取决于你的用例。

修改此回答不再适用于已修改的问题。但是,当个别子列表需要独立洗牌时,它应该有效。