2017-12-27 346 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或類似的性能。這完全取決於你的用例。

編輯此答案不再適用於編輯的問題。但是,當單獨的子列表需要獨立改組時,它應該可以工作。