I am working on a Linked Lists assignment for my OOP class, and have run into some trouble with a remove method. Our professor has asked us to write a method:
public Object removeElement(int index)
This takes an index, which is the location of the element that needs removed. It must return the data the deleted node contained as well. However, I am having trouble with getting the method to return the object it is removing. For some reason I keep getting the error that the method must return a result of type object. I have it returning an object, and I've gone through trial and error in various spots with no success.
Here is my code:
public Object removeElement(int index)
{
ListIterator iterator = listIterator();
Object object;
//If the supplied index is less than zero, throw an exception.
if(index < 0)
{
IndexOutOfBoundsException ex = new IndexOutOfBoundsException();
throw ex;
}
else
{
for(int i = 0; i <= index; i++)
{
if(!iterator.hasNext())
{
IndexOutOfBoundsException ex = new IndexOutOfBoundsException();
throw ex;
}
else
{
if(i == index)
{
object = iterator.next();
iterator.remove();
return object;
}
else
{
iterator.next();
}
}
}
}
}
You have it returning an object if i == index. But the compiler doesn't know that the loop will actually always end at that point. It's looking at the bottom of the loop and thinking "What do we want to return if we get here?"
I would actually restructure your code to:
if (index < 0)
{
// No need for a separate variable
throw new IndexOutOfBoundsException();
}
// No need for an else block
ListIterator iterator = listIterator();
Object current = null;
for (int i = 0; i <= index; i++)
{
// Note: assuming you expose the size(), you could check this up front...
if(!iterator.hasNext())
{
throw new IndexOutOfBoundsException();
}
current = iterator.next();
}
iterator.remove();
return current;
Now you always call remove and return when you've called next() the given number of times, because that's when the loop will end other than via an exception.
Firstly do not use iterator from java LinkedList it is Doubly linked list , I think professor wants to see how you implement remove functionality for LikedList data structure.
Secondly make loop and condition where i+1 == index in this place, save current element for return like Node returnElement = curent.next; and make delete manipulation curent.next = curent.next.next;
Pls post listIterator() method implementation and the error message that you are getting.
Note:> You have to manage the size of the list using an class variable such as an integer. So you dont have check !iterator.hasNext(), instead compare index with current size.
Related
So my friend created a queue class which has an instance variable size = 0; and for the add method he uses.
But what will happen to index 0 in this case?
It will not have an elements declared to it since add starts from size++. Which is 1 starting position.
public void add(T data) {
if(size > elements.length) {
throw new QueueException("Queue is full");
}
elements[size++] = data;
}
size++ returns the size value before it gets incremented in the background. Because of that the elements[0] will be assigned. See Oracle Tutorial on incrementing.
The problem is with the last element. The code will attempt to assign elements[elements.length] which is above the array capacity. The guard should be:
if (size >= elements.length) {
throw new QueueException("Queue is full");
}
I'm having some issue with a part of my homework for CS. I need to write a Linked List in Java and then only iterate the odd numbers with an Iterator. Essentially, a forEach loop must iterate only through odd numbers.
So far I only have this in my LinkedList class:
public class Iterator implements java.util.Iterator<Integer> {
private Node nextNode;
public Iterator(){
nextNode = head_;
}
#Override
public boolean hasNext() {
return (nextNode != null);// && (nextNode.data_ % 2 != 0);
}
#Override
public Integer next() {
if (!hasNext()) throw new NoSuchElementException();
Integer data = nextNode.data_;
nextNode = nextNode.next_;
return data;
}
public void remove(){
throw new UnsupportedOperationException();
}
}
public Iterator iterator() {
return new Iterator();
}
If I uncomment && (nextNode.data_ % 2 != 0);, then only the first number ( which happens to be uneven) is printed. I've also tried to implement this in the next() method, but without success.
Please give me a tip what to try further.
//Later edit: I failed to mention that the linked list I want to filter consists of random numbers and is not sorted.
Your filter should be located inside your .next method, not .hasNext. This is simple logic: you iterate through whole list, and hasNext has to return true all times except when current element is the last one.
Edit: This should be the way to do it if you want only odd data points. I think we were assuming you wanted odd indexes to begin with.
#Override
public Integer next() {
//keep looking for an odd element as long as there is a next
while (hasNext()) {
//move to the next node
nextNode = nextNode.next_;
//check for an odd data point
if (nextNode.data_ % 2 == 1) {
//and return it
return data;
}
}
//no odd element was found
throw new NoSuchElementException();
}
We should look at the official documentation for Iterator.hasNext and Iterator.next
http://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html
For hasNext we read
Returns true if the iteration has more elements
The internal structure does not matter. So we have no choice, our implementation has to check the whole linked list till it finds either an odd element or the end of the list. Also note that a call of hasNext should not change your structure.
public boolean hasNext() {
Node tempNode = nextNode; // nextNode need to stay the same
while (tempNode != null){
if (tempNode .data_ % 2 != 0){
return true;
}
tempNode = tempNode._next;
}
// if we are here, we found no element that is odd
return false;
}
Now the next method is almost the same, this time we need to advance the internal nextNode. If we fail to do it, the caller will always get the same element.
public Integer next() {
while (nextNode != null){
int data = nextNode.data;
nextNode = nextNode.next_;
if (data % 2 != 0){
return data;
}
}
//no odd element was found
throw new NoSuchElementException();
}
You have to use nextnode.next_ twice in order to get only the odd numbers. This is because you want to skip nextnode.next_ because that would always be an even number if your current one is an odd number. Additionally, your hasnext needs to check two spaces ahead
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 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 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());
}