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())
Related
I have an integer array of size 4. I am adding elements to it via the add method. This is as an unsorted array. I am sorting it via the sort method shown in the code below. The sort method places the smallest number in the position a[0]. When I try to add elements after I call the sort method I always get a return value of 0. Is there a way around this?
import java.util.Arrays;
public class Scrap {
private static int[] array = new int[4];
private static int i = 0;
public static void main(String[] args) {
Scrap pq = new Scrap();
pq.add(4);
pq.insert(3);
pq.add(5);
pq.sort();// smallest to largest sort method.
// System.out.println(array[0]);
pq.insert(1);
pq.sort();
int test = pq.Minimum();
System.out.println("The smallest element of the array is " + test);
pq.sort();
}
//
public void add(int input) {
insert(input);
}
// Method to insert number into the array.
public void insert(int input) {
array[i] = input;
i++;
}
// Finding smallest number of the array.
public int Minimum() {
int a = array[0];
return a;
}
// Sorts the array from smallest to largest integer
public void sort() {
int first, temp;
for (int i = array.length - 1; i > 0; i--) {
first = 0;
for (int j = 1; j <= 1; j++) {
if (array[j] > array[first])
first = j;
}
temp = array[first];
array[first] = array[i];
array[i] = temp;
}
}
public int remove() {
return delete();
}
public int delete() {
return remove();
}
// Method to convert the array into a string for output
}
The problem in a nutshell:
You start with an array of length 4.
At this point the array contains 4 zeros, that is: [0, 0, 0, 0]
You add 4, 3, and 5. These operations update the content of the array to [4, 3, 5, 0].
You sort the array. This should change the content of the array to [0, 3, 4, 5]. In fact it changes to [0, 5, 3, 4], which means your implementation of sort is clearly broken.
You probably didn't expect the 0 value to move. You can fix this by sorting only the first 3 values. (And, of course, you should also fix your implementation of sort.)
Then when you insert 1, the program updates the value at index 3, so the content changes to [0, 5, 3, 1].
If you implement the fix I suggested above, and sort only the first size elements, then the content after the first call to sort should become [3, 4, 5, 0], and the content after the insert 1 should become [3, 4, 5, 1]. And when you sort that again, the content should become [1, 3, 4, 5] and the smallest value will be 1 as expected, instead of 0.
More concretely:
First of all, change private static int i = 0; to private int size = 0;. The name i is extremely inappropriate here, and will surely confuse you. size is appropriate. It also doesn't make sense to make it static, so I suggest to drop that keyword.
Fix the implementation of sort. There are many basic sorting algorithms that are easy to implement. In the implementation, instead of going until array.size, go until size. Do you see the difference? size is the field in Scrap, essentially it's the number of elements you added using the add or insert methods.
Some cleaning up would be good too:
Delete the add method and rename insert to add.
Delete the remove and delete methods. They are not used, and you will get a stack overflow if you try to use them as they are now (the methods call each other, forever)
Look at the content of the array after each step in the program.
After Scrap pq is created, this is the content of its array:
[0, 0, 0, 0]
Then a couple of modifications:
pq.add(4);
pq.insert(3);
pq.add(5);
The content at this point:
[4, 3, 5, 0]
So far so good.
Then you sort it:
pq.sort();
The content at this point:
[0, 5, 3, 4]
Ouch. The sort implementation doesn't work very well, does it. But let's ignore that for now. Next step:
pq.insert(1);
The content at this point:
[0, 5, 3, 1]
None of this behavior makes sense, probably this is not how you intended the program to work. Review the program, verify the content after each step. Do not proceed to the next step until the current step is working correctly.
I am assuming that you will be using a correct sort method (because, this is not correct, you can use Arrays.sort). But still with a correct sort, there is a logical problem in your code.
At the beginning, the array contains all 0s. After adding the first 3 int, when you call the sort method, the array contains the values in following order:
0,3,4,5
Note that, the value of i is not changed. At this state the value of i is 3. So when you insert 1, the new values become
0,3,4,1
So after sorting again, the values of arrays become
0,1,3,4
So obviously the minimum will retrun 0
I don't think that is the most effective way to sort an array. It is possible to do this with just 1 for loop. Try this to sort your array from smallest to largest.
int temp;
for(int i=0;i<array.length-1;i++){
if(array[i]>array[i+1]){
temp=array[i];
array[i]=array[i+1];
array[i+1]=temp;
i=-1;
}
}
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 am trying to compute pascal's triangle given a row number. I am using recursion.
My code is below:
public static List<Integer> getRow(int rowIndex) {
if (rowIndex == 1){
List <Integer> list = new ArrayList(rowIndex+1);
list.add(1);
return list;
}
else{
List<Integer> oldList = getRow(rowIndex -1);
List <Integer> list = new ArrayList(rowIndex+1);
int temp = 0;
list.add(0,1);
list.add(list.size()-1,1);
System.out.println("rowIndex "+rowIndex);
for (int i = 1; i < list.size()-1; i ++){
temp = oldList.get(i) + oldList.get(i-1);
list.add(i,temp);
}
return list;
}
}
It always returns [1,1] regardless of what row I am trying to get. I tried inserting print statements. I noticed the size of list is always 2 regardless of what rowIndex is.
List <Integer> list = new ArrayList(rowIndex+1);
Is the line above not the correct way to create an ArrayList? Seems like my arraylist always has size = 2;
you misunderstand how ArrayLists do work and you really should read the Javadoc.
In short, the constructor's parameter defines the initial size of the ArrayList in memory, not the max size. If you instantiate a new ArrayList<Integer>(2)it only means that the jvm allocates upfront enough space for two Integers, and that when you add a third element then the jvm will grow the size of the ArrayList in order to allow you to add more elements.
Further, you can access an ArrayList position with get() only if an element has been added at this position.
Finally, keep in mind that add at a specific position shifts right all elements. Thus if you add(10,1) then add(2,4), your first add will be shifted right.
Back to your question, if you absolutely want to use an ArrayList and not an array, you have to initialize your ArrayList with the right size, then set values at the right positions.
Here is a working solution :
// the method with your algorithm which has been slightly modified
public static List<Integer> getRow(final int rowIndex) {
// notice that I call a helper method which initialises correctly the ArrayList
final List<Integer> list = init(rowIndex);
if (rowIndex == 1) {
// notice that I set the value at a given position
// I can only do it because I initialised all values to 0 first
list.set(0, 1);
} else {
final List<Integer> previousRowList = getRow(rowIndex - 1);
// again, I set values...
list.set(0, 1);
list.set(rowIndex - 1, 1);
for (int i = 1; i < (list.size() - 1); i++) {
// set again...
list.set(i, previousRowList.get(i - 1) + previousRowList.get(i));
}
}
// lets print out the row
System.err.println(list);
// then return it
return list;
}
public static List<Integer> init(final int size) {
// passing the size is overkill, but well...
final List<Integer> list = new ArrayList<Integer>(size);
// fill the ArrayList with zeros
for (int i = 0; i < size; i++) {
list.add(i, 0);
}
// then return it
return list;
}
public static void main(final String[] args) {
getRow(Integer.parseInt(args[0]));
}
If you run it you'll get a (not so nice, but working) Pascal's triangle. Here follows the result if you want 11 rows :
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
[1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1]
Hope it helps !
I think you're miss-interpreting the data structures.
And array list is a LIST implemented on top of an array. Setting the size of the array in the constructor is a way to give control to the developer for the initial size of the array (This is rarely necessary as the class manages the array size itself--so just leave out this argument). So the size of an array list is actually the size of the list, which is the number of elements, not the number of buckets in the underlying array which is specified in the constructor.
If you know the size of the array you want, and you want to get and add at specific locations, use a standard array, not an array list.
However, I think your code will work if you move
list.add(list.size()-1,1);
to after your for-loop (I'm actually surprised it doesn't throw an index out of bounds exception). And since you're going left to right, none of your adds need an index specified, since it'll just add it to the end of the existing list.
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
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);