This question already has answers here:
Randomly select an item from a list
(5 answers)
Closed 4 years ago.
I am using java.util.LinkedList
Is there any method that helps me with this?
int len = list.size();
Random randomGenerator = new Random();
int randomInt = randomGenerator.nextInt(len);
If you only need one element you can use the Random class to generate a (pseudo) random value (as you wrote in your question):
E element = list.get(new Random().nextInt(list.size()));
Remember LinkedList.get(index) is an O(n) operation, as noted in the comments it's better to use an ArrayList for this purpose.
If you want to shuffle the whole array you can use the Collections api like this:
Collections.shuffle(list);
You can also shuffle the List using Collections.shuffle and pick the first element everytime though this might be a bit expensive computation wise. Just another trick you should be aware of. :-)
final List<String> lst = Arrays.asList("a", "b", "c");
Collections.shuffle(lst);
final String rndStr = lst.get(0);
Get the list length with size(), create a random number between 0 and size-1 and use get(index) to retrieve the element with that index.
If you really need just one element, go with dacwe's solution. If you need several values (e.g. when simulating a card game, bingo etc.) you can use java.util.Collections.shuffle(list);, and call list.remove(0); for every element you need.
Related
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.
Use the Collections#shuffle method to shuffle your original list, and return a list with the first 15 elements.
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.
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).
This is a basic combinatorics problem. You have 30 elements in your list, and you want to choose 15. If the order matters, you want a permutation, if it doesn't matter, you want a combination.
There are various Java combinatorics samples on the web, and they typically use combinadics. I don't know of any ready made Java libraries, but Apache Math Commons has binomial coefficient support to help you implement combinadics if you go that route. Once you have a sequence of 15 indices from 0 to 29, I'd suggest creating a read-only iterator that you can read the elements from. That way you won't have to create any new lists or copy any references.
This question already has answers here:
Picking a random element from a set
(34 answers)
Closed 2 years ago.
I'm working on a problem in which I need to pull a random String from a keySet. Just wondering if anyone can give me some direction here. I'm pretty lost on it. I've found quite a few ways to do it if I were using an int, but not a String. For example I want to quiz a user on States and their Capitals, and to pull out a random Key from the keySet for the question.
Here's the set:
Set<String> states = stateCapitals.keySet();
Set is not the best data structure for random indexing.
Better convert to a List and use a random generator to select an index. If you really need to stay with a Set, you can generate a random index n and iterate through the Set, stop at the nth element. For selecting multiple elements, there is no benefit of working with a List. Any iterable would be fine.
The key idea is to dynamically adjust selection probability so you can choose m (out of sizeof(Set)): In the easiest example of m=1, select 1st element with probability of 1/N, if you didn't select it, select 2nd element with probability 1/(N-1)..and so on.
Use conditional probability to show all elements are selected under a fair chance 1/N.
A keySet similar to HashSet is un-ordered and thus makes no guarantee to the order of the element in the set. So pulling a random string might not be as effective thing to do from a set.
Convert the set into arrays or list and then performing random string gets might be good solution.
String ranKey = map.keySet().toArray()[new Random().nextInt(map.keySet().size())].toString();
Try this code
onPress: function () {
debugger;
var textArray = ['Pritesh', 'Nimesh', 'Harshil', 'Ravi', 'Amit', 'Brijesh'];
var randomNumber = Math.floor(Math.random() * textArray.length);
for (var i = 0; i < textArray.length; i++) {
if (i === randomNumber) {
console.log(textArray[i]);
}
}
ArrayList<States> statesList = new ArrayList<>( states );
State x = statesList.get( (int)(statesList.size() * Math.random()) );
The code above will get what you want but this could be inefficient if it's a very large list.
Simple question, but everytime I google it there are only examples using an ArrayList, and list.indexOf(3), doesn't work on int[] nums = new int[10]. Soo im a little confused.
Here's the real problem. You appear to think that
int[] nums = new int[10]
is defining a List or a list. It isn't. It is an array. The words "list" and "array" are NOT synonymous in the context of Java. So when you Google for "finding an index of an element in a list" ... you don't get any useful hits.
If you use the >>correct<< terms when searching (Google, SO search, anything) you are far more likely to get useful search results.
For example:
How to find index of int array in Java from a given value?
FWIW, if you want a (real) list of integers in Java you declare it like this:
List<Integer> nums = new ArrayList<>();
Notes
You have to use Integer as the type parameter, not int.
You don't need to provide 10 as a parameter. And if you do, it is a hint that tells the ArrayList what the initial capacity of the list should be. (For an array it is the actual size ... and it can't be changed).
If you want to use indexOf(3) on an array you could create a List from it
ArrayList<Integer> myInts = new ArrayList<Integer>(Arrays.asList(array))
and then you can use
myInts.indexOf(3)
This question already has answers here:
How to convert Set<String> to String[]?
(7 answers)
Closed 4 years ago.
I'm trying to convert my set of Strings to an array of Strings so I can operate on them one by one. Is there a better way of doing this or is converting to arrays a good way? However, when I try converting to an array like below then I get errors as it doesn't think that it will always be strings passed in. Would appreciate some pointers.
Set<String> s;
s.add("a");
s.add("b");
String[] item = s.toArray();
You do not have to convert a Set to an array just to operate on the elements. You can iterate over the elements directly
Set<String> s = new HashSet<>();
....
for (String item : s)
{
do something...
}
so I can operate on them one by one
You don't have to convert it to an array for that.
Instead iterate using the for-each loop or the iterator.
you can do something like this
String[] item = s.toArray(new String[s.size()]);
As per Java doc - toArray function ( which is the one you need )
toArray() Returns an array containing all of the elements in this list
in proper sequence (from first to last element).
Simple question here -- mostly about APIs.
I want to iterate through an array in random order.
It is easy enough to:
fill a List with the numbers 0 to N
shuffle the List with Collections.shuffle
Use this shuffled list to guide my array iteration.
However, I was wondering if step 1 (generating the list of numbers from 0 to N) exists somewhere in prewritten code.
For instance, could it be a convenience method in guava's XYZ class??
The closest thing in Guava would be
ContiguousSet.create(Range.closedOpen(0, n), DiscreteDomains.integers())
...but, frankly, it is probably more readable just to write the for loop yourself.
Noting specifically your emphasis on 'quick', I can't imagine there'd be much quicker than
List<Integer> = new ArrayList<Integer>(range);
and then iterating and populating each entry. Note that I set the capacity in order to avoid having the list resize under the covers.
You may want to check out the Apache Commons which among many other usefull functions, implement the nextPermutation method in RandomDataGenerator class
This is obviously something much bigger then a method of populating the List or array, but commons are really powerfull libraries, which give much more good methods for mathematical computations.
Java doesn't allow you to auto-populate your values. See this question for the ways to populate an array in java
"Creating an array of numbers without looping?"
If you skip step 1 and just do the shuffeling immediately I think you will have the fastest solution.
int range = 1000;
List<Integer> arr = new ArrayList<Integer>(range);
for(int i=0;i<range;i++) {
arr.add((int)(Math.random()*i), new Integer(i));
}