I am trying to create hasnext() has next() methods for a iterator so that the output of a collection will be:
"printing","elements","in","order","from","collection"
input:
[A] - ["printing", "elements", "in"]
[B] - ["order"]
[C] - ["from", "collection"]
At the moment I have my methods looking like:
public MyIterator(Collection<Collection<Object>> myColl) {
_myColl = myColl;
}
public boolean hasNext() {
if(myColl.next != null)
{
return true
}
return !queue.isEmpty();
}
public Object next() throws java.util.NoSuchElementException {
//Dont really know what to put in here....
}
Any pointers would be appreciated
The best way to do is declare a counter and increment when you are accessing the has next. In the logic if i will express, then that will be like this.
private int counter = 0;
public boolean hasNext(){
counter = counter < collection.size()? counter + 1: counter;// increment
return counter < collection.size();// check and give the appropriate boolean value
}
public T next(){
return collection.get(counter);// to get the counter number of element
}
where counter is the private variable in the class and T is the generic type on which type of object the collection is build up. like
Collection<String>
This answer is all about logic. it may or may not contain the exact code.
Well, i don't understand your question really.. why you can't just use the normal iterator?
I will say to you how to create a basic iterator, to let you understand how things works in basic then adapt your solution:
Suppose we need to iterate over a List<T> and you want to create an helper class to do it.
class ListIterator<T>
You need two private fields
The list to iterate
The pointers to the last item
and 3 methods + 1 constructor
hasNext() -> Boolean, returns true if there are more items to iterate
next() -> Return the next element in the list
reset() -> Reset the interal pointer
constructor -> Just takes as argument the list to iterate
How will look the fields?
private final List<T> list; // The list where this call will iterate
private int pointer; // The pointer to the next iterable item
As said in the description, the constructor will take the reference to the list so it will just be
public ListIterator(List<T> list)
{
this.list = list;
pointer = 0;
}
save the reference and set pointer to 0 (start).
Let's talk about the methods:
hasNext should check if our current pointer has reached the size of the list.
So it will just be (pointer != list.size())
public boolean hasNext()
{
return (pointer != list.size());
}
Will be true if more items are avaitable, false otherwise.
next return the next item if any. Could be simplified by using our hasNext method so it will be
public T next()
{
if (!hasNext())
throw new NoSuchElementException("no field");
return list.get(pointer++);
}
Things to notice:
T is the return because our list is type T
list.get(pointer++) we first get the item from the list in position pointer then we add 1 to the pointer
The reset method is just a pointer = 0.
public void reset()
{
pointer = 0;
}
How to use it?
Like other iterators, create a new object of type ListIterator and pass the list to iterate.
List<String> test = new ArrayList<String>();
test.add("Hello");
test.add("World");
test.add("Whatsapp");
ListIterator<String> iterator = new ListIterator<String>(test);
while (iterator.hasNext())
{
System.out.println(iterator.next());
}
Related
I'm trying to iterate over an Object array. Using the next() method works so I'm guessing that my iterator class and constructors are working.
For some reason i'm not getting any output while the hasNext() method is running.
Iterator it = hej.iterator();
Object j = it.next();
System.out.println(j);
while(it.hasNext()){
Object i = it.next();
System.out.println(i + " ");
}
With "hej" being my Object array.
My code for the next(); and hasNext() methods are as follows:
public class StackIterator implements Iterator<Object>{
// fields
private int element = 0;
private final Object[] elements;
private final int max;
// constructor
public StackIterator(Object[] values, int maxIndex) {
elements = values;
max = maxIndex;
}
// methods
public boolean hasNext() {
return element < max;
}
public Object next() {
return elements[element++];
}
}
The file that constructs the Object Array and the Object Array depends on an interface:
public interface Stack {
int size();
boolean isEmpty();
void push(Object element);
Object pop();
Object peek();
Iterator<Object> iterator();
}
The methods are then explained in another file:
public class StackExample implements Stack {
// fields
int length = 0;
Object[] arr;
// constructor
public StackExample() {arr = new Object[length];}
// method returns size of object array
public int size() {
return arr.length;
}
// method checks if object is empty
public boolean isEmpty() {
boolean result = false;
if (arr.length == 0){
result = true;
}
return result;
}
// method for push
public void push(Object element) {
newBiggerObj();
arr[0] = element;
}
// returns the first object of the stack
public Object pop() {
Object[] temp = new Object[arr.length-1];
Object first = arr[0];
for (int i = 0; i<arr.length-1; i++){
temp[i] = arr[i+1];
}arr = temp;
return first;
}
// returns the object on top of stack
public Object peek() {
if (isEmpty()){
try{
throw new Exception("Stack empty, can't peek!");
}
catch(Exception e){
return e.getMessage();
}
}
else {
Object first = arr[0];
return first;
}
}
// method for push method
private void newBiggerObj(){
Object[] temp = new Object[arr.length+1];
for (int i = 0; i<arr.length; i++){
temp[i+1] = arr[i];
}
arr = temp;
}
public String toString(){
String str = "";
for (int i = 0; i < arr.length; i++){
str = str + arr[i] + " , ";
}return str;
}
public Iterator<Object> iterator() {
return new StackIterator(arr, length);
}
}
What bothers me is that the method Iterator is within itself returning an instance of the class Stack Iterator. Which i posted above. So my real problem seems to be that my fields are not being given any value, since I am not myself giving the any values within the constructor.
My main method in which I'm testing all of this is as follows:
public class Teststack {
public static void main(String[] args){
// new instane of class StackExample
StackExample hej = new StackExample();
// test for the different methods
System.out.println(hej.isEmpty());
System.out.println(hej.size());
hej.push(4);
hej.push("hej");
hej.push(6);
hej.push(5);
System.out.println(hej.size());
System.out.println(hej.peek());
System.out.println(hej.pop());
System.out.println(hej.toString());
System.out.println(hej.isEmpty());
System.out.println("Testing Iterator: ");
// test for iterator
Iterator it = hej.iterator();
Object j = it.next();
System.out.println(j);
while(it.hasNext()){
Object i = it.next();
System.out.println(i + " ");
}
}
}
In your StackExample class, I don't see the length variable being updated when elements are pushed or popped. Due to this, length will always be 0 and calls to it.hasNext() will always return false.
You don't need to pass the length as a separate argument. You can find the array's length in the StackIterator constructor and use it.
Also note that since you're creating a new array on every push and pop, the iterator returned by StackExample#iterator() will become stale after every push/pop since it will work on an old copy/state of the stack.
The problem is here:
public Iterator<Object> iterator() {
return new StackIterator(arr, length);
}
length field is never changed, so its value is always 0. You can change the code to this:
public Iterator<Object> iterator() {
return new StackIterator(arr, arr.length);
}
Also, before retrieving elements from the iterator, you should always call it.hasNext. The fact you did this:
Iterator it = hej.iterator();
Object j = it.next();
And worked was just pure luck.
Apart of this, I can sense you have a bad design on your stack implementation. Here are some hints to improve your code:
The inner array should be initialized with a default size different than 0. E.g. 10 (as done in java.util.ArrayList implementation).
You should avoid creating a new array when adding (push) or removing (pop) an element from your stack. Instead of this, you should use the length field to control how many elements are in your stack.
The value of the new size should be based on another formula rather than array.length + 1. For example, try using something like int newSize = array.length / 2 * 3;.
Resize the inner array only when necessary. When calling push, do it only if you precisely need to increase the size of the array. When calling pop, do it if the current length of the array (this is, array.length) is far greater than the value of length field of your class.
Never forget to update the value of length on push and pop methods.
Couple of issues:
You are calling Object j = it.next(); after creating iterator and then check for hasNext. You are incrementing the element index. Hence if you just have one element, you wont enter the while loop. In addition, if your custom datastructure is empty i.e. array has no elements then you are prone to ArrayIndexOutOfBoundException.
You will always iterate and print n-1 elements instead to n elements.
Once you iterated, then your pointer will always point to last element and never get resetted. So very next time you wont be able to iterate over your elements. Its a one time iterator.
Try not to call
Object j = it.next() statement, but just while cycle. Seems you have an array of just 1 element.
There are a number of problems with this code:
In the StackIterator constructor there is no bounds checking on maxIndex. Callers can pass in a number greater than values.length, less that 0, etc.
In the next method, there is no check of the end condition, either directly or by calling hasNext(). Callers can keep calling next() and see elements beyond max or even get an ArrayIndexOutOfBoundsException, when they should be getting a NoSuchElementException.
The Stack class never increments or decrements its length field when elements are pushed or popped.
The Stack class tracks the length separately from the array, even though it always resizes the array on every push or pop, but Java arrays already know their size. (But see the next item.)
The Stack class resizes the array on every push or pop, which is very inefficient. Typically classes like this only resize the array when necessary, allowing 'slack' space, to give amortized constant time performance (see ArrayList). If you do this, however, it is necessary to null out popped items to avoid unintentional object retention.
The Stack adds and removes elements at the beginning of the array. This is incredibly inefficient since it means a O(n) reshuffling must be done on every push or pop.
The peek() method takes into account the possibility that the Stack may be empty, but the pop() method does not. A pop() on an empty Stack will throw an ArrayIndexOutOfBoundsException.
Stack is not a generic class. It holds Object. Users of the Stack will have to cast the return values from peek() or pop(), and it isn't type safe. In your example, you show a stack that is a heterogeneous mixture of String and Integer. This is a very Java 1.2 way of doing things, and while it isn't necessarily wrong, you should consider parameterizing Stack.
I have a java object that implements the Iterable interface. This linked list has a group of objects that each hold a parameterized object (so it could be a String OR an ArrayList or whatever).
In the iterator() method, i create an Iterator object that takes an array of these parameterized items and return it.
However, when i use the following code:
//create an Iterable object named 'iterate'
for(String current : iterate){
//try to do some stuff with it... print it out?
}
//more code
//here is how i implemented the iterator function of my Iterable class:
public Iterator<Item> iterator(){
// return an iterator over items in order from front to end
Item[] items = (Item[]) new Object[numberOfItems];
QueueItem<Item> item = first;
for(int i=0;i<numberOfItems;i++){
items[i] = item.getInfo();
item = item.next;
}
return new myIterator(items);
}
//here is the code for the myIterator class. it is a private internal class
private class myIterator implements Iterator<Item>{
Item items[];
int index;
public myIterator(Item current[]){
items = current;
index = 0;
}
#Override
public boolean hasNext() {
if(items==null){
return false;
}
return (index>=items.length);
}
#Override
public Item next() {
if(index+1>=items.length){
throw new NoSuchElementException("There are no more elements!");
}
return items[index++];
}
#Override
public void remove() {
throw new UnsupportedOperationException("this operation is not supported");
}
}
the code goes to the for loop, then creates the Iterator object correctly (I used breakpoints to confirm), and returns it, but then the code jumps out of the for loop without going through it even once and continues....
Am i missing something? did i do something wrong here? how do i need to change the implementation of my Iterable object? is there some GOTCHA with implementing this that i'm not taking into account?
thanks!
in hasNext method you check if return (index>=items.length); Well this will return false. change operant to "<"
oh my gosh. so embarrassing. the hasNext method had the boolean statement reversed.
it should have been:
return (index<items.length); thanks anyways!
i've been pulling my hair out about this. i debugged everything else, then it dawned on me.
This is my first iterator implementation, so i figured it must have been something more fundamental that i wasn't doing correctly.
I am trying to delete an element from an array depending on the method's argument. If the argument is the last element's position, I can't use the for loop and end up specifying an if statement just to satisfy that. Also trying to return the current name in that position after the deletion. I have tested and the following code works.
I am trying to see if there is a better way of producing the same result without the extra if statement. I tried looking up the Arrays Class and no static method there that seems to help either. Please advice if there is a better way of doing this method. Thanks.
public class ArrayTester {
public static String[] array1 = new String[100];
public static void main(String[] args) {
remove(50);
System.out.println(remove(50));
}
public static String remove(int name) {
if(name == 99){
array1[name] = null;
return array1[name];
}
else if (name >= 0 && name < 99){
for (int i=name; i < array1.length-1; i++){
array1[i] = array1[i+1];
}
return array1[name];
}
return null;
}
}
And with ArrayList??
import java.util.ArrayList;
public class RemoveArrayListElement {
public static void main(String[] args) {
ArrayList<String> arlist=new ArrayList<String>();
//<E> it is return type of ArrayList
arlist.add("First Element"); // adding element in ArrayList
arlist.add("Second Element");
arlist.add("Third Element");
arlist.add("forth Element");
arlist.add("fifth Element");
// remove array list element by index number
arlist.remove(3);
// remove ArrayList element by Object value
arlist.remove("fifth Element");
// get elements of ArrayList
for(int i=0;i<arlist.size();i++)
{
System.out.println("ArrayList Element "+i+" :"+arlist.get(i));
}
}
}
Output:
Remove ArrayList Element 0 :First Element
Remove ArrayList Element 1 :Second Element
Remove ArrayList Element 2 :Third Element
With ArrayList is easier, isn't it?
You can simplify your code a little by excluding the if. Unfortunately, the loop has to stay - arrays provide contiguous storage, so you need to move the data if you are to delete an item in the middle of the array.
public static String remove(int index) {
// Note the use of "index" instead of "name"
if (index < 0 || index >= array1.length) {
// A more common approach is to throw an exception,
// but your code returns null for out-of-range index
return null;
}
for (int i = index; i < array1.length-1 ; i++) {
array1[i] = array1[i+1];
}
// Unconditionally set null in the last element of the array
array1[array1.length-1] = null;
return array1[index];
}
Looking at your code, you seem to want something like this -
if (name == 99) {
try {
return array1[name];
} finally {
array1[name] = null;
}
}
array1 = Arrays.copyOf(array1, 99);
Sounds to me like you would be better off using an ArrayList. Arrays aren't really made for what you're doing. But you could also just null the value at the desired location and run the java.util.Arrays.sort method on the array. Something like this (I'm winging it, but this would be close):
public static String remove(int name) {
String returnValue = array1[name];
array1[name] = null;
java.util.Arrays.sort(array1);
return returnValue;
}
This is going to leave you with a sorted array, but you're already shifting them out of their original indices anyway so that may or may not matter to you.
Another option would be to simply add a if (array1[index] != null) conditional to all of your code handling that array. That way you wouldn't have to shift your values around in the array and your code would just skip over any null values it runs into.
I have a LinkedList over which I need to iterate back and forth multiple times. I am using it to keep track of a series of pages in a workflow that will be created dynamically. This does not behave as I would expect. Given this example:
LinkedList<String> navigationCases;
navigationCases.add("page1");
navigationCases.add("page2");
navigationCases.add("page3");
navigationCases.add("page4");
ListIterator navigationItr = navigationCases.listIterator();
navigationItr.next(); // Returns page1
navigationItr.next(); // Returns page2
navigationItr.previous(); //Returns page2 again
navigationItr.next(); //Returns page2 again
I thought perhaps I was building my list incorrectly, or using the Iterator wrong, but after reading the documentation, this seems to be by design:
A ListIterator has no current element; its cursor position always lies between the element that would be returned by a call to previous() and the element that would be returned by a call to next().
And:
(Next) Returns the next element in the list. This method may be called repeatedly to iterate through the list, or intermixed with calls to previous to go back and forth. (Note that alternating calls to next and previous will return the same element repeatedly.)
So after reading this, it is clear why my code is behaving the way it does. I just don't understand why it should work this way. Even remove seems to be bending over backwards to accommodate this implementation:
Note that the remove() and set(Object) methods are not defined in terms of the cursor position; they are defined to operate on the last element returned by a call to next() or previous().
Conceptually, a LinkedList seemed to model my workflow cases pretty well, but I can't use an Iterator that behaves this way. Am I missing something here, or should I just write my own class maintain a list of cases and navigate through them?
This should do your job:
public class Main {
public static void main(String[] args) {
final LinkedList<String> list = new LinkedList<String> ();
list.add ("1"); list.add ("2"); list.add ("3"); list.add ("4");
final MyIterator<String> it = new MyIterator (list.listIterator());
System.out.println(it.next());
System.out.println(it.next ());
System.out.println(it.next ());
System.out.println(it.previous ());
System.out.println(it.previous ());
System.out.println(it.next ());
}
public static class MyIterator<T> {
private final ListIterator<T> listIterator;
private boolean nextWasCalled = false;
private boolean previousWasCalled = false;
public MyIterator(ListIterator<T> listIterator) {
this.listIterator = listIterator;
}
public T next() {
nextWasCalled = true;
if (previousWasCalled) {
previousWasCalled = false;
listIterator.next ();
}
return listIterator.next ();
}
public T previous() {
if (nextWasCalled) {
listIterator.previous();
nextWasCalled = false;
}
previousWasCalled = true;
return listIterator.previous();
}
}
}
And a fiddle for it.
ListIterator was designed to behave this way. See the conversation beneath ShyJ's answer for the rationale.
I find this behavior to be beyond idiotic, and have instead written a very simple alternative. Here's the Kotlin code with a extension function for ArrayLists:
class ListIterator<E>(var list: ArrayList<E>) : Iterator<E> {
private var cursor: Int = 0
fun replace(newList: ArrayList<E>) {
list = newList
cursor = 0
}
override fun hasNext(): Boolean {
return cursor + 1 < list.size
}
override fun next(): E {
cursor++
return current()
}
fun hasPrevious(): Boolean {
return 0 <= cursor - 1
}
fun previous(): E {
cursor--
return current()
}
fun current(): E {
return list[cursor]
}
}
fun <E> ArrayList<E>.listFlippingIterator() = ListIterator(this)
If you wish to include removal functionality, I highly recommend writing the API to explicitly instruct the iterator if it should remove left or right, e.g. by defining those methods as removeNext() and removePrevious().
Do something like this (pseudocode) --
class SkipIterator extends ListIterator {
public E previous(){
E n = super.previous();
return super.previous();
}
...
}
then:
LinkedList<String> navigationCases;
navigationCases.add("page1");
navigationCases.add("page2");
navigationCases.add("page3");
navigationCases.add("page4");
SkipIterator navigationItr = (SkipIterator)navigationCases.listIterator();
navigationItr.next(); // Returns page1
navigationItr.next(); // Returns page2
navigationItr.previous(); // Returns page1
Cheers
I have this code that is supposed to merge two instances of SortedLinkedList into one SLL (based on mergeSort merge), but is returning an empty list instead:
import java.util.LinkedList;
public class SortedLinkedList<T extends Comparable<? super T>>
extends LinkedList<T> {
private LinkedList<T> list; // the sorted list
// constructor, sorted with insertion sort
public SortedLinkedList(LinkedList<T> in)
{
if(in.peek() == null || in.size() == 1)
return;
else {
list = new LinkedList<T>();
for(T e : in)
list.add(e);
int i, j;
T temp;
for(i = 0; i < list.size(); i++){
j = i;
temp = list.get(j);
while(j > 0 && list.get(j-1).compareTo(temp) > 0){
list.set(j, list.get(j-1));
j--;
}
list.set(j, temp);
}
}
}
// return the union of the sorted linked lists this
// and other
public SortedLinkedList<T> makeUnion( SortedLinkedList<T> other)
{
list = new LinkedList<T>();
SortedLinkedList<T> temp = new SortedLinkedList<T>(list);
int i = 0, j = 0;
while(i < this.size() && j < other.size()){
if(this.get(i).compareTo(other.get(j)) <= 0){
temp.add(this.get(i));
i++;
}
else {
temp.add(other.get(j));
j++;
}
}
while(i < this.size()){
temp.add(this.get(i));
i++;
}
while(j < other.size()){
temp.add(other.get(j));
j++;
}
return temp;
}
// print the items in list
public void print()
{
for(T e : list)
System.out.println(e);
}
}
In the SLL constructor, I have it simply return on a null list (and the private variable, list, is initialized in the first line of this method). However from what I know, this should still give me an SLL object (initially also null). I can add to temp just fine in the method itself, but get a NullPointerException when printing the list.
I realize it's not very efficient to use get with LinkedList. I'll switch them with an iterator after I settle this.
Any hints would be quite appreciated.
EDIT: Interestingly, I get the same result if I put both lists in a temporary LL and then use the constructor on it. The types are compatible since SLL extends LL:
public SortedLinkedList<T> makeUnion( SortedLinkedList<T> other)
{
LinkedList<T> temp = new LinkedList<T>();
temp.addAll(this);
temp.addAll(other);
SortedLinkedList<T> merge = new SortedLinkedList(temp);
return merge;
}
EDIT2: It seems #Mead was correct... while size() and get() seem to work for the SLL, add() does not. I was thinking that since I'm extending LinkedList, it would work with the SLL as well. It didn't, and overriding them did nothing as well... I'm out of ideas for this. Suggestions?
Great! Your edit pretty much reveals your problem: you're not extending the LinkedList properly. Fix that, and then work on union.
The problem at hand: This is a class called SortedLinkedList. We can assume it's meant to be just like LinkedList, but the values in it are sorted. So, given that, this should work:
LinkedList<Integer> unsorted = new LinkedList<Integer>();
unsorted.add(200);
unsorted.add(100);
unsorted.add(300);
SortedLinkedList<Integer> sorted = new SortedLinkedList<Integer>(unsorted);
System.out.println(sorted.size());
for (Integer i : sorted) {
System.out.println(i);
}
// Should print out:
// 3
// 100
// 200
// 300
But it will not. Run your code, what does it print out?
Back? Why did it print out that? First, consider two variables you can use in the class's code: this refers to the SortedLinkedList object, and this.list refers to an instance variable inside that SortedLinkedList object. Then let's look at the constructor: when you add to the list, you're calling this.list.add(). What you have written makes SortedLinkedList a wrapper around the list instance variable - you're not adding to the SortedLinkedList (this) you are adding to a list inside that (this.list).
The only methods that use your this.list instance variable are the constructor, print, and makeUnion. All the other LinkedList methods aren't aware of the list variable, so when I call get():
LinkedList<Integer> unsorted = new LinkedList<Integer>();
unsorted.add(200);
unsorted.add(100);
unsorted.add(300);
SortedLinkedList<Integer> sorted = new SortedLinked<Integer>(unsorted);
System.out.println(sorted.get(0));
It doesn't know to look in your this.list variable, so it won't get 100 to print. In fact, it will crash because there is no value in index 0. You didn't add to the instance variables that get() actually uses, so the methods think that SortedLinkedList object is empty. this.list is a new variable that the inheritted methods don't know about.
So, if we examine your latest edit:
public SortedLinkedList<T> makeUnion( SortedLinkedList<T> other)
{
LinkedList<T> temp = new LinkedList<T>();
temp.addAll(this);
temp.addAll(other);
SortedLinkedList<T> merge = new SortedLinkedList(temp);
return merge;
}
temp.addAll(this) doesn't work, because all the methods of this think that the list is empty because they're not looking at this.list. temp.addAll(other) doesn't work either, for the same reason.
What is common when you extend classes is that you want the existing methods to continue working. This means that you need to store the data where get() and other methods expect it to be. How do you do that? Well, you're already doing it! You are already doing the right thing - but you are doing it on the instance variable this.list instead of this. Start calling this.add(), this.set(), this.size() instead of this.list.add() and remove the instance variable list completely - it's not needed, you have this. Then the data will be where the other methods expect it to be.
(And call super() on the first line of your constructor, so the code in the super class's constructor is called). Good luck on your homework - I'd recommend testing the object works as-is before adding new methods.
just curious after looking at the implementation, but couldn't you have just done a .addAll(...) followed by a Collections.sort(...)? That's what I would have preferred personally.