工具类:随机抽取数组或集合中的几个不重复元素

       其中的关键在于:每次循环随机获得一个下标,如果是首次访问到这个下标,将这个元素抽出到返回结果数组中,然后让这个数组下标index对应的元素引用一个其他任意对象srcNoContain(数组或集合不包含此对象)。如果下次循产生的随机下标index对应的元素与srcNoContain相等,表明这个下标已经被访问,这个下标对应的元素已经被抽取过了,不能再抽取它了。那么就要再进行循环获取新的随机下标,直到这个下标index对应的元素与srcNoContain不等时,就可以抽出一个这个下标对应的元素。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Random;
 
public class RandomUtil
{
    private static final Random random;
    static
    {
        random = new Random();
    }
     
    /**
     * 从List集合中随机抽取指定数量的非重复元素
     * <p>注意:集合中不能有null元素,否则返回值中可能有重复的元素
     * @param src List集合源
     * @param chooseCount 抽取的元素个数
     * @return
     * @see [类、类#方法、类#成员]
     */
    public static <T> List<T> randomChooseElements(List<T> src, int chooseCount)
    {
        return randomChooseElements(src, chooseCount, null);
    }
     
    /**
     * 从List集合中随机抽取指定数量的非重复元素
     * @param src  List集合源
     * @param chooseCount 抽取的元素个数
     * @param srcNoContain  集合源中不包含的任意对象
     * @return
     * @see [类、类#方法、类#成员]
     */
    public static <T> List<T> randomChooseElements(List<T> src, int chooseCount, T srcNoContain)
    {
        for (Object element : src)
        {
            if (element == srcNoContain)
            {
                throw new IllegalStateException("指定的不同元素srcNoContain与参数src中的某一个元素相同");
            }
        }
         
        if (chooseCount > src.size())
        {
            throw new IllegalArgumentException("参数chooseCount不能大于集合src的元素个数.");
        }
         
        int sizeOfCopiedList = src.size();
        List<T> copiedList = new ArrayList<T>(src);
         
        List<T> choosedList = new ArrayList<T>();
        int index = -1;
        for (int i = 0; i < chooseCount; i++)
        {
            while (true)
            {
                index = random.nextInt(sizeOfCopiedList);
                if (copiedList.get(index) != srcNoContain)
                {
                    choosedList.add(copiedList.get(index));
                    copiedList.set(index, srcNoContain);
                    break;
                }
            }
        }
         
        return choosedList;
         
    }
     
    /**
     * 从数组中随机抽取指定数量的非重复元素
     * <p>注意:数组中不能有null元素,否则返回值中可能有重复的元素
     * @param src  数组源
     * @param chooseCount 抽取的元素个数
     * @return 
     * @see [类、类#方法、类#成员]
     */
    public static Object[] randomChooseElements(Object[] src, int chooseCount)
    {
        return randomChooseElements(src, chooseCount, null);
    }
     
    /**
     * 从数组中随机抽取指定数量的非重复元素
     * @param src  数组源
     * @param chooseCount   抽取的元素个数
     * @param srcNoContain  源数组不包含的(类类型与数组的元素类型相同)任意对象
     * @return
     * @see [类、类#方法、类#成员]
     */
    public static Object[] randomChooseElements(Object[] src, int chooseCount, Object srcNoContain)
    {
        for (Object element : src)
        {
            if (element == srcNoContain)
            {
                throw new IllegalStateException("指定的不同元素srcNoContain与参数src中的某一个元素相同");
            }
        }
        if (chooseCount > src.length)
        {
            throw new IllegalArgumentException("参数chooseCount不能大于数组参数src的长度.");
        }
         
        Object[] copiedArray = Arrays.copyOf(src, src.length);
         
        Object[] choosedArray = new Object[chooseCount];
        int index = -1;
        for (int i = 0; i < choosedArray.length; i++)
        {
            while (true)
            {
                index = random.nextInt(copiedArray.length);
                if (copiedArray[index] != srcNoContain)
                {
                    choosedArray[i] = copiedArray[index];
                    copiedArray[index] = srcNoContain;
                    break;
                }
            }
        }
        return choosedArray;
    }
     
    public static void main(String[] args)
    {
        List<Date> dates1 = Arrays.asList(new Date(119, 7, 21),
            new Date(119, 3, 12),
            new Date(119, 9, 7),
            new Date(119, 3, 23));
         
        List<Date> selectDates = randomChooseElements(dates1, 3);
        System.out.println("源集合是:"+dates1);
        System.out.println("集合中随机抽取的元素:"+selectDates);
       
       
        System.out.println();
        Date[] dates = new Date[] {new Date(119, 7, 21), new Date(119, 3, 12), new Date(119, 9, 7),
            new Date(119, 3, 23)};
        Object[] arr1 = randomChooseElements(dates, 2);
        System.out.println("源数组是"+Arrays.toString(dates));
        System.out.println("数组中随机选择出来元素" + Arrays.toString(arr1));
         
         
    }
}

  

   控制台输出

 另外,其实JDK自带的Collections工具类提供了两个随机打乱集合的方法shuffle(List<?> list)shuffle(List<?> list, Random rnd) ,经过一此处理变通后,数组和集合都可以用这两个静态方法处理。

 

复制代码
        Date[] dates = new Date[] {new Date(119, 7, 21), new Date(119, 3, 12), new Date(119, 9, 7),
            new Date(119, 3, 23)};
        
        List<Date> copiedDates=new ArrayList<Date>( 
            Arrays.asList(Arrays.copyOf(dates, dates.length)));
      
        Collections.shuffle(copiedDates);
        
        System.out.println(copiedDates);
        System.out.println("原"+Arrays.toString(dates));
复制代码

 


作者:蜀中孤鹰
个性签名:技术如逆水行舟,不进则退;若持之以恒,则水滴穿石。

             IT新手,水平有限,谬误疏漏之处,敬请谅解哦! 

posted @   蜀中孤鹰  阅读(1612)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示