Why with streams? You just have to get a random number from 0 to the size of the list and then call get on this index:

Random r = new Random();
ElementType e = list.get(r.nextInt(list.size()));

Stream will give you nothing interesting here, but you can try with:

Random r = new Random();
ElementType e = list.stream().skip(r.nextInt(list.size())).findFirst().get();

Idea is to skip an arbitrary number of elements (but not the last one!), then get the first element if it exists. As a result you will have an Optional<ElementType> which will be non empty and then extract its value with get. You have a lot of options here after having skip.

Using streams here is highly inefficient...

Note: that none of these solutions take in account empty lists, but the problem is defined on non-empty lists.

Answer from Jean-Baptiste Yunès on Stack Overflow
🌐
Baeldung
baeldung.com › home › java › java list › java – get random item/element from a list
Java - Get Random Item/Element From a List | Baeldung
April 4, 2025 - In this article, we’ll show the ... random item from a List instance, you need to generate a random index number and then fetch an item by this generated index number using List.get() method....
Discussions

java - How to get random objects from a stream - Stack Overflow
Lets say I have a list of words and i want to create a method which takes the size of the new list as a parameter and returns the new list. How can i get random words from my original sourceList? ... More on stackoverflow.com
🌐 stackoverflow.com
java - How to get random objects from a stream and return it - Stack Overflow
I have List with some users from google and now in stream I say for every google user make new HRVacationUser ( witch is model ) and give me ( their email, some random date, some random date ) which More on stackoverflow.com
🌐 stackoverflow.com
Java 8 Stream.findAny() vs finding a random element in the stream - Stack Overflow
In my Spring application, I have a Couchbase repository for a document type of QuoteOfTheDay. The document is very basic, just has an id field of type UUID, value field of type String and created ... More on stackoverflow.com
🌐 stackoverflow.com
How to generate random array of ints using Stream API Java 8? - Stack Overflow
I am trying to generate random array of integers using new Stream API in Java 8. But I haven't understood this API clearly yet. So I need help. Here is my code. Random random = new Random(); IntS... More on stackoverflow.com
🌐 stackoverflow.com
July 23, 2025
🌐
Reddit
reddit.com › r/javahelp › need to get a random item from a stream if there are multiple items of the same value
r/javahelp on Reddit: Need to get a random item from a stream IF there are multiple items of the same value
May 3, 2016 -

Hey Guys,

So I need some help with some Java code. I don't want to put the code up as it is part of a programming assessment, but I AM allowed to ask for help.

Basically, I have a stream that has a map function applied to it, a max function (to find the maximum value in the stream) and then another map function to determine if I am interested in that item.

The issue is when I have multiple max values, I need to get one randomly from the stream.

Ex:

If I have 1 3 5 5 7 9 9 9, I need one of the 9 chosen randomly. I used integers in this example, but I am analyzing objects with a price tag on them, so I need to find the maximum valued objects (9 9 9), and then randomly select one.

So far I figured I could do something like filter the stream to get a max, store the max value somewhere, then analyze the stream again to get any other objects with the same value as the max, and then store that into an ArrayList. From there, I can use Java.util.Random to generate a random value between 0 and the size of the array list, and then send that to the final map function.

The issue I am running into is I don't know how to handle the other items in the stream.

The stream is going through all the values, and either saying "Interested" or "Not Interested" to all the items, but if I do what I discussed above, I'd only be handling the maximum, randomly chosen value... I don't know what to do with the others...

Any help???

Top answer
1 of 12
29

I've found a proper solution. Random provides a few methods to return a stream. For example ints(size) which creates a stream of random integers.

public List<String> createList(int listSize)
{
   Random rand = new Random();
   List<String> wordList = 
       rand
           .ints(listSize, 0, sourceWords.size())
           .mapToObj(i -> sourceWords.get(i))
           .collect(Collectors.toList());
   return wordList;
}
2 of 12
16

I think the most elegant way is to have a special collector.

I am pretty sure the only way you can guarantee that each item has an equal chance of being picked, is to collect, shuffle and re-stream. This can be easily done using built-in Collectors.collectingAndThen(...) helper.

Sorting by a random comparator or using randomized reducer, like suggested on some other answers, will result in very biased randomness.

List<String> wordList = sourceWords.stream()
  .collect(Collectors.collectingAndThen(Collectors.toList(), collected -> {
      Collections.shuffle(collected);
      return collected.stream();
  }))
  .limit(listSize)
  .collect(Collectors.toList());

You can move that shuffling collector to a helper function:

public class CollectorUtils {

    public static <T> Collector<T, ?, Stream<T>> toShuffledStream() {
        return Collectors.collectingAndThen(Collectors.toList(), collected -> {
            Collections.shuffle(collected);
            return collected.stream();
        });
    }

}

I assume that you are looking for a way to nicely integrate with other stream processing functions. So following straightforward solution is not what you are looking for :)

Collections.shuffle(wordList)
return wordList.subList(0, limitSize)
🌐
Medium
medium.com › @khemanta › navigating-the-stream-selecting-a-random-element-aedb55d46fb3
Navigating the Stream: Selecting a Random Element | by Hemant, K. Mishra | Medium
January 7, 2024 - For each subsequent element i (where i > k), randomly choose to replace an element in the reservoir with probability k/i. By the end of the stream, the reservoir should contain a randomly selected element with uniform probability.
🌐
Andbin
andbin.dev › home › generating random values with the stream api
Generating random values with the Stream API – andbin.dev
March 9, 2023 - This article describes how to generate random values (numbers and objects) using the Java Stream API introduced in JDK 8.
🌐
HowToDoInJava
howtodoinjava.com › home › java 8 › stream of random numbers in java
Stream of Random Numbers in Java
March 3, 2022 - Let’s learn to use the above-discussed methods to create a stream of random numbers. Random random = new Random(); //1 IntStream randStream = random.ints(5); randStream.forEach(System.out::println); //2 DoubleStream doubleStream = random.doubles(5, 0, 0.5); doubleStream.forEach(System.out::println); //collect to list List<Long> longs = random.longs(5) .boxed() .collect(Collectors.toList()); To get the stream of secure random numbers (i.e.
🌐
GeeksforGeeks
geeksforgeeks.org › dsa › select-a-random-number-from-stream-with-o1-space
Select a random number from stream, with O(1) space - GeeksforGeeks
July 23, 2025 - import random # A function to randomly ... - 1 i = random.randrange(count); # Replace the prev random number # with new number with 1/count # probability if (i == count - 1): res = x; return res; # Driver Code stream = [1, 2, 3, 4]; n = len(stream); # Use a different ...
Find elsewhere
🌐
4Comprehension
4comprehension.com › home › a case study of implementing an efficient shuffling stream/spliterator in java
A Case Study of Implementing an Efficient Shuffling Stream/Spliterator in Java - { 4Comprehension }
November 30, 2017 - To spare precious CPU cycles, instead of pre-shuffling the whole collection, we can just fetch the number of elements that match the upstream demand. To achieve that, we need to implement a custom Spliterator that will allow us to iterate through objects in random order, and then we’ll be able to construct a Stream instance by using a helper method from the StreamSupport class:
🌐
Dirask
dirask.com › posts › Java-8-Int-Stream-API-generate-list-with-10-random-numbers-wDk3AD
Java 8 - Int Stream API generate list with 10 random numbers
5 days ago - @param streamSize the number of values to generate @param randomNumberOrigin the origin (inclusive) of each random value @param randomNumberBound the bound (exclusive) of each random value ...
🌐
Crunchify
crunchify.com › java j2ee tutorials › in java how to get random element from arraylist and threadlocalrandom usage
In Java How to Get Random Element from ArrayList and ThreadLocalRandom Usage • Crunchify
January 29, 2023 - Loop # 1 : Facebook Loop # 2 : Uber Loop # 3 : Twitter Loop # 4 : Twitter Loop # 5 : Google Loop # 6 : Google Loop # 7 : Uber Loop # 8 : Paypal Loop # 9 : Yahoo Loop # 10 : Google RandomDouble: 108.81696504186543 RandomInteger: 10 · Let me know if you face any issue running this code. If you liked this article, then please share it on social media. Have a question or suggestion? Please leave a comment to start the discussion. What is Lock(), UnLock(), ReentrantLock(), TryLock() and How it’s different from Synchronized Block in Java?
🌐
Stack Overflow
stackoverflow.com › questions › 51493859 › how-to-get-random-objects-from-a-stream-and-return-it
java - How to get random objects from a stream and return it - Stack Overflow
My allGoogleUsers list is with ... give me holiday users :) ... import java.util.Random; List<?> yourList = new ArrayList<>(); yourList.get(new Random().nextInt(yourList.size()));...
Top answer
1 of 2
27

The reason behind findAny() is to give a more flexible alternative to findFirst(). If you are not interested in getting a specific element, this gives the implementing stream more flexibility in case it is a parallel stream.

No effort will be made to randomize the element returned, it just doesn't give the same guarantees as findFirst(), and might therefore be faster.

This is what the Javadoc says on the subject:

The behavior of this operation is explicitly nondeterministic; it is free to select any element in the stream. This is to allow for maximal performance in parallel operations; the cost is that multiple invocations on the same source may not return the same result. (If a stable result is desired, use findFirst() instead.)

2 of 2
11

Don’t collect into a List when all you want is a single item. Just pick one item from the stream. By picking the item via Stream operations you can even handle counts bigger than Integer.MAX_VALUE and don’t need the “interesting” way of hiding the fact that you are casting a long to an int (that Long.valueOf(repository.count()).intValue() thing).

public Optional<QuoteOfTheDay> random() {
    long count = repository.count();
    if(count==0) return Optional.empty();
    Random r = new Random();
    long randomIndex=count<=Integer.MAX_VALUE? r.nextInt((int)count):
        r.longs(1, 0, count).findFirst().orElseThrow(AssertionError::new);
    return StreamSupport.stream(repository.findAll().spliterator(), false)
        .skip(randomIndex).findFirst();
}
Top answer
1 of 8
14

The shuffling approach works reasonably well, as suggested by fge in a comment and by ZouZou in another answer. Here's a generified version of the shuffling approach:

static <E> List<E> shuffleSelectN(Collection<? extends E> coll, int n) {
    assert n <= coll.size();
    List<E> list = new ArrayList<>(coll);
    Collections.shuffle(list);
    return list.subList(0, n);
}

I'll note that using subList is preferable to getting a stream and then calling limit(n), as shown in some other answers, because the resulting stream has a known size and can be split more efficiently.

The shuffling approach has a couple disadvantages. It needs to copy out all the elements, and then it needs to shuffle all the elements. This can be quite expensive if the total number of elements is large and the number of elements to be chosen is small.

An approach suggested by the OP and by a couple other answers is to choose elements at random, while rejecting duplicates, until the desired number of unique elements has been chosen. This works well if the number of elements to choose is small relative to the total, but as the number to choose rises, this slows down quite a bit because of the likelihood of choosing duplicates rises as well.

Wouldn't it be nice if there were a way to make a single pass over the space of input elements and choose exactly the number wanted, with the choices made uniformly at random? It turns out that there is, and as usual, the answer can be found in Knuth. See TAOCP Vol 2, sec 3.4.2, Random Sampling and Shuffling, Algorithm S.

Briefly, the algorithm is to visit each element and decide whether to choose it based on the number of elements visited and the number of elements chosen. In Knuth's notation, suppose you have N elements and you want to choose n of them at random. The next element should be chosen with probability

(n - m) / (N - t)

where t is the number of elements visited so far, and m is the number of elements chosen so far.

It's not at all obvious that this will give a uniform distribution of chosen elements, but apparently it does. The proof is left as an exercise to the reader; see Exercise 3 of this section.

Given this algorithm, it's pretty straightforward to implement it in "conventional" Java by looping over the collection and adding to the result list based on the random test. The OP asked about using streams, so here's a shot at that.

Algorithm S doesn't lend itself obviously to Java stream operations. It's described entirely sequentially, and the decision about whether to select the current element depends on a random decision plus state derived from all previous decisions. That might make it seem inherently sequential, but I've been wrong about that before. I'll just say that it's not immediately obvious how to make this algorithm run in parallel.

There is a way to adapt this algorithm to streams, though. What we need is a stateful predicate. This predicate will return a random result based on a probability determined by the current state, and the state will be updated -- yes, mutated -- based on this random result. This seems hard to run in parallel, but at least it's easy to make thread-safe in case it's run from a parallel stream: just make it synchronized. It'll degrade to running sequentially if the stream is parallel, though.

The implementation is pretty straightforward. Knuth's description uses random numbers between 0 and 1, but the Java Random class lets us choose a random integer within a half-open interval. Thus all we need to do is keep counters of how many elements are left to visit and how many are left to choose, et voila:

/**
 * A stateful predicate that, given a total number
 * of items and the number to choose, will return 'true'
 * the chosen number of times distributed randomly
 * across the total number of calls to its test() method.
 */
static class Selector implements Predicate<Object> {
    int total;  // total number items remaining
    int remain; // number of items remaining to select
    Random random = new Random();

    Selector(int total, int remain) {
        this.total = total;
        this.remain = remain;
    }

    @Override
    public synchronized boolean test(Object o) {
        assert total > 0;
        if (random.nextInt(total--) < remain) {
            remain--;
            return true;
        } else {
            return false;
        }
    }
}

Now that we have our predicate, it's easy to use in a stream:

static <E> List<E> randomSelectN(Collection<? extends E> coll, int n) {
    assert n <= coll.size();
    return coll.stream()
        .filter(new Selector(coll.size(), n))
        .collect(toList());
}

An alternative also mentioned in the same section of Knuth suggests choosing an element at random with a constant probability of n / N. This is useful if you don't need to choose exactly n elements. It'll choose n elements on average, but of course there will be some variation. If this is acceptable, the stateful predicate becomes much simpler. Instead of writing a whole class, we can simply create the random state and capture it from a local variable:

/**
 * Returns a predicate that evaluates to true with a probability
 * of toChoose/total.
 */
static Predicate<Object> randomPredicate(int total, int toChoose) {
    Random random = new Random();
    return obj -> random.nextInt(total) < toChoose;
}

To use this, replace the filter line in the stream pipeline above with

        .filter(randomPredicate(coll.size(), n))

Finally, for comparison purposes, here's an implementation of the selection algorithm written using conventional Java, that is, using a for-loop and adding to a collection:

static <E> List<E> conventionalSelectN(Collection<? extends E> coll, int remain) {
    assert remain <= coll.size();
    int total = coll.size();
    List<E> result = new ArrayList<>(remain);
    Random random = new Random();

    for (E e : coll) {
        if (random.nextInt(total--) < remain) {
            remain--;
            result.add(e);
        }
    }            

    return result;
}

This is quite straightforward, and there's nothing really wrong with this. It's simpler and more self-contained than the stream approach. Still, the streams approach illustrates some interesting techniques that might be useful in other contexts.


Reference:

Knuth, Donald E. The Art of Computer Programming: Volume 2, Seminumerical Algorithms, 2nd edition. Copyright 1981, 1969 Addison-Wesley.

2 of 8
4

You could always create a "dumb" comparator, that will compare elements randomly in the list. Calling distinct() will ensure you that the elements are unique (from the queue).

Something like this:

static List<Integer> nDistinct(Collection<Integer> queue, int n) {
    final Random rand = new Random();
    return queue.stream()
                .distinct()
                .sorted(Comparator.comparingInt(a -> rand.nextInt()))
                .limit(n)
                .collect(Collectors.toList());
}

However I'm not sure it will be more efficient that putting the elements in the list, shuffling it and return a sublist.

static List<Integer> nDistinct(Collection<Integer> queue, int n) {
    List<Integer> list = new ArrayList<>(queue);
    Collections.shuffle(list);
    return list.subList(0, n);
}

Oh, and it's probably semantically better to return a Set instead of a List since the elements are distincts. The methods are also designed to take Integers, but there's no difficulty to design them to be generic. :)

Just as a note, the Stream API looks like a tool box that we could use for everything, however that's not always the case. As you see, the second method is more readable (IMO), probably more efficient and doesn't have much more code (even less!).

🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › util › stream › Stream.html
Stream (Java Platform SE 8 )
5 days ago - Returns an infinite sequential unordered stream where each element is generated by the provided Supplier. This is suitable for generating constant streams, streams of random elements, etc.
🌐
GeeksforGeeks
geeksforgeeks.org › java › randomly-select-items-from-a-list-in-java
Randomly Select Items from a List in Java - GeeksforGeeks
July 11, 2025 - // Randomly select an element from ... base on index // and return an element public int getRandomElement(List<Integer> l) { Random r = new Random(); return l.get(r.nextInt(l.size())); } }...
🌐
TutorialsPoint
tutorialspoint.com › randomly-select-items-from-a-list-in-java
Randomly select items from a List in Java
May 16, 2023 - Create an ArrayList and store some elements in it by using ?add()? method. Define an object of class ?Random?. The object will check whole list and select an item using ?nextInt()? method. Then, using ?get()? method we will fetch that item and store it in an integer variable. import java.util.*; public class Randomly { public static void main(String[] args) { // Creating arraylist ArrayList<Integer> araylist = new ArrayList<Integer>(); // Adding elements in arraylist araylist.add(8); araylist.add(5); araylist.add(2); araylist.add(9); araylist.add(4); araylist.add(7); System.out.println("Elemen
🌐
Medium
medium.com › @AlexanderObregon › javas-stream-generate-method-explained-ca60e6cdb939
Java’s Stream.generate() Method Explained | Medium
December 1, 2024 - Learn how Java's Stream.generate() method works, its use cases for creating test data, random values, custom objects, and how to manage infinite streams.