Simple Lock-Free Stack - java

Recently have found such java-concurrency interview task:
Write simple lock-free Stack with two methods: push and pop.
I made the concent:
import java.util.concurrent.atomic.AtomicInteger;
public class Stack {
private AtomicInteger count = new AtomicInteger(-1);
private Object[] data = new Object[1000];
public void push(Object o) {
int c = count.incrementAndGet();
data[c] = o;
}
public Object pop() {
Object top;
int c;
while (true) {
c = count.get();
if (c == -1) return null;
top = data[c];
if (count.compareAndSet(c, c-1))
return top;
}
}
}
Is it similar to approach was expected? Or "lock-free stack" means something different? Please, help a java-interview newbie.

You've certainly started in the right direction, thinking about using Java's atomic integer and atomic functions. That would thus be a lock-free stack, as in: there are no explicit locks.
It is still not correct when concurrently accessed, however, and it's relatively simple to demonstrate that: imagine your push() thread blocks between getting the count and adding the new element to the stack (data[c] = o), and in the meantime a pop() thread comes along, gets the higher count, and pops... What? Whatever happens to be in memory at that location in the stack, but not the Object o (because it wasn't yet inserted).
And that's the problem with lock-free, array-backed stacks, that you have two things you theoretically need to adjust, the count and the content of that particular cell, and you can't do both atomically at the same time. I'm not aware of any lock-free array-backed stack algorithm out there.
There are linked-list-backed stack algorithms though that are lock-free, because in that case you can create a new node, assign it the content, and you only have one operation to execute atomically: change the top pointer.
If you're interested in the argument, the best literary work is Shavit and Herlihy's "The Art of Multiprocessor Programming", which describes lots of different data structures, both lock-free and lock-based. I can't find any paper right now describing the "usual" lock-free stack algorithm in detail, though Maged Michael mentions it in his SMR paper, page 8, point 4.2, and I have done a C99 implementation myself.

import java.util.Random;
import java.util.concurrent.atomic.AtomicReference;
public class LockFreeStack {
public static void main(String... args) {
LFStack<String> stack = new LFStack<String>();
for (int i = 0; i < 10; i++) {
Thread t = new Thread(new RandomStackUse(stack));
t.setName("My stack thread " + i);
t.start();
}
}
private static class LFStack<E> {
private volatile AtomicReference<Node<E>> head = new AtomicReference<Node<E>>();
public E peek() {
E payload = null;
Node<E> node = head.get();
if (node != null) { payload = node.payload; }
return payload;
}
public E pop() {
E payload;
while (true) {
Node<E> oldHeadNode = head.get();
if (oldHeadNode == null) { return null; }
payload = head.get().payload;
if (head.compareAndSet(oldHeadNode, oldHeadNode.next.get())) { break; }
//System.out.println("Retry");
}
return payload;
}
public void push(E e) {
Node<E> oldHeadNode = new Node<E>(e);
while (true) {
Node<E> oldRootNode = head.get();
if (oldRootNode != null) { oldHeadNode.next.set(oldRootNode); }
if (head.compareAndSet(oldRootNode, oldHeadNode)) { break; }
//System.out.println("Retry");
}
}
}
//to be used as LinkedList chain <Node> => <Node> => <Node> => null
private static class Node<E> {
private E payload;
private AtomicReference<Node<E>> next;
public Node(E e) {
payload = e;
next = new AtomicReference<Node<E>>();
}
}
public static class RandomStackUse implements Runnable {
private LFStack<String> stack;
private Random rand = new Random();
public RandomStackUse(LFStack<String> stack) {this.stack = stack;}
#Override
public void run() {
long counter = 0;
while (true) {
if (rand.nextInt() % 3 == 0) {
stack.push(String.valueOf(counter++));
//System.out.println(String.format("%s pushed %d", Thread.currentThread().getName(), counter));
}
if (rand.nextInt() % 3 == 1) {
String value = stack.pop();
//System.out.println(String.format("%s pop %s", Thread.currentThread().getName(), value));
}
if (rand.nextInt() % 3 == 2) {
String value = stack.peek();
//System.out.println(String.format("%s peek %s", Thread.currentThread().getName(), value));
}
}
}
}
}

public class MyConcurrentStack<T>
{
private AtomicReference<Node> head = new AtomicReference<Node>();
public MyConcurrentStack()
{
}
public void push(T t)
{
Node<T> n = new Node<T>(t);
Node<T> current;
do
{
current = head.get();
n.setNext(current);
}while(!head.compareAndSet(current, n));
}
public T pop()
{
Node<T> currentHead = null;
Node<T> futureHead = null;
do
{
currentHead = head.get();
if(currentHead == null)
{
return null;
}
futureHead = currentHead.next;
}while(!head.compareAndSet(currentHead, futureHead));
return currentHead.data;
}
public T peek()
{
Node<T> n = head.get();
if(n==null)
{
return null;
}
else
{
return n.data;
}
}
private static class Node<T>
{
private final T data;
private Node<T> next;
private Node(T data)
{
this.data = data;
}
private void setNext(Node next)
{
this.next = next;
}
}
public static void main(String[] args)
{
MyConcurrentStack m = new MyConcurrentStack();
m.push(12);
m.push(13);
m.push(15);
System.out.println(m.pop());
System.out.println(m.pop());
System.out.println(m.pop());
System.out.println(m.pop());
}
}
The code is self explanatory. Please let me know if anybody needs explanation.
The stack is formed as per the following diagram:
... ... ...
| |-->| | -->| |
... ... ...
^
|
current head

You can use BlockingQueue Use method put() to insert the element and method drainTo(Collection c) to get elements. Then read elements from the end of c.

Related

Properly Writing Object Oriented Code in java for a stack

I'm trying to write code in a way that it is object oriented. In this particular case I want to keep track of the minimum value of my stack in O(1) time. I know how to do it, the idea of it, well my idea of it, which is to have another stack that keeps track of the minimum value for every push and pop.
I've nested every class inside of the program class which is called minStack, which doesn't seem like the right thing to do however when I create a instance of minStack and call its variables it works out fine for a regular stack. I created a class that extends a Stack called StackWithMin but I don't know how to call its values. Should I create a new instance of a StackWithMin? If so how would i do it? I did it at the end of the code above the main function, but peek() always returns null
class minStack {
public class Stack {
Node top;
Object min = null;
Object pop() {
if(top != null) {
Object item = top.getData();
top = top.getNext();
return item;
}
return null;
}
void push(Object item) {
if(min == null) {
min = item;
}
if((int)item < (int)min) {
min = item;
}
Node pushed = new Node(item, top);
top = pushed;
}
Object peek() {
if(top == null) {
//System.out.println("Its null or stack is empty");
return null;
}
return top.getData();
}
Object minimumValue() {
if(min == null) {
return null;
}
return (int)min;
}
}
public class Node {
Object data;
Node next;
public Node(Object data) {
this.data = data;
this.next = null;
}
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
public void setNext(Node n) {
next = n;
}
public Node getNext() {
return next;
}
public void setData(Object d) {
data = d;
}
public Object getData() {
return data;
}
}
public class StackWithMin extends Stack {
Stack s2;
public StackWithMin() {
s2 = new Stack();
}
public void push(Object value) {
if((int)value <= (int)min()) {
s2.push(value);
}
super.push(value);
}
public Object pop() {
Object value = super.pop();
if((int)value == (int)min()) {
s2.pop();
}
return value;
}
public Object min() {
if(s2.top == null) {
return null;
}
else {
return s2.peek();
}
}
}
Stack testStack = new Stack();
StackWithMin stackMin = new StackWithMin();
public static void main(String[] args) {
minStack mStack = new minStack();
//StackWithMin stackMin = new StackWithMin();
mStack.testStack.push(3);
mStack.testStack.push(5);
mStack.testStack.push(2);
mStack.stackMin.push(2);
mStack.stackMin.push(4);
mStack.stackMin.push(1);
System.out.println(mStack.testStack.peek());
System.out.println(mStack.stackMin.peek());
mStack.testStack.pop();
}
}
I would suggest to create generic interface Stack like this one
interface Stack<T> {
void push(T item);
T pop();
T peek();
}
Generics add stability to your code by making more of your bugs
detectable at compile time.
See more about generics here.
Then implement this interface in a common way. All implementation details will be hidden inside of this class (your Node class for example). Here is the code (it is just to show the idea, if you want to use it you need to improve it with exception handling for example). Note that class Node is now also generic.
class SimpleStack<T> implements Stack<T> {
private class Node<T> { ... }
private Node<T> root = null;
public void push(T item) {
if (root == null) {
root = new Node<T>(item);
} else {
Node<T> node = new Node<T>(item, root);
root = node;
}
}
public T pop() {
if (root != null) {
T data = root.getData();
root = root.getNext();
return data;
} else {
return null;
}
}
public T peek() {
if (root != null) {
return root.getData();
} else {
return null;
}
}
}
Now we get to the part with stored minimum value. We can extend our SimpleStack class and add field with another SimpleStack. However I think this is better to make another implementation of the Stack and store two stacks for values and for minimums. The example is below. I have generalize the class that now uses Comparator to compare object, so you can use any other object types.
class StackWithComparator<T> implements Stack<T> {
private Comparator<T> comparator;
private SimpleStack<T> mins = new SimpleStack<>();
private SimpleStack<T> data = new SimpleStack<>();
public StackWithComparator(Comparator<T> comparator) {
this.comparator = comparator;
}
public void push(T item) {
data.push(item);
if (mins.peek() == null || comparator.compare(mins.peek(), item) >= 0) {
mins.push(item);
} else {
mins.push(mins.peek());
}
}
public T pop() {
mins.pop();
return data.pop();
}
public T peek() {
return data.peek();
}
public T min() {
return mins.peek();
}
}
Now you can use both implementations like so
SimpleStack<Integer> s1 = new SimpleStack<>();
s1.push(1);
s1.push(2);
s1.push(3);
System.out.println(s1.pop()); // print 3
System.out.println(s1.pop()); // print 2
System.out.println(s1.pop()); // print 1
StackWithComparator<Integer> s2 = new StackWithComparator<>(new Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
});
s2.push(1);
s2.push(2);
s2.push(3);
s2.push(0);
s2.push(4);
System.out.println(s2.min() + " " + s2.pop()); // print 0 4
System.out.println(s2.min() + " " + s2.pop()); // print 0 0
System.out.println(s2.min() + " " + s2.pop()); // print 1 3
System.out.println(s2.min() + " " + s2.pop()); // print 1 2
System.out.println(s2.min() + " " + s2.pop()); // print 1 1

My implementation of a lock free linked list returns always an empty string on toString()

I am experimenting with lock free linked lists. This is my first shot but I have no idea why the toString method always returns an empty string even if I can see values in the debugger.
package com.linkedq;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicReference;
public class LinkedQueue <E> {
private static class Node <E> {
final E item;
final AtomicReference<Node<E>> next;
Node(E item, Node<E> next) {
this.item = item;
this.next = new AtomicReference<>(next);
}
#Override
public String toString() {
return item.toString();
}
}
private AtomicReference<Node<E>> head = new AtomicReference<>(new Node<E>(null, null));
private AtomicReference<Node<E>> tail = head;
public boolean put(E item) {
Node<E> newNode = new Node<E>(item, null);
while (true) {
Node<E> curTail = tail.get();
Node<E> residue = curTail.next.get();
if (curTail == tail.get()) {
if (residue == null) /* A */ {
if (curTail.next.compareAndSet(null, newNode)) /* C */ {
tail.compareAndSet(curTail, newNode) /* D */ ;
return true;
}
} else {
tail.compareAndSet(curTail, residue) /* B */;
}
}
}
}
public void remove(E item) {
Node<E> current = this.head.get().next.get();
Node<E> next = null;
while (current != null) {
next = current.next.get();
if (next.equals(item)) {
if (!current.next.compareAndSet(next, next.next.get())) {
// some other thread changed the list, do a retry
remove(item);
}
}
current = next;
}
}
#Override
public String toString() {
Node<E> current = head.get().next.get();
StringBuilder sb = new StringBuilder();
while (current != null) {
sb.append(current).append(", ");
current = current.next.get();
}
return sb.toString();
}
public static void main(String[] args) throws InterruptedException {
final ExecutorService es = Executors.newFixedThreadPool(10);
final LinkedQueue<Integer> q = new LinkedQueue<>();
for (int i=0; i<10000; i++) {
es.execute(new Inserter(q, i));
}
// es.shutdown();
// es.awaitTermination(1L, TimeUnit.HOURS);
System.out.println("FIN" + q);
}
private static class Inserter implements Runnable {
private final LinkedQueue<Integer> q;
private final int value;
public Inserter(LinkedQueue<Integer> q, int value) {
this.q = q;
this.value = value;
}
#Override
public void run() {
q.put(value);
System.out.println("q = " + q);
}
}
}
At least one obvious error is that your head and tail are actually the same AtomicReference object, so when you update the tail, the head is updated as well. Use
private AtomicReference<Node<E>> head = new AtomicReference<>(new Node<E>(null, null));
private AtomicReference<Node<E>> tail = new AtomicReference<>(head.get());
Another obvious mistmatch is that the first element you add inside the tail and the head:
tail.compareAndSet(curTail, newNode) ;
While when you read, you start printing from the next of the head:
Node<E> current = head.get().next.get();
So even without having multiple threads, etc, just adding one element and printing the list does not work. Add unit tests to verify the behavior!

Troubles with java generics and linked lists/ques

I am currently running into problems with java generics, linked list/ques structures and methods that should operate on them. Currently, I am trying to write generic methods that should manipulate a linked list of jobs for my school project. I have to implement basic methods, such as enque, de-que, sort-by-priority, get number of elements and so on. The element is, say, a printing job with a priority. A print que shall be implemented as a linked list of jobs. I am not allowed to use any pre-defined collection classes.
This being said, I am not getting something obvious. In the java code shown below, there are 3 classes (Job, MyPrintQue and LinkNode) and one generic interface (PrintQue). I am not importing any other classes from java.util. In the line 85 I use a curr.data.getPriority() method, but curr.data is taken here as the type Object, instead of the type Job, and therefore does have getPriority() method defined. Not sure why is that and how to fix it.
I've gone through a couple of related posts here, but have not found any remedy to my problem. Would be grateful for any input.
Here's the code:
Class Job
public class Job {
private int priority;
public Job(int i) {this.priority=i;}
public int getPriority(){return priority;}
public String toString () {return String.format("This job has priority %d", priority);}
}
Class MyPrintQue
public class ListNode<Job> {
public Job head;
public ListNode<Job> tail;
ListNode (Job j) {this.head=j;}
public Job getHead(){return head;}
public void setHead(Job j){}
}
Interface PrintQue
public interface PrintQue<Job> {
public void enque(Job j);
public void deque(ListNode<Job> n);
public void printQue();
public boolean isEmpty();
public ListNode<Job> hasTheHighestPriority();
public void sortByPriority();
}
and Class MyPrintQue
public class MyPrintQue<Job> implements PrintQue<Job>
{
//Setting up front and end elements of a print que.
private ListNode<Job> front;
private ListNode<Job> end;
private static int queLength;
//Accessors for head and tail.
public ListNode<Job> getFront(){return front;}
public ListNode<Job> getEnd(){return end;}
public void enque(Job j)
{
if (front == null && end == null)
{
front = new ListNode<Job>(j);
queLength++;
}
else if (front !=null & end == null)
{
end = new ListNode<Job>(j);
front.tail =end;
queLength++;
}
else
{
ListNode<Job> temp = new ListNode<Job>(j);
end.tail = temp;
end = temp;
queLength++;
}
}
public boolean find(ListNode<Job> n)
{
for (ListNode<Job> curr = front; curr !=null; curr = curr.tail)
{
if (curr == n) return true;
}
return false;
}
public void deque(ListNode<Job> n)
{
if (find(n))
{
for (ListNode<Job> curr = front; curr !=null; curr = curr.tail)
{
if (front == n) {front = n.tail;}
else if (curr.tail == n) {curr.tail=n.tail;}
}
n = null;
queLength--;
}
}
public void printQue()
{
int length=0;
for (ListNode<Job> curr = front; curr !=null; curr = curr.tail)
{
System.out.println(curr.head);
length++;
}
System.out.println(length);
}
public boolean isEmpty(){if (front == null) return true; else return false;}
public ListNode<Job> hasTheHighestPriority()
{
ListNode<Job> temp = new ListNode<Job>(null);
int prior = 0;
for (ListNode<Job> curr = front; curr.head !=null; curr = curr.tail)
{
if (prior <= ((curr.head).getPriority()))
{
System.out.printf("Current priority is %d, top priority is %d%n", curr.head.getPriority(), prior);
temp = curr;
prior = (int)curr.head.getPriority();
}
}
return temp;
}
public void sortByPriority()
{
MyPrintQue<Job> temp = new MyPrintQue<Job>();
while(!isEmpty())
{
temp.enque(hasTheHighestPriority().head);
deque(hasTheHighestPriority());
}
front = temp.front;
}
}
The difference between your
public class MyPrintQue<Job> implements PrintQue<Job>
and
public class MyJobPrintQue implements PrintQue<Job>
is that in the first case Job is a generic type parameter, nothing to do with the class Job.
And the rewrite, there is a PrintQue of the class Job.
Instead of parameters <Job> better use <J> or whatever.
For good order "queue" is the spelling in English (for an explanation "few" also has double u).
The NullPointerException can be removed by:
if (front == n) {
front = n.tail;
} else {
for (ListNode<Job> curr = front; curr !=null; curr = curr.tail) {
if (curr.tail == n) {
curr.tail = n.tail;
break;
}
}
}

MergeSorting LinkedList in Java recursively

So the task is to implement a linked-list and merge-sort which sorts linked-lists. I am fully aware that in industry I most likely won't have to implement any of these but I feel it's a good way to practice Java. Here is what I've got up to this point:
Node class:
public class Node<E extends Comparable<E>>
{
public E data;
public Node<E> next;
public Node(E data)
{
this.data = data;
next = null;
}
public void printData()
{
System.out.print(data + " ");
}
}
LinkedList class:
public class LinkedList<E extends Comparable<E>>
{
protected Node<E> root;
protected int size = 0;
public LinkedList()
{
root = null;
}
public void addBeg(E e)
{
Node<E> newNode = new Node<E>(e);
newNode.next = root;
root = newNode;
size++;
}
public Node deleteBeg()
{
Node<E> temp = root;
if(!isEmpty())
{
root = root.next;
size--;
}
return temp;
}
public void setRoot(Node<E> newRoot)
{
root = newRoot;
}
public boolean isEmpty()
{
return root == null;
}
public Node<E> getRoot()
{
return root;
}
public void printList()
{
Node<E> cur = root;
while(cur!=null)
{
cur.printData();
cur=cur.next;
}
System.out.println();
}
}
MergeSorter Class:
public class MergeSorter<E extends Comparable<E>>
{
public MergeSorter()
{
}
private void split(LinkedList<E> list, LinkedList<E> firHalf, LinkedList<E> secHalf)
{
//if 0 or only 1 elements in the list - it doesn't seem to work, however
if(list.getRoot() == null || list.getRoot().next == null)firHalf = list;
else{
Node<E> slow = list.getRoot();
Node<E> fast = list.getRoot().next;
while(fast!=null)
{
fast = fast.next;
if(fast!=null)
{
fast = fast.next;
slow = slow.next;
}
}
//If I use the following line firHalf list is empty when in the caller of this method (it's not in this method, however). Don't understand why ):
//firHalf = list;
firHalf.setRoot(list.getRoot());
secHalf.setRoot(slow.next);
slow.next = null;
}
}
private LinkedList<E> merge(LinkedList<E> a, LinkedList<E> b)
{
LinkedList<E> mergedList = new LinkedList<E>();
Node<E> dummy = new Node<E>(null);
Node<E> tail = dummy;
while(true)
{
if(a.getRoot() == null){
tail.next = b.getRoot();
break;
}
else if(b.getRoot() == null){
tail.next = a.getRoot();
break;
}
else
{
if(a.getRoot().data.compareTo(b.getRoot().data) <= 0)
{
tail.next = a.getRoot();
tail = tail.next;
a.setRoot(a.getRoot().next);
}
else
{
tail.next = b.getRoot();
tail = tail.next;
b.setRoot(b.getRoot().next);
}
tail.next = null;
}
}
mergedList.setRoot(dummy.next);
return mergedList;
}
public void mergeSort(LinkedList<E> list)
{
Node<E> root = list.getRoot();
LinkedList<E> left = new LinkedList<E>();
LinkedList<E> right = new LinkedList<E>();
if(root == null || root.next == null) return; //base case
split(list, left, right); //split
mergeSort(left);
mergeSort(right);
list = merge(left, right); // when this mergeSort returns this list should be
// referenced by the left or right variable of the
// current mergeSort call (but it isn't!)
}
}
I am fairly new to Java (coming from a C background) so I am sincerely sorry in advance if my code is utterly false. When I test the split and merge methods in the MergeSorter class independently, everything seems to work (splitting a list consisting of 0 or 1 element is not working and is driving me crazy but this is not needed for merge-sorting). The mergeSort method, however, is not working and I can't seem to figure out way. I tried to debug it myself and there's seems to be a problem when two halves are merged into one list and then the recursion returns. The newly merged list should be referenced by either the left or right variable of the current mergeSort call but instead I get only the last element instead of the whole list.
Method arguments in Java are always passed by value.
This can be a bit confusing, since objects are always accessed via references, so you might think they're passed by reference; but they're not. Rather, the references are passed by value.
What this means is, a method like this:
public void methodThatDoesNothing(Object dst, Object src) {
src = dst;
}
actually does nothing. It modifies its local variable src to refer to the same object as the local variable dst, but those are just local variables that disappear when the function returns. They're completely separate from whatever variables or expressions were passed into the method.
So, in your code, this:
firHalf = list;
does not really do anything. I guess what you want is:
while (! firHalf.isEmpty()) {
firHalf.deleteBeg();
}
if (! list.isEmpty()) {
firHalf.addBeg(list.root().data);
}
which modifies the objected referred to by firHalf so it has the same zero-or-one elements as list.

How to build a link list in Java? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I implement a Linked List in Java?
We know there is no pointers in java. Then what is the best way to build the link list in java?
The best way is to not build it. Java already has a LinkedList class amongst its rather large selection of collection classes.
You would be better off using what the language/library already provides.
You have an object that essentially contains two variables, no methods (bare minimum; however, you could have methods if you wanted). Something like:
class Link
{
int data;
Link next;
}
Then you create a new Link like any other object. Set the data to the data you want a node to hold. Then set the Link node to the node that it will be "pointing" to (or null if it doesn't point to another one).
Note: you can also have a previous node (which points to the previous node) if need be.
try having this code.
public class Main {
public static void main(String[] args) {
LinkedList theList = new LinkedList();
LinkedListIterator theItr;
theItr = theList.zeroth();
printList(theList);
for (int i = 0; i < 10; i++) {
theList.insert(new Integer(i), theItr);
printList(theList);
theItr.advance();
}
System.out.println("Size was: " + listSize(theList));
}
public static int listSize(LinkedList theList) {
LinkedListIterator itr;
int size = 0;
for (itr = theList.first(); itr.isValid(); itr.advance())
size++;
return size;
}
public static void printList(LinkedList theList) {
if (theList.isEmpty())
System.out.print("Empty list");
else {
LinkedListIterator itr = theList.first();
for (; itr.isValid(); itr.advance())
System.out.print(itr.retrieve() + " ");
}
System.out.println();
}
}
class LinkedList {
public LinkedList() {
header = new ListNode(null);
}
public boolean isEmpty() {
return header.next == null;
}
public void makeEmpty() {
header.next = null;
}
public LinkedListIterator zeroth() {
return new LinkedListIterator(header);
}
public LinkedListIterator first() {
return new LinkedListIterator(header.next);
}
public void insert(Object x, LinkedListIterator p) {
if (p != null && p.current != null)
p.current.next = new ListNode(x, p.current.next);
}
public LinkedListIterator find(Object x) {
ListNode itr = header.next;
while (itr != null && !itr.element.equals(x))
itr = itr.next;
return new LinkedListIterator(itr);
}
public LinkedListIterator findPrevious(Object x) {
ListNode itr = header;
while (itr.next != null && !itr.next.element.equals(x))
itr = itr.next;
return new LinkedListIterator(itr);
}
public void remove(Object x) {
LinkedListIterator p = findPrevious(x);
if (p.current.next != null)
p.current.next = p.current.next.next; // Bypass deleted node
}
private ListNode header;
}
class LinkedListIterator {
LinkedListIterator(ListNode theNode) {
current = theNode;
}
public boolean isValid() {
return current != null;
}
public Object retrieve() {
return isValid() ? current.element : null;
}
public void advance() {
if (isValid())
current = current.next;
}
ListNode current;
}
class ListNode {
public ListNode(Object theElement) {
this(theElement, null);
}
public ListNode(Object theElement, ListNode n) {
element = theElement;
next = n;
}
public Object element;
public ListNode next;
}

Categories