简体   繁体   English

如何在不使用 Collections.swap() 的情况下随机化 ArrayList?

[英]How to randomize ArrayList without using Collections.swap()?

I was asked to create a method that randomly rearranges my list which contains arrays.我被要求创建一个随机重新排列包含数组的列表的方法。 The list contains multiple persons and their names and surnames.该列表包含多个人及其姓名。 My question is how do I move a person (array containing two elements name and surname inside the list) to a different index without using the method swap()?我的问题是如何在不使用 swap() 方法的情况下将一个人(列表中包含两个元素 name 和 surname 的数组)移动到不同的索引? Because our list does not support that method.因为我们的列表不支持该方法。 Sadly we do not use the "official" list and have our own one coded like this:遗憾的是,我们不使用“官方”列表,而是使用我们自己的代码如下:

public class List<ContentType> {  

    private class ListNode {

        private ContentType contentObject;
        private ListNode next;

        private ListNode(ContentType pContent) {
          contentObject = pContent;
          next = null;
        }
        
        public ContentType getContentObject() {
          return contentObject;
        }

        public void setContentObject(ContentType pContent) {
          contentObject = pContent;
        }

        public ListNode getNextNode() {
          return this.next;
        }

        public void setNextNode(ListNode pNext) {
          this.next = pNext;
        }
    }


    ListNode first;   
    ListNode last;    
    ListNode current;

    public List() {
        first = null;
        last = null;
        current = null;
    }

    public boolean isEmpty() {
        return first == null;
    }

    public boolean hasAccess() {
        return current != null; 
    }

    public void next() {
        if (this.hasAccess()) {
            current = current.getNextNode();
        }
    }

    public void toFirst() {
        if (!isEmpty()) {
            current = first;
        }
    }

    public void toLast() {
        if (!isEmpty()) {
            current = last;
        }
    }

    public ContentType getContent() {
        if (this.hasAccess()) {
            return current.getContentObject();
        } else {
            return null;
        }
    }

    public void setContent(ContentType pContent) {

        if (pContent != null && this.hasAccess()) { 
            current.setContentObject(pContent);
        }
    }

    public void insert(ContentType pContent) {
        if (pContent != null) { 
            if (this.hasAccess()) { 
                ListNode newNode = new ListNode(pContent); 

                if (current != first) { 
                    ListNode previous = this.getPrevious(current);
                    newNode.setNextNode(previous.getNextNode());
                    previous.setNextNode(newNode);
                } else { 
                    newNode.setNextNode(first);
                    first = newNode;
                }
            } else {
                if (this.isEmpty()) {
                    ListNode newNode = new ListNode(pContent); 

                    first = newNode;
                    last = newNode;
                }
            }
        }
    }

    public void append(ContentType pContent) {
        if (pContent != null) {
            if (this.isEmpty()) { 
                this.insert(pContent);
            } else { 
                ListNode newNode = new ListNode(pContent); 

                last.setNextNode(newNode);
                last = newNode;    
            }
        }
    }

    public void concat(List<ContentType> pList) {
        if (pList != this && pList != null && !pList.isEmpty()) { 

            if (this.isEmpty()) { 
                this.first = pList.first;
                this.last = pList.last;
            } else { 
                this.last.setNextNode(pList.first);
                this.last = pList.last;
            }

            pList.first = null;
            pList.last = null;
            pList.current = null;
        }
    }

    public void remove() {
        if (this.hasAccess() && !this.isEmpty()) { 
            if (current == first) {
                first = first.getNextNode();
            } else {
                ListNode previous = this.getPrevious(current);
                if (current == last) {
                    last = previous;
                }
                previous.setNextNode(current.getNextNode());
            }

            ListNode temp = current.getNextNode();
            current.setContentObject(null);
            current.setNextNode(null);
            current = temp;
  
            if (this.isEmpty()) {
                last = null;
            }
        }
    }

    private ListNode getPrevious(ListNode pNode) {
        if (pNode != null && pNode != first && !this.isEmpty()) {
            ListNode temp = first;
            while (temp != null && temp.getNextNode() != pNode) {
                temp = temp.getNextNode();
            }
            return temp;
        } else {
            return null;
        }
    }

    public int length() {
        int i = 0;
        while(this.hasAccess()) {
            i++;
            next(); 
        }
        return i;
    }
}

This is my version of the wanted method it should randomly rearrange the list by swapping objects multiple times but it apparently does not work.这是我想要的方法的版本,它应该通过多次交换对象来随机重新排列列表,但它显然不起作用。

public static void shuffleList(final List<String[]> list) {

    int length = list.length();
    Random random = new Random();

    for (int i = 0; i < length; i++) {

        // Swap index
        int swap = i + random.nextInt(length - i);

        // Store temporarily
        String name1 = list.getContent()[0];
        String surname1 = list.getContent()[1];
        String[] temp1 = {mail1, pw1};
            
        System.out.println(temp1);
            
        for (int j = 0; j < swap; j++) {
            list.next();
        }

        String name2 = list.getContent()[0];
        String surname2 = list.getContent()[1];
        String[] temp2 = {mail2, pw2};
            
        // Set the values
        list.setContent(temp1);
            
        list.toFirst();
        for (int k = 0; k < i; k++) {
            list.next();
        }
        list.setContent(temp2);
    }
}

I would be very glad if somebody could help me find a way to swap elements inside of my list so that I can finally get my method to randomly rearrange the list.如果有人能帮我找到一种方法来交换我的列表中的元素,我会很高兴,这样我就可以最终获得随机重新排列列表的方法。

Thank you for every answer!谢谢你的每一个回答! :) :)

I would suggest firstly converting your list to an array, so you have O(1) random access, then shuffle this array and after that replace values in your list.我建议首先将您的列表转换为数组,这样您就可以进行O(1)随机访问,然后对这个数组进行洗牌,然后替换列表中的值。

Here is a code这是一个代码

public class ListUtils {

    /**
     * Shuffles a list, leaving it's pointer on the first element.
     * 
     * @param list list to shuffle
     * @param rnd random number generator
     */
    @SuppressWarnings({"unchecked"})
    public static <T> void shuffleList(List<T> list, Random rnd) {
        Object[] arr = toArray(list);

        for (int i = arr.length; i > 1; --i) {
            swap(arr, i - 1, rnd.nextInt(i));
        }

        list.toFirst();
        for (Object o : arr) {
            list.setContent((T) o);
            list.next();
        }
    }

    private static void swap(Object[] arr, int i, int j) {
        Object temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    private static Object[] toArray(List<?> list) {
        // length is O(n), makes sense to track size on every add, so it will be O(1)
        list.toFirst();
        int size = list.length();
        Object[] result = new Object[size];
        list.toFirst();
        for (int i = 0; i < size; ++i) {
            result[i] = list.getContent();
            list.next();
        }
        return result;
    }

    public static void main(String[] args) {
        List<String> l = new List<>();
        l.append("a");
        l.append("b");
        l.append("c");
        l.append("d");
        shuffleList(l, new Random());
        l.toFirst();
        while (l.hasAccess()) {
            System.out.println(l.getContent());
            l.next();
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 两个如何在不使用 collections.swap 方法的情况下交换数组列表中的两个元素 - How two swap two elements in a array list without using collections.swap method 在arraylist for循环中进行Collections.swap()是否安全? - Is it safe to do a Collections.swap() inside a arraylist for loop? Java中的Collections.swap()交换方法中的所有内容 - Collections.swap() in java swap everything in the method 对于数组列表,哪个更有效:collections.swap() 或使用临时变量进行交换? - Which is more efficient for array lists: collections.swap() or using a temporary variable to swap? 如何在不使用集合的情况下随机播放ArrayList - How to shuffle an ArrayList without collections 为什么Collections.swap将目标列表分配给原始类型的变量? - Why does Collections.swap assign the target list to a variable of a raw type? 如何不使用collections.sort()按字母顺序对数组列表排序 - How to sort an arraylist alphabetically without using collections.sort(); 实现自己的ArrayList &lt;&gt;而不使用集合 - Implement own ArrayList<> without using collections 如何在不使用 Collections.sort 方法的情况下按字母顺序排列这个 ArrayList? - How do i alphabetize this ArrayList without using the Collections.sort method? 使arraylist方法同步而不使用Collections.synchronizedList() - Make an arraylist method synchronized without using Collections.synchronizedList()
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM