I have an arraylist full of different types of an object. (i.e an objects that extend a superobject)
an example is:
{object1,
object1,
object2,
object3}
Now what I need to do is effectively pull a random object out of the array list. If it matches a set of criteria it will then run a method of this object. Otherwise it will run again till it finds an object till it does.
Now the reason why I can't just go over the objects from start to finish is because I need to provide some form of distribution.
How would I go about this? I know how to iterate over an array list, but Randomly inspecting an object in an array is out of my scope.
This is quite easy using the Random class. Since I don't know what object you are working with, I'll show you an example where you want to randomly search a list of integers until you find one that is less than 10.
ArrayList<int> list = new ArrayList<int>();
Random random = new Random();
do{
int randomlyChosenInt = list.get(random.nextInt(list.Size()));
while(int >= 10);
One way is to shuffle with Collections.shuffle(), then iterate.
Another way is to pick a random element, swap it with the last one, remove it from list and then check. The advantage is that you don't have to swap N time like shuffle does - you only swap until you found a satisfactory element.
Instead of picking random elements, shuffle the array once and then iterate over the result:
Collections.shuffle(objects);
for (Object o : objects) {
// you are now accessing objects in random order
}
Related
I want to know how to add or append a new element to the end of an array. Is any simple way to add the element at the end? I know how to use a StringBuffer but I don't know how to use it to add an element in an array. I prefer it without an ArrayList or list. I wonder if the StringBuffer will work on integers.
You can not add an element to an array, since arrays, in Java, are fixed-length. However, you could build a new array from the existing one using Arrays.copyOf(array, size) :
public static void main(String[] args) {
int[] array = new int[] {1, 2, 3};
System.out.println(Arrays.toString(array));
array = Arrays.copyOf(array, array.length + 1); //create new array from old array and allocate one more element
array[array.length - 1] = 4;
System.out.println(Arrays.toString(array));
}
I would still recommend to drop working with an array and use a List.
Arrays in Java have a fixed length that cannot be changed. So Java provides classes that allow you to maintain lists of variable length.
Generally, there is the List<T> interface, which represents a list of instances of the class T. The easiest and most widely used implementation is the ArrayList. Here is an example:
List<String> words = new ArrayList<String>();
words.add("Hello");
words.add("World");
words.add("!");
List.add() simply appends an element to the list and you can get the size of a list using List.size().
To clarify the terminology right: arrays are fixed length structures (and the length of an existing cannot be altered) the expression add at the end is meaningless (by itself).
What you can do is create a new array one element larger and fill in the new element in the last slot:
public static int[] append(int[] array, int value) {
int[] result = Arrays.copyOf(array, array.length + 1);
result[result.length - 1] = value;
return result;
}
This quickly gets inefficient, as each time append is called a new array is created and the old array contents is copied over.
One way to drastically reduce the overhead is to create a larger array and keep track of up to which index it is actually filled. Adding an element becomes as simple a filling the next index and incrementing the index. If the array fills up completely, a new array is created with more free space.
And guess what ArrayList does: exactly that. So when a dynamically sized array is needed, ArrayList is a good choice. Don't reinvent the wheel.
The OP says, for unknown reasons, "I prefer it without an arraylist or list."
If the type you are referring to is a primitive (you mention integers, but you don't say if you mean int or Integer), then you can use one of the NIO Buffer classes like java.nio.IntBuffer. These act a lot like StringBuffer does - they act as buffers for a list of the primitive type (buffers exist for all the primitives but not for Objects), and you can wrap a buffer around an array and/or extract an array from a buffer.
Note that the javadocs say, "The capacity of a buffer is never negative and never changes." It's still just a wrapper around an array, but one that's nicer to work with. The only way to effectively expand a buffer is to allocate() a larger one and use put() to dump the old buffer into the new one.
If it's not a primitive, you should probably just use List, or come up with a compelling reason why you can't or won't, and maybe somebody will help you work around it.
As many others pointed out if you are trying to add a new element at the end of list then something like, array[array.length-1]=x; should do. But this will replace the existing element.
For something like continuous addition to the array. You can keep track of the index and go on adding elements till you reach end and have the function that does the addition return you the next index, which in turn will tell you how many more elements can fit in the array.
Of course in both the cases the size of array will be predefined. Vector can be your other option since you do not want arraylist, which will allow you all the same features and functions and additionally will take care of incrementing the size.
Coming to the part where you want StringBuffer to array. I believe what you are looking for is the getChars(int srcBegin, int srcEnd,char[] dst,int dstBegin) method. Look into it that might solve your doubts. Again I would like to point out that after managing to get an array out of it, you can still only replace the last existing element(character in this case).
one-liner with streams
Stream.concat(Arrays.stream( array ), Stream.of( newElement )).toArray();
I have just started learning Java, and i can't figure out how to create an array from user input. For example, a user inputs n numbers, and the program outputs the square of each number. Wherever I look, i see that the array length is predefined, and I can't seem to find any comprehensible explanation on how to have it depend on the amount of input values from the user.
You can use an arraylist or a list of integers instead, so that you can add items to the list as and when required. Also, the list would then have only as many elements as the number of inputs.
Syntax:
List<Integer> elements = new ArrayList<Integer>();
To add elements to the list, use:
elements.add(new_item);
To access members of the list, use:
elements.get(index);
Ask user that how many number he wants to enter and define array of that much size .
this is the only way that you can go with if you are new in java.
else you can use ArrayList. for that see COLLECTIONS IN JAVA
You can use java.util.ArrayList instead, it would solve your problem. For your reference http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html
http://docs.oracle.com/javase/7/docs/api/java/util/List.html
You could use an ArrayList instead of an array. It has no predefined size and scales with the amount of inputs.
List<Integer> inputs = new ArrayList<Integer>();
inputs.add(yourNumber);
inputs.get(index);
Link to the JavaDoc: ArrayList API
Am working on some programming homework and am a bit lost. The project is to select the even/odd elements of a listarray and store in another array. It is not the even numbers in each element, but the elements themselves so if an array had values "1,2,5,7,9" and returned the even elements it would give "1, 5, 9". Also have to use recursion. Would anyone be able to give me a starting point or some advice. Though about starting with 2 elements and taking 2nd element and then building up from that, but don't know how it would add on the 2nd pass
public static ArrayList<Integer> even(ArrayList<Integer> list)
ArrayList<Integer> evenlist = ListMethods.deepClone(tList);//make copy of list
if (evenlist.size()<=1) // The list is empty or has one element
{
// return null;// Return the list as is
}
if
(evenlist.size()==2)
{
//return right element
//call method again
//add to list
}
Psuedocode
int[] evens,odds;
function categorize(List<Integer> in,int idx)
if(idx>=in.length)
return
int cur = in[idx]
if(even), add to evens
else add to odds
categorize(in,idx+1)
This sounds similar to the homework I just completed, so if it is (And you're in my class!), I'll not tell you to use any terminology we haven't covered as I know it can be daunting trying to discover something new for practicals (beyond what we have to do).
First, set your exit condition. As you've already said, you have to create a new ArrayList out of the existing one. You are going to remove items from the existing ArrayList, storing the integers that are at even (or odd) indices, until the list is empty.
So your exit condition is:
if (evenList is Empty)
return evenList;
Then, work your way through the steps. I would advise determining if the Array you start with has an even of odd number of steps, something like this:
if (evenList has Even Elements)
int holderForIntsAtEvenElements = last evenList EVEN element
Note we start at the last element, so when you are coming OUT of the recursive method, this will be the last one added to your new ArrayList, and thus it'll be in numerical order. You might find this post interesting to do this: What does this boolean return mean?
We then want to remove the last element from the list and recursively call the method again.
Finally, when we hit our exit condition and start to come out, we want to add the ints we've been storing to them, e.g.:
evenList.add(holderForIntsAtEvenElements);
return evenList;
That doesn't solve one problem, which is what to do with the very first element if the list does NOT have an even number of elements - however, I'll let you try and solve that!
That's a good mix of code and pseudo code and will hopefully help to get you on the right track.
You could use a simple for loop like this:
for (int i = 0; i < list.size(); i += 2) {
System.out.println(list.get(i));
}
If you have to use recursion, here's an outline of the steps you might take. (I won't tell you exactly what to do because you haven't tried anything and it is like homework.)
Take first element and store it
Remove (new) first element from list
Call self
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.
I have few files which I put in array.
I shuffle the files so that it can be displayed in random order.
How to know that array index 0 is actually image1.txt or image2.txt or image3.txt?
Thanks in advance.
String[] a = {"image1.txt","image2.txt","image3.txt"};
List<String> files = Arrays.asList(a);
Collections.shuffle(files);
I'm not sure what you are trying to do.
To access the first element of the shuffled list, use files.get(0).
If you want to know where each element is gone, I suggest you take another approach to it. Create a list of integers from 0 to a.length() - 1, inclusive and shuffle that list. Then manually permute the array a to a new collection.
INCORRECT - see explanation
Note: Arrays.asList() will create a NEW list with the contents of the passed array. The original array will not be modified at all when you use Collections.shuffle().
Explanation
Peter has correctly pointed our that Arrays.asList() does NOT make a copy. The returned list is "write-through" back to the original array. Shuffling the list will shuffle the contents of the original array. Also worth noting that the list is immutable (new elements cannot be added) but typically I find that the use of Arrays.asList() involves immutable lists anyway.
files.get(0); // get the first elements in shuffled list, random
// as greg said
int index = files.indexOf(a[0]); // find out where "image1.txt" is in the list
files.get(index); // get "image1.txt" back from the list