Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sampling with no replacement in Java from an ArrayList

I have an arrayList with 30 elements. I'd like to create many sublists of 15 elements from this list. What's the efficient way of doing so?

Right now I clone the ArrayList and use remove(random) to do it, but I am sure this is too clumsy. What should I do instead? Does Java have a "sample" function like in R?



Clarification: by sampling with no replacement I mean take at random 15 unique elements from the 30 available in the original list. Moreover I want to be able to do this repeatedly.

like image 968
CarrKnight Avatar asked Jan 22 '12 21:01

CarrKnight


3 Answers

Use the Collections#shuffle method to shuffle your original list, and return a list with the first 15 elements.

like image 180
Robin Avatar answered Oct 01 '22 00:10

Robin


Consider creating new list and adding random elements from current list instead of copying all elements and removing them.

Another way to do this is to create some kind of View on top of the current list.

Implement an Iterator interface that randomly generates index of element during next operation and retrieves element by index from current list.

like image 21
Mairbek Khadikov Avatar answered Oct 01 '22 01:10

Mairbek Khadikov


No, Java does not have a sample function like in R. However, it is possible to write such a function:

// Samples n elements from original, and returns that list
public <T> static List<T> sample(List<T> original, int n) {
    List<T> result = new ArrayList<T>(n);
    for (int i = 0; i < original.size(); i++) {
        if (result.size() == n)
            return result;
        if ((n - result.size()) >= (original.size() - i)) {
            result.add(original.get(i));
        } else if (Math.random() < ((double)n / original.size())) {
            result.add(original.get(i));
        }
    }

    return result;
}

This function iterates through original, and copies the current element to result based on a random number, unless we are near enough to the end of original to require copying all the remaining elements (the second if statement in the loop).

like image 39
Adam Mihalcin Avatar answered Oct 01 '22 01:10

Adam Mihalcin