Java 如何洗牌除元素外的列表?

Java 如何洗牌除元素外的列表?,java,shuffle,Java,Shuffle,我有一个包含值元素的整数列表:0、7、2、1、6、5。 我知道我可以使用这种方法 Collections.shuffle(list); 来洗牌我的名单。但我不想改变第二位的价值。它应该总是7 我该怎么做呢?您可以洗牌集合,然后将7恢复到第二位: Collections.shuffle(list); list.set(list.indexOf(7),list.get(2)); list.set(2,7); 或更短: Collections.shuffle(list); Collections.

我有一个包含值元素的整数列表:0、7、2、1、6、5。

我知道我可以使用这种方法

Collections.shuffle(list);
来洗牌我的名单。但我不想改变第二位的价值。它应该总是7


我该怎么做呢?

您可以洗牌集合,然后将7恢复到第二位:

Collections.shuffle(list);
list.set(list.indexOf(7),list.get(2));
list.set(2,7);
或更短:

Collections.shuffle(list);
Collections.swap(list, 2, list.indexOf(7));
正如其他人所建议的,您还可以在洗牌之前删除希望保留其位置的元素,然后将其添加到同一位置


对于ArrayList,这两种方法都需要相似的时间(在最坏的情况下是线性的),因为在我的回答中,
indexOf
将需要线性时间,但是在替代解决方案中删除和添加元素(特别是如果索引接近列表的开头)将需要
ArrayList
的线性时间,因为删除/添加索引之后的所有元素都必须推送到新索引

简单地防止移动任意数量的元素

  • 将它们从列表中删除
  • 洗牌其余元素
  • 将它们放回原来的位置(从左开始,以避免元素向右移动的问题)

有一种替代解决方案更长,但对于长列表可能更快:

public static <T> void shuffleExcept(final List<T> list, final int position) {
    List<T> view = new AbstractList<T>() {
        @Override
        public T get(int index) {
            return list.get(index >= position ? index+1 : index);
        }

        @Override
        public T set(int index, T element) {
            return list.set(index >= position ? index+1 : index, element);
        }

        @Override
        public int size() {
            return list.size()-1;
        }
    };
    Collections.shuffle(view);
}

如果您不知道元素的值,只想将其保留在第二个位置,则可以在洗牌之前将其删除,然后将其添加到第二个位置。@NuongReo第一个片段不会复制7的值。如果7在洗牌后留在2索引中,两个set操作将是相同的-
list.set(2,7)
,并且不会更改任何内容,因为
set
不会向列表中添加值(它只会更改现有值)。对于文档:这将保留
Collections.shuffle(…)
的分发属性。
List<Integer> input = Arrays.asList(0, 7, 2, 1, 6, 5);
shuffleExcept(input, 1);
System.out.println(input);
shuffleExcept(input, 1);
System.out.println(input);
shuffleExcept(input, 1);
System.out.println(input);
shuffleExcept(input, 1);
System.out.println(input);
shuffleExcept(input, 1);
System.out.println(input);
shuffleExcept(input, 1);
System.out.println(input);
shuffleExcept(input, 1);
System.out.println(input);
[6, 7, 5, 2, 1, 0]
[5, 7, 6, 1, 2, 0]
[6, 7, 2, 0, 5, 1]
[6, 7, 2, 0, 5, 1]
[2, 7, 0, 5, 6, 1]
[6, 7, 0, 2, 5, 1]
[5, 7, 2, 0, 1, 6]