suppose I have arraylist of integers...is there a way that I can generate a random permutation/arrangement of the elements in the arraylist
so if the list is {1,2,3,4,5,6}
calling some method randomPermute() would change it to something random like
{1,3,2,6,5,4}
Collections.shuffle() does the job:
public static void shuffle(List<?> list) -
Randomly permutes the specified list using a default source of randomness. All permutations occur with approximately equal likelihood.
http://download.oracle.com/javase/6/docs/api/java/util/Collections.html#shuffle(java.util.List)
For example
ArrayList<Integer>anArrayList = new ArrayList<Integer>();
anArrayList.add(1);
anArrayList.add(2);
anArrayList.add(3);
anArrayList.add(4);
anArrayList.add(5);
System.out.println(anArrayList);
Collections.shuffle(anArrayList);
System.out.println(anArrayList);
Sample Output
[1, 2, 3, 4, 5]
[3, 5, 1, 2, 4]
You can use the Knuth shuffle: go through the positions 1 through n−1, and for each position i swap the element currently there with an arbitrarily chosen element from positions i through n, inclusive.
Edit: The answer by hooch is better. :)
A simple example:
ArrayList<MyObject> myObjects = new ArrayList<MyObject>();
//code -- load myObjects...
Collections.shuffle(myObjects);
Related
Here is my code
import java.util.*;
public class ArrayExample {
public static void main(String[] args) {
Integer arr[] = {5,4,3,2,15,8,9};
List<Integer> list = Arrays.asList(arr);
Collections.sort(list);
System.out.println(list);
list.add(6);// here I am adding 6 to my array.
System.out.println(list);
// Here I should get output as [2,3,4,5,6,8,9,15]
}
}
You can't because this declaration :
List<Integer> list = Arrays.asList(arr);
From documentation :
Arrays.asList Returns a fixed-size list backed by the specified array. (Changes to the returned list "write through" to the array.)
This method acts as bridge between array-based and collection-based
APIs, in combination with Collection.toArray(). The returned list is
serializable and implements RandomAccess.
for that you can't add to this list, even if you try to remove list.remove(index); this not work.
so to solve your problem you can use :
List<Integer> list = new ArrayList<>();//declare the list
for(Integer i : arr){
list.add(i);//add element by element to the list
}
Or simply you can use :
List<Integer> list = new ArrayList<>(Arrays.asList(arr));
//----------------------------------^------------------^
If you want the array to stay sorted, you will have to sort it after each insert.
However, using a binary search, you could also find the index i where the item should be inserted and insert it there using list.add(i,6). Which would be more efficient.
No you cannot add, as you are using Arrays.asList(arr);
List<Integer> list = Arrays.asList(arr);
asList returning a fixed-size list, you cannot add any element in that, once the list is formed.
You may get java.lang.UnsupportedOperationException
[2, 3, 4, 5, 8, 9, 15]
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
at Test.main(Test.java:14)
You can add an element without using a list by using 2 arrays: a source array src and a destination array dest. The destination array will have one more element than the source one. You simply need to copy all the elements of the source array to the destination, and add your new element. Depends on different requirement of your post title & your post body, I added 2 solutions:
Solution 1
This solution add an element to your array AFTER sorting the array, as mentioned in the post title. But please notice that the element added is located at the tail of the new array.
Integer src[] = { 5, 4, 3, 2, 15, 8, 9 };
Integer dest[] = new Integer[src.length + 1];
Arrays.sort(src);
System.out.println(Arrays.toString(src));
// [2, 3, 4, 5, 8, 9, 15]
System.arraycopy(src, 0, dest, 0, src.length);
dest[src.length] = 6;
System.out.println(Arrays.toString(dest));
// [2, 3, 4, 5, 8, 9, 15, 6]
// ^
Solution 2
This solution add an element to your array BEFORE sorting the array. It contains the expected array as mentioned in your code comment in the post body.
Integer src[] = { 5, 4, 3, 2, 15, 8, 9 };
Integer dest[] = new Integer[src.length + 1];
System.arraycopy(src, 0, dest, 0, src.length);
dest[src.length] = 6;
Arrays.sort(dest);
System.out.println(Arrays.toString(dest));
// [2, 3, 4, 5, 6, 8, 9, 15]
// ^
See also:
Sorting methods in Arrays (Java Platform SE 8) - Oracle Help Center
System#arraycopy(Object, int, Object, int, int)
I can only seem to find answers about last/first element in a list or that you can get a specific item etc.
Lets say I have a list of 100 elements, and I want to return the last 40 elements. How do I do that? I tried doing this but it gave me one element..
Post last40posts = posts.get(posts.size() -40);
Do use the method sub list
List<Post> myLastPosts = posts.subList(posts.size()-40, posts.size());
(To complete Ankit Malpani answer)
If 40 is provided by our lovely users, then you will have to restrict it to the list size:
posts.subList(posts.size()-Math.min(posts.size(),40), posts.size())
Another way to show it:
#Test
public void should_extract_last_n_entries() {
List<String> myList = Arrays.asList("0","1","2","3","4");
int myListSize = myList.size();
log.info(myList.subList(myListSize,myListSize).toString()); // output : []
log.info(myList.subList(myListSize-2,myListSize).toString()); // output : [3, 4]
log.info(myList.subList(myListSize-5,myListSize).toString()); // output : [0, 1, 2, 3, 4]
int lastNEntries = 50; // now use user provided int
log.info(myList.subList(myListSize-Math.min(myListSize,lastNEntries),myListSize).toString());
// output : [0, 1, 2, 3, 4]
// log.info(myList.subList(myListSize-lastNEntries,myListSize).toString());
// ouch IndexOutOfBoundsException: fromIndex = -45
}
Your code will give you only a single element.
You need to use subList method like:
posts.subList(posts.size()-40, posts.size())
I'm trying to, given some ArrayList of Integers, create all the permutations of that list. I want to store each permutation (an ArrayList itself) in a bigger ArrayList of ArrayLists. I can find the permutations and print each to the console without an issue. I haven't found a way to successfully add them to a list. My current attempt is shown below.
//myList is a field that I need to use elsewhere
//a is the ArrayList of Integers
//initially, n is a.size()
private static void perm2(ArrayList<ArrayList<Integer>> myList,
ArrayList<Integer> a, int n)
{
for (int i = 0; i < n; i++)
{
swap(a, i, n-1);
perm2(where, a, n-1);
swap(a, i, n-1);
}
if (n == 1)
{
System.out.println(a.toString());
myList.add(a);
return;
}
}
Here is the output given [0, 1, 2]:
[1, 2, 0]
[2, 1, 0]
[2, 0, 1]
[0, 2, 1]
[1, 0, 2]
[0, 1, 2]
[[0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]]
The print code is sending the right thing to the console, so why isn't it adding the right thing immediately after? If this isn't a good way to go about it, which direction should I look to? Ultimately, these are indices to retrieve data from a list in every order.
Thanks in advance.
I should note that the input list can be of arbitrary length, within reasonable computing capabilities.
EDIT: oversight on my part. Here's the swap code:
private static void swap(ArrayList<Integer> list, int a, int b)
{
T temp = list.get(a);
list.set(a, list.get(b));
list.set(b, temp);
}
You always store the same list in the list of lists. Then you swap its elements and store it again. So you end up with N references to the same list. You need to make a copy of the list before storing it in the list of lists:
myArray.add(new ArrayList<>(a));
You haven't shown us swap, but I assume it is modifying the list in place. The list of lists then contains multiple references to the same underlying list, which is in the final permuted state. Basically, you've put a mutable object into a list and then changed it, while expecting it to be in the state it was in when you first added it to the list.
One way to fix this is to make a defensive copy of the list at the time you add it:
myArray.add(new ArrayList<Integer>(a));
(Also, you call your variable myArray and say, "add them to an array", but myArray is a List and you are adding things to a list. I was a bit confused when I first read your question. You shouldn't refer to a list as an array.)
Each time when you call 'add' method on myArray, elements of 'a' are not copied. myArray will hold a refernece to 'a' only. Since the reference is always the same, the latest state of 'a' element will be printed.
Try to print the content of myArray right after myArray.add(a) to see what I mean.
You do need to create a new instance of ArrayList to avoid this problem
I have an arraylist with the size 0 or .. any size. And I want to turn anything inside into string list. So, suppose the arraylist has the size of 10 and I only want the first 5 elements of it. Instead of doing a for loop, any other efficient method?
Thanks.
You could use the subList method:
List<String> s = new ArrayList<>(Arrays.asList("one","two","three","four"));
List<String> sub = s.subList(0,2); //["one","two"]
Something like this, maybe?
List<Integer> intList = Arrays.asList(1, 2, 3, 5, 6, 7, 8, 9);
List<String> stringList = intList.stream().map(i -> i.toString())
.limit(5).collect(Collectors.toList());
System.out.println(stringList);
I'm not sure whether I understood your question correctly, but this way, you can turn anything into a list of strings first and limit it thereafter.
This is a programming question on my homework for one of my courses. I haven't programmed in a couple years and I wasn't that great to begin with. I'm currently going through tutorials to get back up to speed, but it will take some time. If you guys can help me out with this problem, I would really appreciate it.
Constraints:
Each term of this sequence is a positive integer of the form 2^i*3^j*5^k, for all non-negative integers i, j, and k with
i + j + k >= 1.
Can't use arrays. The algorithm to solving this problem must involve the repeated creation and merger of lists. Specifically 5 lists; a final list, temp list, and three term lists.
"The final list grows by being merged with the current temp list. The temp list, in turn, is replaced by the merger of the three term lists. New term lists are generated by multiplying the new temp list by 2, 3, and 5 respectively"
The desired sequence would go as follows: 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, . . .
As you've explained in your question, you might do your algorithm recursively.
At step n:
The final list will represent the set F(n) = {m | m = 2^i*3^j*5^k, 1<=i+j+k<=n}
The temp list will represent the set T(n) = {m | m = 2^i*3^j*5^k, i+j+k=n}
Then, the "L2" term list will be L2(n) = 2*T(n-1)
the "L3" term list will be L3(n) = 3*T(n-1)
the "L5" term list will be L5(n) = 5*T(n-1)
To get T, T(n) = merge(L2(n), L3(n), L5(n))
To get F, F(n) = merge(F(n-1), T(n))
Once you've got this, you have to implement a function to merge 2 lists. In the main function, you just have to translate these in Java.
You can also make the lists always sorted so that merge is easy and efficient! In java, I think you can use LinkedList or ArrayList, both work fine.
After all, it's your homework.