Iterating through elements of a data structure instead of Collection - java

My problem is this: I have an iterator class which is supposed to iterate through elements in a given data structure, <E> let's say, but what I have managed to accomplish is that when I pass in the data structure it will iterate the data structure itself.
ie. DynamicIterator it = new DynamicIterator(da);
say da is an array the output will be [1,2,3,4,5,6] instead of 1,2,3,4,5,6
My issue is, more than anything, understanding the generally accepted practice for dealing with this more than the issue itself.
edit for code:
public class X<E>
{
private final E[] rray;
private int currentIndex = 0;
public X(E... a)
{
//if the incoming array is null, don't start
if(a == null)
{
System.out.println("Array is null");
System.exit(1);
}
//set the temp array (rray) to the incoming array (a)
this.rray = a;
}
//hasNext element?
public boolean hasNext()
{
return rray.length > currentIndex;
}
//next element (depends on hasNext())
public E next()
{
if (!hasNext())
{
System.out.println("Element doesn't exist, done");
System.exit(1);
}
return rray[currentIndex++];
}
//return array
public E[] access()
{
return rray;
}
}

You won't be able to do this with a completely generic parameter <E> - how would you iterate through a Throwable, for example? What your class X does at the moment is accept any number of objects in its constructor, and then simply returns each of those objects in turn.
If you restricted the bounds of the objects passed in to implement e.g. Iterable, then you can actually start to "look inside" them and return their contents:
public class X<E> {
private final Iterator<E> it;
public X(Iterable<E> a) {
it = a.iterator();
}
public boolean hasNext() {
return it.hasNext();
}
public E next() {
return it.next();
}
}
Although this doesn't really accomplish anything different to just using a.iterator() directly instead of an instance of X...

Related

Get collection element one by one when needed

I have a class Game, which contains a class Board, which contains an ArrayList of Rows.
Currently Game can getCurrentRow() and when the game progresses it does a getNextRow(). Board gets the currentRow, loops over the ArrayList, from the wrong end and at each step holds that row in lastCheckedRow and breaks when it finds currentRow. The nextRow will then become lastCheckedRow. Simple enough, but ugly.
I want to change this approach into streams instead. Is it possible to make a stream that remains reachable, only returning one element at a time when called?
public class Board implements Skinnable{
private Stream<Skinnable> stream;
protected List<Skinnable> rowItems = new ArrayList<>();
private BoardRow currentRow;
private final BoardSkin skin;
public Board(Game game) {
for (int i = 0; i < 10; i++) {
rowItems.add(new BoardRow(game));
if (i == 9) {
setCurrentRow((BoardRow) rowItems.get(rowItems.size() - 1));
}
}
stream = rowItems.stream();
skin = new BoardSkin(this);
}
public void setCurrentRow(BoardRow row) {
currentRow = row;
currentRow.activate();
}
public Row getStreamedRowItem () {
List<Skinnable> collect = stream.limit(1).collect(Collectors.toList());
return (Row) collect.get(0);
}
}
This works, one time, then the stream is closed. This is more of a general question. I have searched, both here and other places, but this is too new to me so I can't even phrase my questions correctly and therefor I am stuck.
Streams can be traversed only once. So you cannot keep it open and yet run the .collect terminal operation.
The best alternative for retrieving an element at a time is to use an iterator:
private Iterator<Skinnable> stream; //Please rename the variable
Then create the iterator in the constructor with:
stream = rowItems.iterator();
Retrieving the next element changes to:
public Row getStreamedRowItem () {
//you'll need to check if there's a next element
//if(stream.hasNext())
return stream.next();
}
If I were you, I would follow JB Nizet's idea which will give you more space/chance to control.
Since you already had rowItems, just by adding another index you can fly anywhere you want in the collection.
Have something as:
int index; // always pointing to the element to be fetched;
public Board(Game game) { {
index = 0; // pointing to the first element;
// or if you want it to point to the last using rowItems.size() - 1 instead;
}
public boolean hasNext() {
return index < rowItems.size();
}
public Row next() {
return (Row) rowItems.get(index++);
}
public boolean hasPrevious() {
return index > -1;
}
public Row previous() {
return (Row) rowItems.get(index--);
}

Fundamental misunderstanding of objects and attributes in Java

I'm sitting on an assignment for university and I'm at a point, where I fear I haven't really understood something fundamental in the concecpt of Java or OOP altogether. I'll try to make it as short as possible (maybe it's sufficient to just look at the 3rd code segment, but I just wanted to make sure, I included enough detail). I am to write a little employee management. One class within this project is the employeeManagement itself and this class should possess a method for sorting employees by first letter via bubblesort.
I have written 3 classes for this: The first one is "Employee", which contains a name and an ID (a running number) , getter and setter methods and one method for checking whether the first letter of one employee is smaller (lower in the alphabet) than the other. It looks like this:
static boolean isSmaller(Employee source, Employee target) {
char[] sourceArray = new char[source.name.length()];
char[] targetArray = new char[target.name.length()];
sourceArray = source.name.toCharArray();
targetArray = target.name.toCharArray();
if(sourceArray[0] < targetArray[0])
return true;
else
return false;
}
I tested it and it seems to work for my case. Now there's another class called EmployeeList and it manages the employees via an array of employees ("Employee" objects). The size of this array is determined via constructor. My code looks like this:
public class EmployeeList {
/*attributes*/
private int size;
private Employee[] employeeArray;
/* constructor */
public EmployeeList(int size) {
this.employeeArray = new Employee[size];
}
/* methods */
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
/* adds employee to end of the list. Returns false, if list is too small */
boolean add(Employee m) {
int id = m.getID();
if (id > employeeArray.length) {
return false;
} else {
employeeArray[id] = m;
return true;
}
}
/* returns employee at certain position */
Employee get(int index) {
return employeeArray[index];
}
/* Sets employee at certain position. Returns null, if position doesn't exist. Else returns old value. */
Employee set(int index, Employee m) {
if (employeeArray[index] == null) {
return null;
} else {
Employee before = employeeArray[index];
employeeArray[index] = m;
return before;
}
}
Now comes my real problem: In a third class called "employeeManagement" I am supposed to implement the sorting algorithm. The class looks like this:
public class EmployeeManagement {
private EmployeeList ml = new EmployeeList(3);
public boolean addEmployee(Employee e) {
return ml.add(e);
}
public void sortEmployee() {
System.out.println(ml.getSize()); // I wrote this for debugging, exactly here lies my problem
for (int n = ml.getSize(); n > 1; n--) {
for (int i = 0; i < n - 1; i++) {
if (Employee.isSmaller(ml.get(i), ml.get(i + 1)) == false) {
Employee old = ml.set(i, ml.get(i + 1));
ml.set(i+1, old);
}
}
}
}
The "println" before my comment returns "0" in console... I am expecting "3" as this is the size I gave the "EmployeeList" as parameter of the constructor within my "EmployeeManagement" class. Where is my mistake ? And how can I access the size of the object I created in the "EmployeeManagement" class (the "3") ? I'm really looking forward to your answers!
Thanks,
Phreneticus
You are not storing size in your constructor. Something like,
public EmployeeList(int size) {
this.employeeArray = new Employee[size];
this.size = size; // <-- add this.
}
Also, setSize isn't going to automatically copy (and grow) the array. You will need to copy the array, because Java arrays have a fixed length. Finally, you don't really need size here since employeeArray has a length.
The size variable you are calling is the class field. If you take a quick look at your code, the getter is getting the field (which is initialized as zero when created). The size you are using it. The good way of doing it would be to get the size of the array in the getter like this:
public int getSize() {
return employeeArray.length;
}
This would return the size of the array in the object.

How to print the first object from the LinkedList using Iterator?

Trying to print out objects from my LinkedList using iterator, but the first object does not get printed out, so it starts from the second one:
Car car1 = new Car("Koenigsegg CCXR Trevita", "BASASS1");
Car car2 = new Car("Lamborghini Veneno", "B1T3M3");
Car car3 = new Car("W Motors Lykan Hypersport", "NUMERO1");
public void addToList() {
availableCarList.add(car1);
availableCarList.add(car2);
availableCarList.add(car3);
System.out.print("Original contents of list: ");
IIterator itr = availableCarList.getIterator();
while(itr.hasNext()) {
Object element = itr.next();
System.out.print(element + " ");
}
System.out.println();
}
Result:
What do I do wrong?
hasNext() and next() implemented in the LinkedList class:
private class Iterator<T> implements IIterator<T>
{
private LinearNode<T> temp;
public Iterator()
{
temp = (LinearNode<T>) front;
}
#Override
public boolean hasNext()
{
return (temp.getNext() != null);
}
#Override
public T next()
{
if (temp == null)
{
throw new IllegalStateException();
}
temp = temp.getNext();
return temp.getElement();
}
}
First of all, the code you have shown us suggests that LinkedList is actually your own class ... not the standard LinkedList.
It is a really bad idea to name your classes with the same (short) name as a standard library class. It confuses readers ... and that would include yourself if you looked at your code in 3+ months time.
The actual problem is most likely that your implementation of the list iterator is incorrect. And it looks to me like you are skipping the first element in the list.
Given what temp contains, I think that:
the hasNext() method should be testing temp, not temp.getNext()
the next() method should be returning temp.getElement(), not temp.getNext().getElement()

StringEnumeration (Enumeration in General)

Ok so the goal of the class is to override the two methods inside of the Enumeration object class. I believe my hasNextElement() method should work, any pointers on that would be appreciated. I, however, am having troubles with the nextElement() method. Excuse the improper commenting throught the class but the goal of nextElement() is to return one character at a time. I figured its just a simple loop but netBeans keeps giving me incompatible dataTypes, which makes sense because its a String method not a Char method. So I change it to char and I get
nextElement() in StringEnumeration cannot implement nextElement() in Enumeration return type char is not compatible with String where E is a type-variable:
Any help would be greatly appreciated. Do remember I am a beginner programmer so I may have done something wrong that is easily fixable.
public class StringEnumeration implements Enumeration<String> {
public String value;
public StringEnumeration(String initialValue) throws InvalidStringException {
if (initialValue == null || initialValue.length() == 0) {
throw new InvalidStringException("initialValue is either null or 0");
}
this.value = initialValue;
}
#Override
public boolean hasMoreElements() {
return value.length() != 0 || value != null;
}
#Override
public String nextElement() {
StringBuffer test = new StringBuffer(value);
for (int i = 0; i < value.length(); i++) {
return test.charAt(i);
}
}
}
The easiest is to keep the index you're at as a variable in the enumeration:
// we return characters
public class StringEnumeration implements Enumeration<Character> {
// the value
private String value;
// current index
private int idx=0;
public StringEnumeration(String initialValue) throws IllegalArgumentException {
if (initialValue == null || initialValue.length() == 0) {
throw new IllegalArgumentException("initialValue is either null or 0");
}
this.value = initialValue;
}
#Override
public boolean hasMoreElements() {
// can we still read
return idx<value.length();
}
#Override
public Character nextElement() {
// get current char and increment index
return value.charAt(idx++);
}
}
Your implementation has several problems.
First, in Enumeration<E> the E is not the type the enumeration is working on. It's the type that the nextElement() method is supposed to return. So an Enumeration<String> has a nextElement() method that returns String. But your implementation returns the result of charAt() - a method that returns the primitive char, not a String! You either have to return some sort of string (maybe a single-char string like "m") or a Character (because you can't make E a primitive type like char).
The next problem is that your hasNextElement() method is not actually correct. An Enumeration is intended to give you one element (character, in your case) of the data at a time, and each time you call nextElement() it moves ahead towards the end of the data. so hasNextElement() has to return true based on whether or not there is still another element to go through. Your implementation, however, will always return true for the same string. It will not give an indication when to stop calling nextElement().
Last, your nextElement() somehow thinks that it's going to return all the elements at the same time. This cannot work. An Enumeration can only give one element each time you call nextElement(). So using a loop inside it makes no sense. The proper way to do this is to keep state inside the Enumeration object, say a variable named next, that indicates where the next element is. Each time the caller calls nextElement(), you take that element, advance next, and return the element. One element at a time, no loops. The actual loop will be created by whoever is using the Enumeration, not by the Enumeration itself.
It is also this next field (or whatever you want to call it) that can help you to create a proper hasMoreElements() method. If the next reaches beyond the end of the string, hasMoreElements() has to return false, and nextElement() has to throw NoSuchElementException.
I think what you intend to implement is an Iterator<T> over the characters of a given string:
public class StringEnumeration implements Iterator<Character> {
private final String value;
private int index = 0;
public StringEnumeration(String initialValue) {
if(initialValue == null) {
this.value = "";
} else {
this.value = initialValue;
}
}
#Override
public boolean hasNext() {
return index < value.length();
}
#Override
public Character next() {
try {
return test.charAt(this.index);
} finally {
this.index++;
}
}
#Override
public void remove() {
//can be done. Necessary?
}
}
(You can use an Enumeration<T> by simply replacing Iterator<Character> with Enumeration<Character>; and hasNext and next with hasMoreElements and nextElement and remove the remove method.
This iterator considers that the null String and the empty string "" contain both zero characters.
An iterator needs to store a state in the iteration process: the index of the character to enumerate. Initially the index is set to 0. After each item, the index is incremented.
Furthermore the test is simply whether the value has already reached the end of the String.
The main problem with your code is the following:
#Override
public String nextElement() {
StringBuffer test = new StringBuffer(value);
for (int i = 0; i < value.length(); i++) {
return test.charAt(i);
}
}
You use a for-loop but with a return statement. If you thus ask for the nextElement Java will start iterating and immediately return the first character. Furthermore this probably won't compile since the Java compiler can't figureout test has at least one element and thus it is possible that the for loop is never executed.
Other advice
Please always make fields private. By making fields public, a class can no longer guarantee the consistency of its state.
Furthermore Iterator is a modern version of Enumeration (although there is some discussion about this).
//know acess modifiers well...
private String value;
private Integer currentPosition;
public StringEnumeration(String initialValue) throws InvalidStringException {
if (initialValue == null || initialValue.length() == 0) {
throw new InvalidStringException("initialValue is either null or 0");
}
this.value = initialValue;
}
//you would return false when the list is empty OR the current position is
//past the end of the string
#Override
public boolean hasMoreElements() {
return value.length() != 0 || currentPosition < value.length();
}
//you would return the character at the current position
#Override
public char nextElement() {
return value.charAt(currentPosition++);
}

Java look at elements in queue

So I'm making a search algorithm. I'm using a queue to store all of my objects
This is how I initialised it
Queue<Node> queue = new LinkedList<Node>();
I want to compare a variable in each object and order to queue. My plan is to use a for loop to compare the first object with each of the other objects and whichever object has the lowest variable is sent to the front of the queue. Then move onto the next object and repeat the process. My issue is I'm not sure how to retrieve an object from the queue that isn't the first object in the queue....
You could do a for loop through the Queue:
for (Node n : queue) {
do stuff with n
}
However, you aren't going to be able to remove items from the middle of the queue. Might I suggest a structure like an ArrayList?
In my opinion the best way is to use PriorityQueue. You can specify implementation of Comparator interface that will impose how elements should be sorted inside of queue.
Here is an example:
Let's say that this is your Node class:
public class Node {
// this field will be used to sort in queue
private int value;
public Node(int value) {
this.value = value;
}
public int getValue() {
return value;
}
#Override
public String toString() {
return "My value is: " + value;
}
}
And here is example of adding Nodes into queue:
import java.util.PriorityQueue;
import java.util.Random;
public class QueueExample {
public static void main(String[] args) {
Random r = new Random();
// Priority queue with custom comparator
PriorityQueue<Node> queue = new PriorityQueue<Node>(10, new SampleNodeComparator());
// adding 100 nodes with random value
for(int i = 0; i < 100; ++i) {
queue.add( new Node(r.nextInt(1000)));
}
// nodes will be removed from queue in order given by comparator
while(queue.size() != 0) {
System.out.println(queue.remove());
}
}
}
And the most important part - implementation of our custom comparator
import java.util.Comparator;
// our comparator needs to implements Comparator interface
public class SampleNodeComparator implements Comparator<Node> {
#Override
public int compare(Node o1, Node o2) {
/*
value that should be return from compare method should follow rules:
if o1 == o2 - return 0
if o1 > o2 - return any positive value
if o1 < 02 - return any negative value
*/
return o1.getValue() - o2.getValue();
}
}
When you run main method from QueueExample class you will see on console that values are removed from queue sorted by Node.value value.
Use Queue<E>#peek () to retrieve an object without removing it.
Some example code:
import java.util.*;
class Example {
public static void main (String[] args) throws Exception {
Queue<String> list = new PriorityQueue<>();
{ // Initialize the Queue
list.add ("Hello ");
list.add ("Mrs. ");
list.add ("DoubtFire! ");
}
System.out.println (list);
// Iterating through the Queue
String element;
while ( (element = list.peek()) != null) {
if (element.equals ("Mrs. ")) {
System.out.println ("\"Mrs\" found!");
}
System.out.println (element);
list.remove (element);
}
System.out.println (list); // Empty by now...
}
}
Output:
[DoubtFire! , Mrs. , Hello ]
DoubtFire!
Hello
"Mrs" found!
Mrs.
[]
Queue interface does not guarantee any particular order while iterating or polling so theoretically this task is impossible to implement with Queue.
Seeing your response to my comment, I think that in your case, you should use the PriorityQueue because it does what you need without needing you to reinvent the wheel, which is usually not recommended.
By default, the priority queue will use the default implementation of the compareTo method. Assuming that you have a composite type, you have two options:
You can make your custom class implement the Comparabale interface and have your sorting logic there.
Alternatively, you could pass your own comparator:
PriorityQueue<..> p = new PriorityQueue<..>(5, new Comparator<..>()
{
#override
public int compare(.. type1, .. type2)
{
//comparison logic done here.
}
}
You can take a look at this short tutorial for more information.

Categories

Resources