工具类:随机抽取数组或集合中的几个不重复元素
其中的关键在于:每次循环随机获得一个下标,如果是首次访问到这个下标,将这个元素抽出到返回结果数组中,然后让这个数组下标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));
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步