how arrayDeque.peek() Method in java working with while loop - java

import java.util.ArrayDeque;
class Main {
public static void main(String[] args) {
ArrayDeque<Integer> arrayDeque = new ArrayDeque<>();
arrayDeque.push(10);
arrayDeque.push(11);
arrayDeque.push(15);
arrayDeque.push(20);
arrayDeque.push(200);
arrayDeque.add(700);
while (arrayDeque.peek() != null) {
System.out.println(arrayDeque.pop() + " ");
}
}
}
Good Day .. I have a question regarding the peek() method in ArrayDeque Class .. all the method will do is retrieve the head of the arrayDeque without removing it. so if that is the case how it's working perfectly without going for an infinite loop .. I mean who told the Method to look for the Next element after each complete loop.

There is no infinite loop because the condition in the whole loop will be false when the queue is empty.
while (arrayDeque.peek() != null)
When pop removes the last element, arrayDeque.peek() will return null and that's the end.

That is probably why I prefer to check for isEmpty().
This makes it easier to grasp that you need to pop elements off the queue or it will never go emtpy.
while (!arrayDeque.isEmpty()) { arrayDeque.pop(); }

Related

Usage of Iteration's .hasNext(); and .next(); methods in Java

For 2 days I'm pretty confused about .hasNext(); and next(); methods of Iteration interface especially in while loop. Let me give an example:
import java.util.*; // imported whole java.util package.
class Main {
public static void main(String[] args) {
ArrayList<String> cars = new ArrayList<String>(); // created ArrayList which name is cars.
cars.add("Volvo");
cars.add("Mercedes");
cars.add("BMW");
Iterator<String> x = cars.iterator();
while(x.hasNext()) {
System.out.print(x.next() + " "); // It prints Volvo Mercedes BMW
}
}
}
I understood that .hasNext(); is boolean and it returns true if iteration has elements. The .next(); method returns the next element. After first element Volvo, it gets back while(x.hasNext()) and entering the inside of loop again but where is the counter of this loop? I mean after printing Volvo how can it goes to the next element? It returns all element and if there is no more .hasNext(); returns false and code continues to next line is simple answer and correct but I want to understand it clearly.
Actually the iterator() Method Creates an iterator for all elements in your (let's say) Arraylist. Now in Your Code, the condition of while loop x.hasNext() checks whether the list contains an element or not, if yes it will return true else false.
Now x.next() point to First Element (Like of LinkedLists for example) in Your ArrayList and store that Object(Volvo in your case). When You Call this method it basically gives you reference of that object in List and the Iterator Moves to next element in the List. When Calling next() method the iterator(x in your case) returns the object and then moves to next Element (Mercedes in your case).
Now When you call next() method Again you will find Mercedes is returned. To know How it Works type System.out.println(x.next()) thrice instead of while loop u will understand that it moves to next location. If you type System.out.println(x.next()) fourth time it will give exception because there is no element in your list furthur more. Exception in thread "main" java.util.NoSuchElementException This is the Exception.
That's why hasNext() method is used as it checks whether an element is there or not.
you can Compare this to printing of linkedlist(Data structure if you know) where we make one object point to head node print it and move to next node. Same Case is here it returns current element(object) and moves to next element(object).
while is java-ese for: Keep doing this until a thing changes.
It's a bit like this common household task:
How to wash dishes
Check if there are still dirty dishes on the right side of the counter.
If there are some, do the dishwash thing: Pick up the nearest dirty dish, and wash it, then stow it away on the left side of the counter, and go back to the start of this algorithm.
Otherwise (there are no dirty dishes), you are done.
while (counterRightSide.hasItems()) {
Dish dirty = counterRightSide.fetch();
Dish clean = sink.clean(dirty);
counterLeftSide.stow(clean);
}
EDIT: I realize now that 'a kitchen counter' is an unfortunate example, given the homonym 'kitchen counter' and 'counter in code'. I'll use 'accumulator' instead of 'counter in code' to fix this confusion.
Note how there is no accumulator here either, and you aren't counting in your head when you wash the dishes either. You COULD first take inventory of the amount of dirty dishes you have (say, 15 dishes), and then write a protocol where you grab a dirty dish exactly 15 times before decreeing that you've done the job, but surely you realize that that's just one way to do it, and another is to just... check if there are any dirty dishes left every time you're done washing 1 dirty dish. Which is how the above code works.
Note that the action of 'fetching' an item from the right side of the kitchen counter changes properties of that kitchen counter. It now has one less item on it.
The same applies to iterators: Calling .next() on an iterator changes it in some form. After all, if you call next twice, the results of these calls are different. Contrast with invoking, say, someArrayList.get(5) a bunch of times in a row; that doesn't change the arraylist at all, and therefore you get the same thing back every time. next() is not like that.
So how DOES that work? Who counts this stuff?
Well, that's the neat thing about abstraction! A 'Collection' is something that can do a few things, such as 'it must be able to report to how how many items it holds', and, 'it must be able to festoon you an object that can be used to loop through each item that it holds'.
That's what an iterator is: An object that can do that.
So how does it work? Who knows! It doesn't matter! As long as you CAN do these things, you can be a collection, you are free to implement the task however you like.
Okay, but how does a common collection, like, say, ArrayList do this?
With a counter, of course. Here's the implementation:
public Iterator<T> iterator() {
return new Iterator<T>() {
int counter = 0; // here it is!
public boolean hasNext() {
return counter < size();
}
public int next() {
return get(counter++);
}
};
}
you're getting this object and referencing it in your code (your x variable), and that object has a field with a counter in it. You can't see it; it's private, and not actually in the Iterator type (Iterator is an interface; what you get is some unknown subtype of it, and that contains the counter variable). That's assuming you're getting an iterator by invoking .iterator() on an arraylist. If you invoke it on something else, there may or may not be a counter - as long as the iterator WORKS, it doesn't matter how it works, that's the beauty of interfaces.
A while loop checks the condition and when condition is true then executes the body of the loop and iterates itself,
while(condition){
//do something.
}
The hasNext() is a method from the Iterator interface which returns true if the "iteration" has more elements, if there are no more elements it returns fals and will no longer enter the body of the while loop:
while(x.hasNext){
//do something.
}
The next() method is a method from the Iterator interface and returns the next element of the iteration.
while(x.hasNext){
x.next();
}
I mean after printing Volvo how can it goes to the next element? It
returns all element and if there is no more .hasNext(); returns false
and code continues to next line is simple answer and correct but I
want to understand it clearly.
int cursor; // index of next element to return
//...
public boolean hasNext() {
return cursor != size;
}
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
//...
Given above is how ArrayList#hasNext and and ArrayList#next have been implemented. The code is straight forward and easy to understand. You can check the full code by using a decompiler or here.

Recursion reverse a SingleLinkedList and print as a String

I was given the task to add a method reversed to a SingleLinkedList using recursion preferably.
public String reversed() {
StringBuilder b = new StringBuilder();
reversed(first, b);
return b.toString();
}
private void reversed(Node<E> n, StringBuilder b) {
if (n != null) {
reversed(n.next, b);
b.append(n.element);
b.append(ā€™\nā€™);
}
}
Seems to work very well when I test in eclipse.
However, I am not sure if I understand 100% why.
This is how I think. Let us imagine we have SingleLinkedList with 5 Nodes and we put in the first Node in the private method to reverse it.
Since n isnt null, its the first node. It will enter the if statement.
It will call on itself, but now with Node second, its not null since it will repeat....
Now it reaches Node 5, it calls itself, but then it will call on reversed (six,b) since Node six dosent exist and is null, it will not work. Therefore it moves to the row "b.append(n.element);" however. It now remembers where it started and appends "first.element"; after that it will append a new row.
What exaplins the logic that it will hereafter append second.element; Can someone explain how I should think to understand that it will now append the second element?
Thanks in advance, think I really need to understand this to under recursion fully in java
Each method call keeps its own state. Once you get to node 6, there will be 5 calls on the stack waiting for reversed(n.next, b) to finish. Each method can only continue after the call to reversed on the stack above it finishes.
In this example you have last in as the first to act, i.e. you have a non-tail recursive function (the recursive call is happening before you perform the action of that method).
Imagine if every time you got to reversed you replaced that method call with the code it would execute. Remember all the calls happens serially (there is only one thread, nothing can happen in parallel). You'd get something that looks like this:
if (n0 != null) {
Node<E> n1 = n0.next;
if (n1 != null) {
Node<E> n2 = n1.next;
if (n2 != null) {
Node<E> n3 = n2.next;
if (n3 != null) {
Node<E> n4 = n3.next;
if (n4 != null) {
Node<E> n5 = n4.next;
if (n5 != null) {
// would be null so nothing happens
}
b.append(n4.element);
b.append('\n');
}
b.append(n3.element);
b.append('\n');
}
b.append(n2.element);
b.append('\n');
}
b.append(n1.element);
b.append('\n');
}
b.append(n0.element);
b.append('\n');
}
You can see how this code gets pretty hard to read once the number of elements goes up. When we don't know exactly how long the list will be this approach breaks down... you wouldn't want to do this 10, 100, or possibly thousands of times!
This is exactly why recursion is so useful for applications like this. We are able to re-use the interesting logic without having to know the length of the list, and are able to reduce duplicated code significantly.
Just keep in mind that recursion comes at a memory cost. Each time you enter the recursive method you add state to the stack. Once you cap out the memory on your machine you'll have to begin looking at non recursive ways of performing this work.

Implenting Iterator interface in a linked list class

public boolean hasNext() {
// TODO Auto-generated method stub
return current != null;
}
public T next() throws NoSuchElementException {
if (!hasNext())
throw new NoSuchElementException();
else
prev = current;
current = current.next;
return (T) prev.data;
}
//This is my linked list
f.add(132);
f.add(133);
//while loop I am using in regular main method to test
while(f.iterator().hasNext()){
System.out.println(f.iterator().next());
}
For some reason I just get an infinite loop here and I am not sure why. I ran this in my main method and it just kept printing 132, I am not sure what's wrong.
Get the iterator out of the loop. You are getting a new iterator every time the loop completes one circle. Thus just the first element is printed again and again.
Since the same element print again and again, there are 2 possibility could be happen.
The iterator is not moving and pointed to same element, even after you call next.
The linked-list is a circular one, iterator is automatically moving without call next. So iterator move to next Node (value = 133) and then calling next will move it to same element, since it is circular one.
I hope the problem is with the linked-list code. So give the linked-list code. It will help to find out the bug.

Monster object deletion

Short introduction:
I'm building a game, where monsters spawn at the top, and moves through a path, to the reach a point where they need to be removed/destroyed/deleted. But I can't seem to get the Monster Object deleted.
for (Monster i : Monstre)
{
this.add(i); //adds monster to JPanel
if(i.monstery > 50 && i.monsterx > 50){ //check if monster have reached end point
this.remove(i); //Should remove Object from the JPanel ?
i = null; //Sets object too null
Monstre.remove(i); //Removes object from arrayList "Monstre".
}else{
//Update the monsters bounds
The above removes the object from the JPanel, and it seems to be all good. But when i call System.out.println(Monstre.size()); I get an increasing amount of monsters spawned, and if increasing the monster spawn rate, the program starts to eventually slow down, because amount of monsters in the Monstre arraylist is over 9000, and never decreasing.
What I'm looking for, is a way to remove these objects while the game is running.
Remove the i = null; line. This is not C and you don't have to assign your variables to null. JVM will do that for you (google "java garbage collection"). Because of that line, you practically call Monstre.remove(null) which does not work.
Also, you cannot iterate over the collection in that manner and modify it (remove values). Save the monsters you want to delete in an array outside of the scope of the loop, and remove them after the loop finishes. Otherwise, use an iterator:
Iterator<Monster> it= Monstre.iterator();
while (it.hasNext()) {
Monster i= it.next();
//code code code
if (shouldDelete) {
this.remove(i);
it.remove();
}
}
In addition to the suggestion in the first answer, you should change your loop. Removing items from the Monstre list while using the for-each loop will cause problems.
Instead try :
Iterator<Monster> iter = Monstre.iterator ();
while (iter.hasNext())
{
i = iter.next();
this.add(i); //adds monster to JPanel
if(i.monstery > 50 && i.monsterx > 50){ //check if monster have reached end point
this.remove(i);
iter.remove();
}else{
EDIT :
Here's an explanation where you can't use the for-each loop :
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. Finally, it is not usable for loops that must iterate
over multiple collections in parallel. These shortcomings were known
by the designers, who made a conscious decision to go with a clean,
simple construct that would cover the great majority of cases.
i = null; //Sets object too null
Monstre.remove(i); //Removes object from arrayList "Monstre".
Here you set the variable i to null then you request that i (i.e. null) is removed from your arraylist, the arraylist does not contain null so nothing happens. Setting things equal to null is very rarely nessissary.
As you have correctly said removing the i=null upsets the program, this is because you are iterating through the list and then changing the list while iterating, you have two options;
1) go through the Arraylist in a manor similar to an array
import java.util.*;
public class Test{
public static void main(String [] args){
ArrayList<Double> doubles=new ArrayList<Double>();
for(double i=0;i<10;i++){
doubles.add(i);
}
//remove 7.0s from doubles
for(int i=doubles.size()-1;i>=0;i--){
//must go through backwards - see http://stackoverflow.com/questions/12111210/java-arraylist-search-and-remove for why
if (doubles.get(i).equals(7.0)){
doubles.remove(i);
}
}
}
}
2) use an iterator and its remove method
import java.util.*;
public class Test{
public static void main(String [] args){
ArrayList<Double> doubles=new ArrayList<Double>();
for(double i=0;i<10;i++){
doubles.add(i);
}
//remove 7.0s from doubles
Iterator<Double> iterator=doubles.iterator();
while(iterator.hasNext()){
Double testDouble=iterator.next();
if (testDouble.equals(7.0)){
iterator.remove();
}
}
}
}
You cannot remove this element in a for-loop.
You need to use listIterator() method to retrieve an iterator that can be modified and loop with iterator-style. Otherwise you would always get java.util.ConcurrentModificationException

Implementing Stack's Pop method with Recursion

I am self-studying java. I have been studying data structures for the past couple of days. I am reading the book "Data Structures and Algorithms in Java". there is an exercise that I have problem with. it asks for implementing the pop method with recursion so that when the method is called it should delete all the items at once. can anyone help on this? a pointer on how to do it would be much appreciated. thanks. (following is the pop method currently implemented).
public double pop() // take item from top of stack
{
return stackArray[top--]; // access item, decrement top
}
First IMO you should understand how to implement a non-recursive counterpart of this method.
It can be something like this:
public void popAll() {
while(!stack.isEmpty()) {
stack.pop();
}
}
Once you understand this, the recursive version should be easy:
public void popAllRecursive() {
if(stack.isEmpty()) {
//nothing to remove, return
return;
}
stack.pop(); // remove one stack element
popAllRecursive(); // recursive invocation of your method
}
Since its an exercise I just provide you an idea and leave the implementation to you (you can consider to provide the method in class Stack and use the top counter and stackArray - an implementation of your stack.
Hope this helps
You need to think about the base case where there is nothing in the stack, i.e. stack.pop() == null.
For the recursive case, it is quite intuitive as you just need to recursively call pop() until the base case is met.
Call pop() repeatedly till end of stack.
As you have not mentioned how the data is stored cant help you providing code.
thanks every one, i solved the problem. don't know if efficient, but i did like below:
public void pop()
{
if(isEmpty()){
return;
}
if (top>=0){
stackArray[top] = stackArray[top--];
pop();
}
}

Categories