• 周一. 10 月 7th, 2024

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

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

admin

11 月 28, 2021

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

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));

发表回复