zoukankan      html  css  js  c++  java
  • Collections.shuffle源码阅读

    java.util.Collections

      /**
         * Randomly permutes the specified list using a default source of
         * randomness.  All permutations occur with approximately equal
         * likelihood.<p>
         *
         * The hedge "approximately" is used in the foregoing description because
         * default source of randomness is only approximately an unbiased source
         * of independently chosen bits. If it were a perfect source of randomly
         * chosen bits, then the algorithm would choose permutations with perfect
         * uniformity.<p>
         *
         * This implementation traverses the list backwards, from the last element
         * up to the second, repeatedly swapping a randomly selected element into
         * the "current position".  Elements are randomly selected from the
         * portion of the list that runs from the first element to the current
         * position, inclusive.<p>
         *
         * This method runs in linear time.  If the specified list does not
         * implement the {@link RandomAccess} interface and is large, this
         * implementation dumps the specified list into an array before shuffling
         * it, and dumps the shuffled array back into the list.  This avoids the
         * quadratic behavior that would result from shuffling a "sequential
         * access" list in place.
         *
         * @param  list the list to be shuffled.
         * @throws UnsupportedOperationException if the specified list or
         *         its list-iterator does not support the <tt>set</tt> operation.
         */
        public static void shuffle(List<?> list) {
            if (r == null) {
                r = new Random();
            }
            shuffle(list, r);
        }
        private static Random r;
    java.util.Random
      /**
         * Randomly permute the specified list using the specified source of
         * randomness.  All permutations occur with equal likelihood
         * assuming that the source of randomness is fair.<p>
         *
         * This implementation traverses the list backwards, from the last element
         * up to the second, repeatedly swapping a randomly selected element into
         * the "current position".  Elements are randomly selected from the
         * portion of the list that runs from the first element to the current
         * position, inclusive.<p>
         *
         * This method runs in linear time.  If the specified list does not
         * implement the {@link RandomAccess} interface and is large, this
         * implementation dumps the specified list into an array before shuffling
         * it, and dumps the shuffled array back into the list.  This avoids the
         * quadratic behavior that would result from shuffling a "sequential
         * access" list in place.
         *
         * @param  list the list to be shuffled.
         * @param  rnd the source of randomness to use to shuffle the list.
         * @throws UnsupportedOperationException if the specified list or its
         *         list-iterator does not support the <tt>set</tt> operation.
         */
        public static void shuffle(List<?> list, Random rnd) {
            int size = list.size();
            if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
                for (int i=size; i>1; i--)
                    swap(list, i-1, rnd.nextInt(i));
            } else {
                Object arr[] = list.toArray();
    
                // Shuffle array
                for (int i=size; i>1; i--)
                    swap(arr, i-1, rnd.nextInt(i));
    
                // Dump array back into list
                ListIterator it = list.listIterator();
                for (int i=0; i<arr.length; i++) {
                    it.next();
                    it.set(arr[i]);
                }
            }
        }
        private static final int SHUFFLE_THRESHOLD        =    5;
        /**
         * Swaps the elements at the specified positions in the specified list.
         * (If the specified positions are equal, invoking this method leaves
         * the list unchanged.)
         *
         * @param list The list in which to swap elements.
         * @param i the index of one element to be swapped.
         * @param j the index of the other element to be swapped.
         * @throws IndexOutOfBoundsException if either <tt>i</tt> or <tt>j</tt>
         *         is out of range (i &lt; 0 || i &gt;= list.size()
         *         || j &lt; 0 || j &gt;= list.size()).
         * @since 1.4
         */
        public static void swap(List<?> list, int i, int j) {
        final List l = list; //这一步有什么用
        l.set(i, l.set(j, l.get(i)));
        }
    java.util.List
    @org.intellij.lang.annotations.Flow(sourceIsContainer=true) 
    public abstract E set(int index,
                          @org.intellij.lang.annotations.Flow(targetIsContainer=true) E element)
    Replaces the element at the specified position in this list with the specified element (optional operation).
    Parameters:
    index - index of the element to replace
    element - element to be stored at the specified position
    Returns:
    the element previously at the specified position
        /**
         * Swaps the two specified elements in the specified array.
         */
        private static void swap(Object[] arr, int i, int j) {
            Object tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
        }



    这里假设集合List由四个元素List1、List2、List3和List4组成,当使用语句Iterator it = List.Iterator()时,迭代器it指向的位置是上图中Iterator1指向的位置,当执行语句it.next()之后,迭代器指向的位置后移到上图Iterator2所指向的位置。

    首先看一下Iterator和ListIterator迭代器的方法有哪些。

    Iterator迭代器包含的方法有:

    hasNext():如果迭代器指向位置后面还有元素,则返回 true,否则返回false

    next():返回集合中Iterator指向位置后面的元素

    remove():删除集合中Iterator指向位置后面的元素

    ListIterator迭代器包含的方法有:

    add(E e): 将指定的元素插入列表,插入位置为迭代器当前位置之前

    hasNext():以正向遍历列表时,如果列表迭代器后面还有元素,则返回 true,否则返回false

    hasPrevious():如果以逆向遍历列表,列表迭代器前面还有元素,则返回 true,否则返回false

    next():返回列表中ListIterator指向位置后面的元素

    nextIndex():返回列表中ListIterator所需位置后面元素的索引

    previous():返回列表中ListIterator指向位置前面的元素

    previousIndex():返回列表中ListIterator所需位置前面元素的索引

    remove():从列表中删除next()或previous()返回的最后一个元素(有点拗口,意思就是对迭代器使用hasNext()方法时,删除ListIterator指向位置后面的元素;当对迭代器使用hasPrevious()方法时,删除ListIterator指向位置前面的元素)

    set(E e):从列表中将next()或previous()返回的最后一个元素返回的最后一个元素更改为指定元素e

    一.相同点

    都是迭代器,当需要对集合中元素进行遍历不需要干涉其遍历过程时,这两种迭代器都可以使用。

    二.不同点

    1.使用范围不同,Iterator可以应用于所有的集合,Set、List和Map和这些集合的子类型。而ListIterator只能用于List及其子类型。

    2.ListIterator有add方法,可以向List中添加对象,而Iterator不能。

    3.ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator不可以。

    4.ListIterator可以定位当前索引的位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。

    5.都可实现删除操作,但是ListIterator可以实现对象的修改,set()方法可以实现。Iterator仅能遍历,不能修改。

    三:Iterator和ListIterator用法示例

    ListIterator用法:

    package com.collection;
    
    import java.util.LinkedList;
    import java.util.List;
    import java.util.ListIterator;
    
    public class ListIteratorTest {
    
     public static void main(String[] args) {
    
      List<String> staff = new LinkedList<>();
      staff.add("zhuwei");
      staff.add("xuezhangbin");
      staff.add("taozhiwei");
      ListIterator<String> iter = staff.listIterator();
      String first = iter.next();
      
      //删除zhuwei
      iter.remove();
      
      //把zhuwei改为simei
      //iter.set("simei");
      System.out.println("first:"+first);
      
      iter.add("xiaobai");
      
      //遍历List元素
      System.out.println("遍历List中元素,方法一:");
      for(String str : staff)
       System.out.println(str+"  ");
      
      iter = staff.listIterator();
      System.out.println("遍历List中元素,方法二:");
      while(iter.hasNext())
      {
       System.out.println(iter.next());
      }
     }
    
    }

    http://www.linuxidc.com/Linux/2014-11/109950.htm

  • 相关阅读:
    pip install urllib2不能安装
    linux 基础信息查询
    gitlab 操作指南
    ubuntu 新手入门第一天
    颜色配色
    mvn mybatis-generator:generate postgresql
    sublime 列编辑模式
    mybatis-generator 根据表生成对应文件
    Spring MVC Mock demo
    Toad常用快捷键
  • 原文地址:https://www.cnblogs.com/softidea/p/5824199.html
Copyright © 2011-2022 走看看