Which of these loops are more efficient? - java

I have these three collections in Java:
ArrayList<Integer> list1 = new ArrayList<Integer>(6000);
ArrayList<Integer> list2 = new ArrayList<Integer>(6000);
ArrayList<Integer> list3 = new ArrayList<Integer>(6000);
Which is more efficient to loop through and set to 0?
for(int i =0; i < rHist.size(); i++) {
list1.set[i] = 0;
list2.set[i] = 0;
list3.set[i] = 0;
}
Or this?
for (int n : list1) {
n = 0;
}
for (int n : list2) {
n = 0;
}
for (int n : list3) {
n = 0;
}
Thanks

As already mentioned in the comments, both of the variants do not reach the goal you stated. That being said, better look to write readable, understandable and short code and refrain to the methods given in the Collections API. Something like that fills your list with 6000 copies of zeros:
List<Integer> list = Collections.nCopies(6000, 0);
If you need to mutate the list afterwards, you need to wrap it in a modifiable List like so:
List<Integer> list = new ArrayList<Integer>(Collections.nCopies(6000, 0));

The first one is better because you are looping one time instead of three if you put the size to 6000 in the loop, and the set should look like this list1.set(i,0) instead of list1[i]=0
if you decompiled both them uisng javap -c "appname" lets assume that they are under the main, you can see your self whats happening

Related

How do I loop thorough a 2D ArrayList in Java and fill it?

I am trying to use 2D arrayLists in Java.
I have the definition:
ArrayList<ArrayList<Integer>> myList = new ArrayList<ArrayList<Integer>>();
How can I loop through it and enter in numbers starting from 1?
I know that I can access a specific index by using:
myList.get(i).get(j)
Which will get the value. But how do I add to the Matrix?
Thanks
You can use a nested for loop. The i-loop loops through the outer ArrayList and the j-loop loops through each individual ArrayList contained by myList
for (int i = 0; i < myList.size(); i++)
{
for (int j = 0; j < myList.get(i).size(); j++)
{
// do stuff
}
}
Edit: you then fill it by replacing // do stuff with
myList.get(i).add(new Integer(YOUR_VALUE)); // append YOUR_VALUE to end of list
A Note: If the myList is initially unfilled, looping using .size() will not work as you cannot use .get(SOME_INDEX) on an ArrayList containing no indices. You will need to loop from 0 to the number of values you wish to add, create a new list within the first loop, use .add(YOUR_VALUE) to append a new value on each iteration to this new list and then add this new list to myList. See Ken's answer for a perfect example.
Use for-each loop, if you are using Java prior 1.5 version.
for(ArrayList<Integer> row : myList) {
for(Integer intValue : row) {
// access "row" for inside arraylist or "intValue" for integer value.
}
}
Assuming the matrix is not initialized,
int m = 10, n = 10;
ArrayList<ArrayList<Integer>> matrix = new ArrayList<ArrayList<Integer>>();
for (int i = 0; i < m; i++) {
List<Integer> row = new ArrayList<Integer>();
for (int j = 0; j < n; j++) {
row.add(j);
}
matrix.add(row);
}

Fastest way to get the first n elements of a List into an Array

What is the fastest way to get the first n elements of a list stored in an array?
Considering this as the scenario:
int n = 10;
ArrayList<String> in = new ArrayList<>();
for(int i = 0; i < (n+10); i++)
in.add("foobar");
Option 1:
String[] out = new String[n];
for(int i = 0; i< n; i++)
out[i]=in.get(i);
Option 2:
String[] out = (String[]) (in.subList(0, n)).toArray();
Option 3:
Is there a faster way? Maybe with Java8-streams?
Assumption:
list - List<String>
Using Java 8 Streams,
to get first N elements from a list into a list,
List<String> firstNElementsList = list.stream().limit(n).collect(Collectors.toList());
to get first N elements from a list into an Array,
String[] firstNElementsArray = list.stream().limit(n).collect(Collectors.toList()).toArray(new String[n]);
Option 1 Faster Than Option 2
Because Option 2 creates a new List reference, and then creates an n element array from the List (option 1 perfectly sizes the output array). However, first you need to fix the off by one bug. Use < (not <=). Like,
String[] out = new String[n];
for(int i = 0; i < n; i++) {
out[i] = in.get(i);
}
It mostly depends on how big n is.
If n==0, nothing beats option#1 :)
If n is very large, toArray(new String[n]) is faster.
Option 3
Iterators are faster than using the get operation, since the get operation has to start from the beginning if it has to do some traversal. It probably wouldn't make a difference in an ArrayList, but other data structures could see a noticeable speed difference. This is also compatible with things that aren't lists, like sets.
String[] out = new String[n];
Iterator<String> iterator = in.iterator();
for (int i = 0; i < n && iterator.hasNext(); i++)
out[i] = iterator.next();
Use .take(n) operator on your list
Use:
Arrays.copyOf(yourArray,n);

IndexOutOfBoundsException when working with arrayList

The task is described here Creating combination of numbers or here Permutations of integer array algorithm.
I decided to solve this problem in this way:
From first number to the last check the possibility of permutation:
Create arraLists of the first permutation and of the difference
del1 and rem0
Bool is an object with two parametrs: st - start and end
It`s new permutation
I create new Bool, that at the start have the same start and end, like it is one number. So, we cant use this number anymore before starting new permutation with another start number. And we remove it from the list of numbers rem . And start create permutation with checking.
for (int index = 0; index < arr.length; index++) {
List<Integer> del1 = new ArrayList<Integer>();
List<Integer> rem0 = new ArrayList<Integer>();
for (int i = 0; i < del.length; i++) {
del1.add(del[i]);
}
for (int i = 0; i < arr.length; i++) {
rem0.add(arr[i]);
}
Bool start = new Bool(arr[index], arr[index]);
rem0.remove(index);
check(start, del1, rem0);
}
Checking:
ucet - number of "good" permutations, if the difference of new permutation is the same, as the first, it is "good".
So, I for the ending number I add difference number and if it = number in the list of possible numbers - I add this number to the end of permutation, remove it from the list of possible and remove difference prom the list of differences(by creating new lists).
And then continue creating.
private static void check(Bool start, List<Integer> del2, List<Integer> rem) {
if (del2.isEmpty()) {
ucet++;
}
for (int index = 0; index<rem.size(); index++) {
for (int i = 0; i<del2.size(); i++) {
if(start.end+del2.get(i)==rem.get(index)){
List<Integer> del3 = new ArrayList<Integer>();
List<Integer> rem2 = new ArrayList<Integer>();
del3=del2;rem2=rem;
Bool con=new Bool(start.st,rem.get(index));
rem2.remove(index);
del3.remove(i);
check(con,del3,rem2);
}
}
}
}
But I have one bug, that I cant understand. Its IndexOutOfBoundsException. In the string if(start.end+del2.get(i)==rem.get(index)){ .
And it causes del2.get(i).
But the problem is, that i<del2.size().
Can you help me to deal with it? Thanks
You are removing entities from the list as you are looping through it, not good. You could try using while loop in conjunction with iterable.hasNext() or instead of rem0.remove(index) do rem0.set(index, null).

Delete those elements from the list that are indexed in another list

List<Double> elements = new ArrayList<Double>();
List<Integer> usedElements = new ArrayList<Integer>();
for (int i=0; i<usedElements.size(); i++)
{
elements.remove(usedElements.get(i));
}
There is a List of indexes called usedElements. I need to delete those elements from the List elements that are mentioned in usedElements. How to do this in a correct way.
If you know your usedElements list is in ascending order, the simplest approach would be to remove the elements in reverse order - that way the "shuffling up" effect won't affect any of the later operations:
List<Double> elements = ...;
List<Integer> usedElements = ...;
for (int i = usedElements.size() - 1; i >= 0; i--) {
elements.remove(usedElements.get(i));
}
If usedElements isn't currently sorted, it would be best to just sort it first. If usedElements isn't currently sorted and you need to maintain its current order for another reason, then create a copy first, and sort that:
List<Double> elements = ...;
List<Integer> usedElements = ...;
List<Integer> sortedUsedElements = new ArrayList<Integer>(usedElements);
Collections.sort(sortedUsedElements);
for (int i = sortedUsedElements.size() - 1; i >= 0; i--) {
elements.remove(sortedUsedElements.get(i));
}
Or even sort the copy in reverse order and use an enhanced for loop:
List<Double> elements = ...;
List<Integer> usedElements = ...;
List<Integer> sortedUsedElements = new ArrayList<Integer>(usedElements);
Collections.sort(sortedUsedElements, Collections.<Integer>reverseOrder());
for (Integer index : sortedUsedElements) {
elements.remove(index);
}
You might find it easier to create a new list instead of trying to modify the original list in place:
Set<Integer> used = new HashSet<>(usedElements); // maybe use a set in the
// first place?
List<Integer> newElements =
new ArrayList<>(elements.size() - used.size());
for (int i = 0; i < elements.size(); i++) {
if (!used.contains(i))
newElements.add(elements.get(i));
}
elements = newElements;
This entire process is O(n).

Clean way to initialize an arraylist

I want an Arraylist in Java, which I want to fill with 10's
ArrayList<Integer> list = new ArrayList<Integer>(100);
for (int i = 0; i < 100; i++) {
list.add(10);
}
I'm going to have to initialize a lot of Arraylists, so I was wondering if there is there a clean way to do this without a for loop?
You can use Collections.nCopies:
ArrayList<Integer> list = new ArrayList<Integer>(Collections.nCopies(100, 10));
This will initialize list with 100 10's.
ArrayList<Integer> list = new ArrayList<Integer>(100);
for (int i = 0; i < list.size(); i++)
{
list.add(10);
}
list.size() will be 0 here, so this is why your code does not work. size keeps track of how many elements are currently in the list, not the capacity.
If you want the ArrayList to be initialized with all 10s, you can use:
ArrayList<Integer> list = new ArrayList<Integer>(Collections.nCopies(100, 10));
Edit: You said later that you didn't want a for loop, but to fix your code, just replace list.size() with 100.

Categories

Resources