簡體   English   中英

shuffle 多維 List、ArrayList、LinkedList

[英]shuffle multidimensional List, ArrayList, LinkedList

正如我們所知,可以使用Collections.shuffle方法對ArrayList進行混洗。

但是這如何與多維順序集合一起工作呢?

如果我有如下模式:

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

如果您只是在多維列表上調用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));
}

如果你想進行深度洗牌,我會推薦一種方法,檢查列表中的每個項目是否是另一個列表,並遞歸地洗牌該列表。 像這樣的東西:

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

您可以使用 ForkJoinPool 或類似方法添加多線程以潛在地提高性能。 不過,這完全取決於您的用例。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM