Why did the first for loop fail in Java? [duplicate] - java

This question already has answers here:
Why does the foreach statement not change the element value?
(6 answers)
Closed 7 years ago.
I have a int[] a, and trying to set every element in the a to be 1. So when I did following code, and printed every element, it shows they are still 0s.
for(int num:a)
num=1;
But if I try below, every element is 1 now. I'm confused. I always thought the 2 for loop have the same functionality. Can anyone tell me why my first try failed? And why it works when i print them? Thanks~~~
for(int num=0;num<a.length;num++)
a[num]=1;
for(int n:a)
System.out.println(n);

Your first loop declares a local variable which only exists inside that loop. Its value iterates over every value in the array. A new memory location is reserved temporarily and given the name "num". Changing contents of that memory location does not modify the values in the "a" array.
Your second loop explicitly accesses memory allocated for the array "a" and changes their contents.

These loops are different. Both in functionality and operations.
The first one - an enhanced-for loop - is giving you each element in the array referenced by the variable a. It is not exposing anything for you to mutate, so assignments to a have no effect on the actual value in the array.
The second loop is simply going through all of the elements in the array, but you are directly working with the array itself at all times, so mutating the values is perfectly possible.
To put this in other terms:
The enhanced-for is going through the array, and providing you a value to use. That value, while originally provided by the array, has no connection to the array otherwise. Any modifications made to the value would not propagate to the array.
The alternative loop is only ever accessing the array contents directly, where it is perfectly possible to make modifications and reassignments to the array.
Thus, if you ever want to set the values of an array to anything other than their default value, then using the second approach is the way to go.
Or...you could use Java 8's Stream API and come up with something like this:
IntStream.iterate(1, (x) -> 1).limit(100).toArray()

Related

What is the time complexity of the add and element in a Java Array?

Hello I am research about that, but I cannot found anything in the oracle website.
The question is the next.
If you are using an static Array like this
int[] foo = new int[10];
And you want add some value to the 4 position of this ways
foor[4] = 4;
That don't shift the elements of the array so the time complexity will be O(1) because if you array start at 0x000001, and have 10 spaces, and you want put some in the x position you can access by (x*sizeOf(int))+initialMemoryPosition (this is a pseudocode)
Is this right, is this the way of that this type of array works in java, and if its time complexity O(1)
Thanks
The question is based on a misconception: in Java, you can't add elements to an array.
An array gets allocated once, initially, with a predefined number of entries. It is not possible to change that number later on.
In other words:
int a[] = new int[5];
a[4] = 5;
doesn't add anything. It just sets a value in memory.
So, if at all, we could say that we have somehow "O(1)" for accessing an address in memory, as nothing related to arrays depends on the number of entries.
Note: if you ask about ArrayList, things are different, as here adding to the end of the array can cause the creation of a new, larger (underlying) array, and moving of data.
An array is somewhere in memory. You don’t have control where, and you should not care where it is. The array is initialized when using the new type[size] syntax is used.
Accessing the array is done using the [] index operator. It will never modify size or order. Just the indexed location if you assign to it.
See also https://www.w3schools.com/java/java_arrays.asp
The time complexity is already correctly commented on. But that is the concern after getting the syntax right.
An old post regarding time complexity of collections can be found here.
Yes, it takes O(1) time. When you initialize an array, lets say, int[] foo = new int[10],
then it will create a new array with 0s. Since int has 4 bytes, which is 32 bits, every time assign a value to one element, i.e., foo[4] = 5, it will do foo[32 x input(which is 4)] = value(5); That's why array is 0-indexed, and how they assign values in O(1) time.

Java ForEach in ArrayList with Locate [duplicate]

This question already has answers here:
Java, How do I get current index/key in "for each" loop [duplicate]
(6 answers)
Closed 8 years ago.
Overview:
I'm using for-each loops and I'm curious if I need to replace them with regular for loops, or if there is a way to do a locate in an ArrayList which will give me the equivalent of keeping track of the index which is used in normal for loops.
Simplified Version of the Problem:
I'm using for-each with an ArrayList of objects. These objects are used to calculate different values at different times, so I need to iterate through the items and do the calculates a couple different times. I wish to track these results in a structure, which I can easily do, if I can locate items in an ArrayList (without having to iterate through everything in a separate loop). If there is, then I can use that to build what I need. If not, I'll replace the for-each with for loops and get the functionality I need.
You can use a regular for-loop but sometimes it just isn't a good idea, for example if you're dealing with linked lists where element retrieval is O(n) in the index. Why not just keep track of index?
int index = 0;
for (Element e : list) {
...
index++;
}
I find this cleaner than a plain for-loop, and it will remain efficient even if you change from ArrayList to another type of list which is not random-access.
The for-each loop is meant to be an easy way to operate on every element in a collection or array. If you want to iterate and keep track of indicies, you'll want a normal for loop.
However, some Collections (Lists for example) have an indexOf() method which you can use to get the index. That would kill your performance though.
You can also use a counter:
int i = 0;
for (Object o : list) {
// Code
i++;
}

Efficient Way to Find Index of Object in ArrayList

I have an ArrayList which I fill with objects of type Integer in a serial fashion (i.e. one-by-one) from the end of the ArrayList (i.e. using the method add(object)). Every time I do this, the other objects in the ArrayList are of course left-shifted by one index.
In my code I want to find the index of a random object in the ArrayList. I want to avoid using the indexOf method because I have a very big ArrayList and the looping will take an enormous amount of time. Are there any workarounds? Some idea how to keep in some data structure maybe the indexes of the objects that are in the ArrayList?
EDIT: Apparently my question was not clear or I had a missunderstanding of the arraylist.add(object) method (which is also very possible!). What I want to do is to have something like a sliding-window with objects being inserted at one end of the arraylist and dropped from the other, and as an object is inserted to one end the others are shifted by one index. I could use arraylist.add(0, object) for inserting the objects from the left of the arraylist and right-shifting each time the previous objects by one index, but making a google search I found that this is very processing-intensive operation - O(N) if I remember right. Thus, I thought "ok, let's insert the objects from the right-end of the arraylist, no problem!", assuming that still each insertion will move the previous objects by one index (to the left this time).
Also when I use the term "index" I simply mean the position of the object in the ArrayList - maybe there is some more formall term "index" which means something different.
You have a couple of options. Here are the two basic options:
You can maintain a Map<Object,Integer> that holds indexes, in parallel to the array. When you append an element to the array you can just add it to the map. When you remove an element from the beginning you will have to iterate through the entire map and subtract one from every index.
If it's appropriate for your situation and the Map does not meet your performance requirements, you could add an index field to your objects and store the index directly when you add it to the array. When you remove an element from the beginning you will have to iterate through all objects in the list and subtract one from their index. Then you can obtain the index in constant time given an object.
These still have the performance hit of updating the indexes after a remove. Now, after you choose one of these options, you can avoid having to iterate through the map / list to update after removal if you make a simple improvement:
Instead of storing the index of each object, store a count of the total number of objects added so far. Then to get the actual index, simply subtract the count value of the first object from the value of the one you are looking for. E.g. when you add:
add a to end;
a.counter = counter++;
remove first object;
(The initial value of counter when starting the program doesn't really matter.) Then to find an object "x":
index = x.counter - first object.counter;
Whether you store counter as a new field or in a map is up to you. Hope that helps.
By the way; a linked list will have better performance when removing object from the front of the list, but worse when accessing an object by index. It may be more appropriate depending on your balance of add/remove vs. random access (if you only care about the index but never actually need to retrieve an object by index, random access performance doesn't matter). If you really need to optimize further you could consider using a fixed-capacity ring buffer instead (back inserts, front removes, and random access will all be O(1)).
Of course, option 3 is to reconsider your algorithm at a higher level; perhaps there is a way to accomplish the behavior you are seeking that does not require finding the objects in the list.

IndexOutOfBoundsException with Android ArrayList [duplicate]

This question already has answers here:
Java - IndexOutOfBoundsException: Index: 1, Size: 0
(1 answer)
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed last year.
I've got a very annoying problem with some code throwing an IndexOutOfBoundsException and I really cannot understand why. The logcat points to the "addTimetableItem" of the following code which ill explain more on:
if(sortedFridayTimes.size()>0){
insertDay("Friday");
for(int i=1; i<sortedFridayTimes.size()+1;i++){
addTimetableItem(sortedFridayTimes.get(i));
}
}
"sortedFridayTimes" is an ArrayList containing my own "Timetable Entry" objects which I have sorted into order already. First the size is checked to see if there are any objects and if there is then "insertDay" runs which creates a new textview for a title and adds it to the layout (This works fine..).
Inside the for loop the idea is to then add all the objects from the arraylist into the layout. Now I know that the "addTimetableItem" code works as ive tested it already, but my problem is that i cant seem to get the last object out of the arraylist. If I declare the for loop to only run for
"i<sortedFridayTimes.size()"
then the program runs fine but I don't get the last entry in the arraylist which I know exists because I've debugged and watched my variables. On adding the "+1" as shown above I now get the IndexOutOfBoundsException and I really don't know why. As I've said, I've debugged and I know that an entry exists in the arraylist where I'm trying to point to, but it just crashes. I can provide more code if needs be, but does anyone have any ideas please?
You should accept #Tim's or #Graham's answer, this is just an addendum. They're correct about your size()+1 going past the end of the array.
If you're having difficulty using indexes to properly get everything out of the list, you can also try using a for-each loop (depending on the version of the Android SDK you're using). I'm assuming sortedFridayTimes is a list of class TimetableItem since you don't specify.
So this:
if(sortedFridayTimes.size()>0){
insertDay("Friday");
for(int i=1; i<sortedFridayTimes.size()+1;i++){
addTimetableItem(sortedFridayTimes.get(i));
}
}
Becomes this:
if(!sortedFridayTimes.isEmtpy()){
insertDay("Friday");
for(TimetimeItem item : sortedFridayTimes){
addTimetableItem(item);
}
}
A little cleaner if you don't actually need to use i anywhere.
i<sortedFridayTimes.size()+1
You are looping past the last element in the array. Why the +1?
If there are N elements in the array, then the elements are from indexes 0 through to N-1.
So it should be:
for(int i=0; i<sortedFridayTimes.size(); i++) {
The last loop in your for loop runs:
sortedFridayTimes.get(sortedFridayTimes.size())
This will always be out of bounds, because the elements are zero indexed.
For example, if the array size is "5", then you cannot access index "5", because the 5 elements in the array are 0,1,2,3,4.

Java for( x : y) execution

I have the following for loop:
for(String s : someString.split("\\s+")){
//do something
}
Does java execute the split() method each time the loop iterates, or does it do it only once and keep a temp array to iterate on?
It only does it once, and uses that array and interates through it.
Edit: from Mat This is the reference
It stores the array in a temporary variable before using it.
No the split is executed once on the string and after that the loop iterate over the result
The split method is only called once. Think of the structure (also known as a for-each) as follows:
The second argument is evaluated and kept for the duration of the loop.
If the argument gives an Iterable or is an array (special case), a check is then made to see if the type of the first argument corresponds with the elements that are returned.
The process enters the loop and executes the code inside the scope and exits when there are no more elements left.
More information can be had here:
http://www.leepoint.net/notes-java/flow/loops/foreach.html
P.S: This works with Java 5 minimum.

Categories

Resources