Amar Amar - 24 days ago 6
Java Question

Loop through a LinkedList

I'm trying to get a

LinkedList
from my buffer class (
BufferCharacter
) and then loop through every element in the
LinkedList
in the
Reader
class. But when I try return the
LinkedList
in the
get()
method in
BufferCharacter
class I then cannot loop through it in the
Reader
class. I've tried to loop through the List in the
Buffer
class and then return each element from there but that doesn't work either.

Any help is highly appreciated!

public class CharacterBuffer {

private char ch;
private LinkedList buffer = new LinkedList();
private boolean filled;

public void put(char ch) {
buffer.addLast(ch);
}

public void filled() {
filled = true;
}

public Object get() throws InterruptedException {
while (buffer.isEmpty()) {
// wait();
return "Waiting";
}
return buffer;
}

public synchronized void putSync(char ch) {
buffer.addLast(ch);
}

public synchronized Object getSync() throws InterruptedException {
while (buffer.isEmpty()) {
// wait();
return "---------";
}

for(int i = 0; i<buffer.size(); i++){
System.out.println(buffer.get(i));
}

return buffer;

}

public int size(){
return buffer.size();
}

}

public class Reader extends Thread {

private GUIMutex gui;
private CharacterBuffer buffer;
private boolean isSynced;

public Reader(GUIMutex gui, CharacterBuffer buffer, boolean isSynced) {
this.gui = gui;
this.buffer = buffer;
this.isSynced = isSynced;
}

public void run() {
String data = "test";
while (true) {

try {
// data = buffer.get();
if (isSynced) {
gui.setReaderText(buffer.getSync() + "\n");
} else {
for(int i = 0; i<buffer.get().size(); i++){
gui.setReaderText(i);
}
gui.setReaderText(buffer.get() + "\n");
}
Thread.sleep(700);
} catch (InterruptedException e) {
}

}
}
}

Answer

I think you don't understand what you are talking about; so lets try to shed some light here.

In the end, you are talking about some kind of "collection" class that contains multiple elements; in your case a LinkedList. The thing is: in order to make use of such a class, you need a clear understanding of the APIs you intend to provide.

You figured that you want to use that buffer to store individual char values, that you add using putSync().

But then ... what exactly is getSync() supposed to do?

In your case, you are simply returning the buffer, and that is probably wrong.

Instead, you want to have methods like:

synchronized boolean hasNext() 

and

synchronized char getNext() 

A user of your class can call the first method to figure: are there other chars; and if so, the second method returns those values.

That would a first, simple way to improve your code. A more reasonable way would be that you implement a method getIterator() that would return an object implementing the Iterator interface.

Other things to note: if you are using the "built-in" LinkedList; please understand that this class supports generics!

Thus you should be using it like:

private final List<Character> buffer = new LinkedList<>();

to get all the benefits from using strongly typed collections!

EDIT: upon your comments, I think using a LinkedList is simply the wrong approach here.

Instead of using a List, you want to use a Queue, like:

private final Queue<Character> buffer = new ConcurrentLinkedQueue<>();

That class gives you that functionality that one party can add elements at the queue tail; whereas another party removes elements from the queue head.

Extra bonus: that class is doing the synchronisation work for you already, so you don't need to care about that!