2017-12-27 348 views
-1

正如我们所知,洗牌ArrayList可以用方法Collections.shuffle完成。shuffle multidimensional List,ArrayList,LinkedList

但是,这是如何与多维顺序收集工作?

,如果我有一个模式如下:

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 
+0

你期望什么结果? – bcsb1001

+0

arraylist所有元素变得随机破裂 –

+0

我用适合您的问题的解决方案扩展了我的答案。 – Ward

回答

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)); 
} 

+0

我想在每个子列表中同时执行洗牌子列表和随机播放元素,以便所有元素都获得完整的新订单。 –

+0

好吧,那么我上面的一段代码将完成这个。 – Ward

+0

现在,谢谢你,它似乎做我想要的 –

0

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

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

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

编辑此答案不再适用于编辑的问题。但是,当单独的子列表需要独立改组时,它应该可以工作。