what does ":" stands for, in a for function - java

i have this code, and i would like to know what the ":" mean in the function
Element[][] grid = readFile();
for (Element[] ea : grid) {
for (Element e : ea)
System.out.print(e.getChar());
System.out.println();

In terms of a language equivalent, you can think of it as the word "in". You can read it as "for each Element 'e' in 'ea'".
Here's the documentation on that type of loop: http://docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html

When : is used in for, it acts as a for-each loop. Each iteration, the variable after the colon is assigned to the next value in the array.
int[] arr = {1,2,3,4};
for ( arr : num ) {
System.out.print( num + " " );
}
// prints "1 2 3 4 "

It's a for-each comprehension for Collections and Array. It's same as some languages like Python provide in functionality. So when you see a : in a for loop, read as in. For more details see this http://docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html
In your case it's like for ea in grid.

This type of loop is called a 'for-each' loop. The colon (:) is read as 'in'. Basically, this type of for loop is used with collections.
It could be read as:-
for each element x in collection Y{
//do something
}
Here, in each iteration, the element x refers to the respective elements in Collection Y. i.e, in first iteration, x will be Y[0], in second iteration, x will be y[1], so on and so forth till the end.
The advantage is that condition checking and all those stuff need not be written explicitly. It is especially useful when iteration elements in a collection sequentially till the end. This makes iterating over collections quite easier. It is easier than making use of iterators.
In your code, each element of the two dimensional array 'ea' is printed, using a nested for-each loop. Outer loop iterates over each row (a single dimensional array), and inner loop iterates over each element in the respective row.
Refer these:-
For-each loop
Related question in stackoverflow

This is the new enhanced for loop.
You can read it out loud as for each Element ea in grid. It iterates over the elements in grid.
Here is a nice tutorial .

It's simply a divider between the temporary variable and the Iterable or array.
It's called a foreach loop, and basically means:
"For each element ae in Iterable grid, do {...}"
Read more here: The For-Each Loop
Iterable being an array or a list, for example.

Related

Use substring for every element of Hashtable JSP

I'm working on my first project in JSP. I have a istance of Hashtable (hParamsRecherche) that get some values from a form.
I have to substring every element of this Hashtable :
hParamsRecherche.get("INVERSE_GEO").toString()
That contains values like:
'95','14','300','165'
I have to substring all the element that have a length bigger than 2 char, et take the first two number.
'95','14','30','16'
I think that i have to do this with a loop, but i m open to others suggestions ! Thank you !
If you want to process all strings in way that they are at most 2 digits long, you can use the following approach.
It uses streams instead of a loop, which is more elegant solution, because it uses less lines of code to solve the same problem as a loop, without sacrificing code readability.
// ... contains a list like '95','764', etc ..
// getListOfStrings() is the method, which wraps hParamsRecherche.get
var stringsToCut = getListOfString()
// The result variable now contains the list of strings, which are at most 2 digits long
var result = stringsToCut.stream
.map(s -> s.length() <= 2 ? s :s.substring(0,2))
.collect(Collectors.toList())

how to remove object from stream in foreach method?

i have to arrays: arrA and arrB. arrA and arrB are Lists of objectss of diffrent types and add function converts objects A to objects B. I want to add each object from arrA to arrB and remove that object from arrA. Im trying to do this by stream:
arrA.stream().foreach(c -> {arrB.add(c); arrA.remove(c);});
when i execute this, two things are happening:
not all objects are passed from arrA to arrB.
after few iterations null pointer exception is thrown.
i gues it's because length of array is decreased after each remove() call and the counter of iterations is increased (only objects under odd indexes are passed to arrB)
Now i could solve this by copying array in one stream call and then remove objects in second stream call but this doesnt seem correct for me.
What would be proper solution to this problem?
EDIT.
Additional information:
in real implementation this list if previously filtered
arrA.stream().filter(some condition).foreach(c -> {arrB.add(c); arrA.remove(c);});
and its called few times to add elements meeting diffrent conditions to diffrent lists (arrC, arrD etc.) but each object can be only on one list
Streams are designed to be used in a more functional way, preferably treating your collections as immutable.
The non-streams way would be:
arrB.addAll(arrA);
arrA.clear();
However you might be using Streams so you can filter the input so it's more like:
arrB.addAll(arrA.stream().filter(x -> whatever).toList())
then remove from arrA (thanks to #Holgar for the comment).
arrA.removeIf(x -> whatever)
If your predicate is expensive, then you could partition:
Map<Boolean, XXX> lists = arrA.stream()
.collect(Collectors.partitioningBy(x -> whatever));
arrA = lists.get(false);
arrB = lists.get(true);
or make a list of the changes:
List<XXX> toMove = arrA.stream().filter(x->whatever).toList();
arrA.removeAll(toMove);
arrB.addAll(toMove);
As the others have mentioned, this is not possible with foreach - as it is impossible with the for (A a: arrA) loop to remove elements.
In my opinion, the cleanest solution is to use a plain for while with iterators - iterators allow you to remove elements while iterating (as long as the collection supports that).
Iterator<A> it = arrA.iterator()
while (it.hasNext()) {
A a = it.next();
if (!check(a))
continue;
arrB.add(a);
it.remove();
}
This also saves you from copying/cloning arrA.
I don't think you can remove from arrA while you iterate over it.
You can get around this by wrapping it in a new ArrayList<>();
new ArrayList<>(arrA).stream().foreach(c -> {arrB.add(c); arrA.remove(c);});
i guess it's because length of array is decreased after each remove() call and the counter of iterations is increased
Right. the for-each-loop is just like a normal for-loop, but easier to write and read. You can think of it as syntactic sugar. Internally it will either use an Iterator or array indices. The forEach method of streams is a more fancy version of it that allows parallel execution and functional coding style, but has its own drawbacks.
As with any indexed loop, removing an element while looping breaks the loop. Consider having three elements with indices 0, 1, and 2. When you remove element 0 in the first iteration, the list items will shift one up and the next iteration you'll have elements 0 (previously 1) and 1 (previously 2). Your loop variable now points to 1, so it skips the actually next item. When it gets to index 2 the loop you're working on only has one item left (you removed two), which throws an error because the index is out of bounds.
Possible solutions:
Use the List methods for cloning and clearing lists.
Do it with two loops if you really need to call the methods on each single item.
You could just do Collections.addAll. Then when that's finished. just call clear() on arrA.

For loop java query

I have a question about for loops in java. I understand how for loops work an using the format :
for(initialize variable : condition : counter){}
My problem is in one of my lectures it says:
for(String s : str){.....}
How come this doesn't need a counter?
What is str?
This is an enhanced for loop, or a "for each" loop. It iterates over all the elements of str, which is probably a Collection of Strings in your example, or an Array of Strings.
Read this for more details.
For example, instead of writing this:
for (int i = 0; i < myArray.length; i++) {
System.out.println(myArray[i]);
}
you can write its equivalent:
for (int myValue : myArray) {
System.out.println(myValue);
}
First of all replace : with ; in the first for loop like this(you have used wrong syntax)
for(initialize variable ; condition ; counter){}
and the second one is the enhanced for loop,
for(String s : str){.....}
quite handy in case of the collections,It does not require any counter because it runs till it reaches the last element in the collection provided to it(In this case str is that collection)
See this to learn more about it What is the syntax of enhanced for loop in Java?
It is an enhanced for loop that iterates through every element in the Collection. It doesn't stop until it is has hit the last element or encounters a break;.
Your definitive source for this sort of questions is the Java Language Specification. In this particular case:
http://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.14
A more friendly source may be found in the official Java Tutorials, in this case:
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html

How enhanced is enhanced-for loop?

I am iterating on the elements of a list of String objects
one after the other:
LinkedList list;
// add values to the list here
for (int i = 0; i < list.size(); i++)
System.out.println(list.get(i));
Here, each and every time i invoke get() on list, the list is iterated from one of its ends all the way to the i-th element-- so the complexity of the above loop is O(n^2).
Is is a.) the same as above for enhanced-for loop, or b.) is for-loop maintaining the pointer where it's last have been and thus the complexity of the below loop is O(n)?
for (String s:list)
System.out.println(s);
If case (b) above -- which i think it is -- is there any advantage of using an iterator on the list. this is plain iteration-- there's no going back&forth. EDIT: ..and my list operation is read-only.
TIA.
The "enhanced for loop" as you call it (it's actually called the foreach loop) internally uses an iterator for any iterable - including linked lists.
In other words it is O(n)
It does handle looping over arrays by using an integer and iterating over it that way but that's fine as it performs well in an array.
The only advantages of using an iterator manually are if you need to remove some or all of the elements as you iterate.
A foreach loop like this:
for (String s:list)
System.out.println(s);
Would be desugared to something like
for(Iterator<String> iter = list.iterator(); iter.hasNext();) {
String s = iter.next();
System.out.println(s);
}
i.e. it is equivalent to using an Iterator. And much better than using a standard for loop.
Enhanced loop uses an Iterator behind the scenes [1] if it is about lists.
In your case you have a linked list (which keeps pointers to next-previous items), so by using an enhanced for (iterator) you have sequential read complexity O(1).
If you use the for you suggested, you're accessing your list randomly, which is O(n) for the LinkedList but it would be O(1) if it was an ArrayList.
So it can be enhanced if used in a List with sequential read complexity < random read complexity
[1] why is enhanced for loop efficient than normal for loop
Enhanced for loop is useful in certain situations like when there is a need to search a key in an array,where it obtains one element at a time in sequence. It eliminates the need to establish loop counter,specify starting and ending value.So based on the requirement simple for loop or enhanced for loop can be used.

How to fill two-dimensional array using java enhanced loop?

Basically, I am trying this, but this only leaves array filled with zeros. I know how to fill it with normal for loop such as
for (int i = 0; i < array.length; i++)
but why is my variant is not working? Any help would be appreciated.
char[][] array = new char[x][y];
for (char[] row : array)
for (char element : row)
element = '~';
Thirler has explained why this doesn't work. However, you can use Arrays.fill to help you initialize the arrays:
char[][] array = new char[10][10];
for (char[] row : array)
Arrays.fill(row, '~');
From the Sun Java Docs:
So when should you use the for-each loop?
Any time you can. It really beautifies your code. Unfortunately, you cannot use it everywhere. Consider, for example, the expurgate method. The program needs access to the iterator in order to remove the current element. The for-each loop hides the iterator, so you cannot call remove. Therefore, the for-each loop is not usable for filtering. Similarly it is not usable for loops where you need to replace elements in a list or array as you traverse it.
This is because the element char is not a pointer to the memory location inside the array, it is a copy of the character, so changing it will only change the copy. So you can only use this form when referring to arrays and objects (not simple types).
The assignment merely alters the local variable element.

Categories