Stackoverflow exception that occurs through non-recursive function - java

I am relatively new to Java Generics and the following two Generic classes represent the Vertex and the Connector involved in Graph data structure.
Connector.java class
package ac.lk.iit.algorithmscomplexities.coursework2.datastructure;
public class Connector<E,F> {
private Vertex<E, F> start, end; // starting Vertex instance and ending Vertex instance of the Connector
private F element; // the data of generic type F to be held by the Vertex connector
private double value; // a descriptive value of the connector relative to other connectors depending on the scenario
/**
* a protected constructor which creates an instance of Connector class
* #param start starting Vertex instance of the Connector
* #param end ending Vertex instance of the Connector
* #param element data of generic type F to be held by the Vertex connector
* #param cost descriptive value of the connector relative to other connectors depending on the scenario
*/
protected Connector(Vertex<E,F> start, Vertex<E,F> end, F element, double cost) {
this.setStart(start);
this.setEnd(end);
this.setElement(element);
this.setValue(cost);
}
/**
* returns the starting Vertex instance of the Connector
* #return the starting Vertex instance of the Connector
*/
protected Vertex<E,F> getStart() {
return start;
}
/**
* sets the Vertex argument provided to the starting Vertex instance field of the Connector instance
* #param start the starting Vertex instance of the Connector
*/
private void setStart(Vertex<E,F> start) {
if(start != null) {
this.start = start;
}
}
/**
* returns the ending Vertex instance of the Connector
* #return the ending Vertex instance of the Connector
*/
protected Vertex<E,F> getEnd() {
return end;
}
/**
* sets the Vertex argument provided to the ending Vertex instance field of the Connector instance
* #param end the ending Vertex instance of the Connector
*/
private void setEnd(Vertex<E,F> end) {
if(end != null) {
this.end = end;
}
}
/**
* returns the data of generic type F held by the Vertex connector
* #return the data of generic type F held by the Vertex connector
*/
protected F getElement() {
return element;
}
/**
* sets the data of generic type F to the element instance field of the Vertex connector
* #param element data of generic type F to be held by the Vertex connector
*/
private void setElement(F element) {
if(element != null) {
this.element = element;
}
}
/**
* returns a descriptive value of the connector relative to other connectors depending on the scenario
* #return descriptive value of the connector relative to other connectors depending on the scenario
*/
protected double getValue() {
return value;
}
/**
* sets a descriptive value of the connector relative to other connectors depending on the scenario to value instance field of Connector instance
* #param value a descriptive value of the connector relative to other connectors depending on the scenario
*/
private void setValue(double value) {
if(value >= 0) {
this.value = value;
}
}
public String toString() {
return this.element.toString();
}
#SuppressWarnings("unchecked")
#Override
public boolean equals(Object object) {
if(object instanceof Connector) {
Connector<E,F> newConnector = (Connector<E, F>)object;
// since it is a directed graph the start, end of each connector and the data element should be unique
return ((this.getStart().equals(newConnector.getStart())) && (this.getEnd().equals(newConnector.getEnd())) && (this.getElement().equals(newConnector.getElement())));
}
else {
return false;
}
}
}
Vertex.java class
package ac.lk.iit.algorithmscomplexities.coursework2.datastructure;
import java.util.LinkedList;
public class Vertex<E,F> {
private int id; // a unique id value for each vertex created
private E dataElement; // data to be held within a vertex
private LinkedList<Connector<E, F>> pointers; // list of references to other Vertices connected
// keeps track of the number of vertices created during the runtime
protected static int NUMBER_OF_VERTICES = 0;
/**
* a protected constructor which creates an instance of Vertex class with the generic E argument provided
* #param element the element of generic type E to be assigned to dataElement instance field
*/
protected Vertex(E element) {
this.setId(Vertex.NUMBER_OF_VERTICES);
Vertex.NUMBER_OF_VERTICES++;
this.setDataElement(element);
this.pointers = new LinkedList<Connector<E, F>>();
}
/**
* returns the unique Integer id value of the Vertex instance
* #return the unique Integer id value of the Vertex instance
*/
protected int getId() {
return id;
}
/**
* sets the Integer argument provided to the id instance field of the Vertex instance
* #param id the Integer argument provided to be set to the id instance field of the Vertex instance
*/
private void setId(int id) {
if(!(id < 0)) {
this.id = id;
}
}
/**
* returns the content of the dataElement instance field of the Vertex instance
* #return the content of the dataElement instance field of the Vertex instance
*/
protected E getDataElement() {
return dataElement;
}
/**
* sets the argument of generic type E to the dataElement instance field of the Vertex instance
* #param dataElement the element of generic type E to be assigned to dataElement instance field
*/
protected void setDataElement(E dataElement) {
if(dataElement != null) {
this.dataElement = dataElement;
}
}
/**
* returns the list of Connector instances associated with a Vertex instance
* #return the list of Connector instances associated with a Vertex instance
*/
protected LinkedList<Connector<E, F>> getPointers() {
return pointers;
}
/**
* adds a new Connector instance starting from this Vertex and ending in the specified Vertex instance
* #param another the ending Vertex of the Connector
* #param element the data element of generic type F held by the Connector
* #param value the list of Connector instances associated with a Vertex instance
*/
protected void connectTo(Vertex<E,F> another, F element, double value) {
Connector<E,F> newConnector = new Connector<E,F>(this, another, element, value);
if(!(this.pointers.contains(newConnector))) {
this.pointers.add(newConnector);
}
LinkedList<Connector<E, F>> anotherList = another.getPointers();
if(!(anotherList.contains(newConnector))) {
anotherList.add(newConnector);
}
System.out.println("[this vertex]:" + this.pointers);
System.out.println("[that vertex]:" + another.pointers);
}
#SuppressWarnings("unchecked")
#Override
public boolean equals(Object object) {
if(object instanceof Vertex) {
Vertex<E,F> newVertex = (Vertex<E,F>) object;
if(this.pointers.size() != newVertex.getPointers().size()) {
return false;
}
if(!(this.getDataElement().equals(newVertex.getDataElement()))) {
return false;
}
for(int i = 0 ; i < this.pointers.size() ; i++) {
if(!(this.pointers.get(i).equals(newVertex.getPointers().get(i)))) {
return false;
}
}
}
else {
return false;
}
return true;
}
public static void main(String[] args) {
Vertex<String, String> vertex1 = new Vertex<String, String>("Chiranga");
Vertex<String, String> vertex2 = new Vertex<String, String>("Robin");
Vertex<String, String> vertex3 = new Vertex<String, String>("Sunethra");
Vertex<String, String> vertex4 = new Vertex<String, String>("Ananda");
vertex1.connectTo(vertex2, "John", 0);
//vertex1.connectTo(vertex3, "Mark", 0);
//vertex1.connectTo(vertex4, "Rob", 0);
vertex2.connectTo(vertex3, "James", 0);
vertex4.connectTo(vertex2, "John", 0);
vertex4.connectTo(vertex3, "Sean", 0);
//System.out.println(vertex1.equals(vertex4));
//System.out.println(vertex1.equals(vertex2));
}
}
The above classes give out a stackoverflowexception when executing the following code segment.
vertex4.connectTo(vertex3, "Sean", 0);
It is hardly possible to understand the real reason behind the above exception as I am not involving any recursive code sample and because it occurs when I make connections between certain Vertex instances only. Most of the code problems related to the above exception type speaks about recursion but the above one seems to be different.
Why do I always get the mentioned stackoverflow exception?
Please note that the above code sample involving main method was coded for testing purposes.

Your equals method...
When you do the contains method in connectTo it calls equals on the Connectors to ascertain whether the connector is in the list or not.
The equals method for Connector:
#SuppressWarnings("unchecked")
#Override
public boolean equals(Object object) {
if (object instanceof Connector) {
Connector<E, F> newConnector = (Connector<E, F>) object;
// since it is a directed graph the start, end of each connector and the data element should be unique
return ((this.getStart().equals(newConnector.getStart())) && (this.getEnd().equals(newConnector.getEnd())) && (this.getElement().equals(newConnector.getElement())));
} else {
return false;
}
}
Notice how it does equals comparision on getStart() - which is a Vertex. Then Vertex equals:
#SuppressWarnings("unchecked")
#Override
public boolean equals(Object object) {
if (object instanceof Vertex) {
Vertex<E, F> newVertex = (Vertex<E, F>) object;
if (this.pointers.size() != newVertex.getPointers().size()) {
return false;
}
if (!(this.getDataElement().equals(newVertex.getDataElement()))) {
return false;
}
for (int i = 0; i < this.pointers.size(); i++) {
if (!(this.pointers.get(i).equals(newVertex.getPointers().get(i)))) {
return false;
}
}
} else {
return false;
}
return true;
}
So Vertex Equals: calls equals on this.pointers (Connectors).
So in other words your equals methods have a cyclic dependency - they each call the other equals method and thus you get a stack overflow exception.

Looking at the stack trace, it's easy to understand where the problem is:
Exception in thread "main" java.lang.StackOverflowError
at ac.lk.iit.algorithmscomplexities.coursework2.datastructure.Connector.equals(Connector.java:123)
at ac.lk.iit.algorithmscomplexities.coursework2.datastructure.Vertex.equals(Vertex.java:117)
at ac.lk.iit.algorithmscomplexities.coursework2.datastructure.Connector.equals(Connector.java:123)
at ac.lk.iit.algorithmscomplexities.coursework2.datastructure.Vertex.equals(Vertex.java:117)
at ac.lk.iit.algorithmscomplexities.coursework2.datastructure.Connector.equals(Connector.java:123)
...
Your Connector equals method calls Vertex equals method, which calls Connector's equals methods,...

equals method of Vertex class contains :
if(!(this.pointers.get(i).equals(newVertex.getPointers().get(i))))
where this.pointers.get(i) is a Connector, so equals of Vertex calls equals of Connector.
equals of the Connector class contains :
return ((this.getStart().equals(newConnector.getStart())) && (this.getEnd().equals(newConnector.getEnd())) && (this.getElement().equals(newConnector.getElement())));
And since getStart() and getEnd() are of type Vertex, this means equals of Connector is calling equals of Vertex.
Therefore a call to equals of either Vertex or Connector may lead to infinite recursion.

Related

Very weird NPE when trying to copy an object

I'm trying to copy an object while passing in a parameter to the method I'm using to copy with. In the constructor for the object after I try to copy it the parameter becomes null.
This is the class that I'm trying to copy:
/**
* Represents the extra health perk
*/
public class ArrowRegen implements Perk
{
private int id = 0;
private double chance = 0.15;
private int level = 0;
private int price = 1000;
private int arrowGain = 0;
private GamePlayer ourPlayer;
public ArrowRegen(){}
public ArrowRegen(GamePlayer ourPlayer)
{
this.ourPlayer = ourPlayer;
if(this.ourPlayer == null)
aa.debug("its null");
}
#Override
public Perk getThisPerk(GamePlayer player)
{
aa.debug("returning an arrow regen");
if(player == null)
aa.debug("player is null? somehow?");
return new ArrowRegen(ourPlayer);
}
}
nothing is null up until the point in the constructor at the "its null" comment. *
This is where I call the copy from:
player.addActivePerks(PerkEngine.getPerk(1).getThisPerk(player));
(player is a GamePlayer object)
Here is the PerkEngine bit:
/**
* Gets a perk by it's ID
* #param id The Perk's ID
* #return The Perk with the specified ID
*/
public static Perk getPerk(int id)
{
for(Perk perk : perks)
{
if(perk.getID() == id)
{
return perk;
}
}
// This will never return null
return null;
}
EDIT:
I just realized my mistake was in the "getThisPerk" method. When returning the new object, I pass in the wrong variable.
I just realized my mistake was in the "getThisPerk" method. When returning the new object, I pass in the wrong variable.

Override method error

I am getting the following error when I'm compiling my code...
BSLinkedList.java:10: error: BSLinkedList is not abstract and does not override abstract method push(T) in BoundedStack
public class BSLinkedList <T> implements BoundedStack<T>{
^
where T is a type-variable:
T extends Object declared in class BSLinkedList
I have tried to make sure that everything I am using is generic type T. All of the questions I've found on this topic say that people have not implemented a method from the interface, however I have implemented the method push as well as all other methods from my interface! I appreciate any help or guidance anyone can supply! Thank you!
import java.util.EmptyStackException;
import java.util.*;
/**
* The class BSLinkedList implements the Stack ADT as described
* in cpsc331Stack using a linked list
*
* #version 1.0
*/
public class BSLinkedList <T> implements BoundedStack<T>{
public class StackNode<T> {
private T value;
public StackNode<T> next;
private int capacity;
public StackNode<T> top;
private int size;
public StackNode(T x, StackNode<T> n){
value = x;
next = n;
}
public void BSLinkedList(int capacity) {
assert capacity >= 0;
LinkedList<T> stack = new LinkedList<T>();
size = 0;
top = (StackNode<T>)null;
}
public boolean isEmpty(){
assert size >= 0;
if (size == 0){
return true;
}
else{
return false;
}
}
public boolean isFull(){
if (size == capacity){
return true;
}
else{
return false;
}
}
public int capacity(){
return capacity;
}
public int size(){
return size;
}
public void push(T x) {
if (isFull()){
throw new FullStackException();
}
else{
++size;
top = new StackNode<T>(x, top);
}
}
public T top(){
if(isEmpty()){
throw new EmptyStackException();
}
else{
return top.value;
}
}
public T pop(){
if (isEmpty()){
throw new EmptyStackException();
}
else{
T e = top.value;
top = top.next;
--size;
return e;
}
}
}
}
and the interface...
/**
* The BoundedStack interface represents the Bounded Stack ADT as described in CPSC 331.
* This interface extends the interface cpsc331Stack.
*
* #version 1.0
*/
public interface BoundedStack<T> extends cpsc331Stack<T>{
/**
* Returns the number of elements currently on the stack.
*
* #return the number of elements on the stack
*/
public int size();
/**
* Returns the maximum number of elements the stack can store.
*
* #return the maximum number of elements the stack can store
*/
public int capacity();
/**
* Tests whether the stack is full.
*
* #return true if number of elements in the stack is equal to
* the stack's capacity, false otherwise
*/
public boolean isFull();
/**
* Pushes the object x onto the top of the stack.
*
* #param x object to be pushed onto the stack.
* #throws FullStackException if the stack is full
*/
public void push (T x);
}
Other implementation that is working correctly...
import java.util.EmptyStackException;
/**
* The class BSArray implements the Stack ADT as described
* in cpsc331Stack using an array
*
* #version 1.0
*/
public class BSArray <T> implements BoundedStack<T>{
private T[] stack;
private int size;
private int top = -1;;
private int capacity;
/**
* Creates a new BSArray of size capacity
*
* #param capacity integer value of the maximum number of elements the array can store
*/
public BSArray(int capacity) {
assert capacity >= 0;
stack = (T[]) new Object[capacity];
}
/**
* Tests whether or not the stack is empty.
*
* #return true if the stack is empty, false otherwise
*/
public boolean isEmpty(){
if (size >= 0){
return true;
}
else{
return false;
}
}
/**
* Tests whether or not the stack is full.
*
* #return true if number of elements in the stack is equal to
* the stack's capacity, false otherwise
*/
public boolean isFull(){
if (size == capacity){
return true;
}
else{
return false;
}
}
/**
* Returns the maximum number of elements the stack can store.
*
* #return the maximum number of elements the stack can store
*/
public int capacity(){
return capacity;
}
/**
* Returns the number of elements currently on the stack.
*
* #return the number of elements on the stack
*/
public int size(){
return size;
}
/**
* Pushes the object x onto the top of the stack.
*
* #param x object to be pushed onto the stack.
* #throws FullStackException if the stack is full
*/
public void push(T x){
if (isFull()){
throw new FullStackException();
}
else{
++top;
++size;
stack[top] = x;
}
}
/**
* Returns the object at the top of the stack.
*
* #return reference to the item at the top of the stack
* #throws EmptyStackException if the stack is empty
*/
public T top(){
if(isEmpty()){
throw new EmptyStackException();
}
else{
return (T) stack[top];
}
}
/**
* Removes and returns the object at the top of the stack.
*
* #return reference to the item at the top of the stack
* #throws EmptyStackException if the stack is empty
*/
public T pop(){
if (isEmpty()){
throw new EmptyStackException();
}
else{
assert top >= -1;
T e = stack[top];
stack[top] = null;
--top;
--size;
return e;
}
}
}
cpsc331Stack interface
/**
* The cpsc331Stack interface represents the Stack ADT as described
* in CPSC 331.
*
* #version 1.0
*/
public interface cpsc331Stack<T> {
/**
* Tests whether the stack is empty.
*
* #return true if the stack is empty, false otherwise
*/
public boolean isEmpty();
/**
* Pushes the object x onto the top of the stack.
*
* #param x object to be pushed onto the stack.
*/
public void push(T x);
/**
* Returns the object at the top of the stack.
*
* #return reference to the item at the top of the stack
* #throws EmptyStackException if the stack is empty
*/
public T top();
/**
* Removes and returns the object at the top of the stack.
*
* #return reference to the item at the top of the stack
* #throws EmptyStackException if the stack is empty
*/
public T pop();
}
This is a bit speculative, but I believe the problem you are seeing is because your push() method does not actually override the exact signature you specified in your interface. You have this:
public void push(T x) throws FullStackException { }
but the interface has this:
public void push (T x);
For a quick fix, you can update the interface to throw the FullStackException.
By the way, the error you are seeing is a standard Java 101 error which occurs when you extend an abstract class without overriding all the abstract methods contained within that class. So your compiler thinks that there is an abstract method push() out there which you never overrode (even though you did, at least functionally speaking).
You have implemented the methods in the StackNode inner class but it is the outer class BSLinkedList which implements the interface.
In addition, as mentioned in the previous answer the push method declares an exception that is not in the interface method signature. This will result in an different error when you fix other issue.
**Edit in your second example you are have correctly implemented the methods in the class that implements the interface (you do not have the inner class).
Is this what you are trying to achieve?
/**
* The class BSLinkedList implements the Stack ADT as described
* in cpsc331Stack using a linked list
*
* #version 1.0
*/
public class BSLinkedList<T> implements BoundedStack<T> {
private int capacity;
public StackNode<T> top;
private int size;
public void BSLinkedList(int capacity) {
assert capacity >= 0;
LinkedList<T> stack = new LinkedList<T>();
size = 0;
top = null;
}
public boolean isEmpty() {
assert size >= 0;
if (size == 0) {
return true;
} else {
return false;
}
}
public boolean isFull() {
if (size == capacity) {
return true;
} else {
return false;
}
}
public int capacity() {
return capacity;
}
public int size() {
return size;
}
#Override
public void push(T x) {
if (isFull()) {
throw new FullStackException();
} else {
++size;
top = new StackNode<T>(x, top);
}
}
public T top() {
if (isEmpty()) {
throw new EmptyStackException();
} else {
return top.value;
}
}
public T pop() {
if (isEmpty()) {
throw new EmptyStackException();
} else {
T e = top.value;
top = top.next;
--size;
return e;
}
}
public class StackNode<T> {
private T value;
public StackNode<T> next;
public StackNode(T x, StackNode<T> n) {
value = x;
next = n;
}
}
}
Your method signature should match exactly with the method it is overriding. So, either remove the throws Exception from push method of BSLinkedList class or add the throws exception in the push method of BoundedStack interface.
Moreover, your class overrides all the methods of the BoundedStack interface. However, there may be certain methods which are defined in cpsc331Stack which you have to implement in your class.
Kindly post the source code of cpsc331Stack interface here so that we can help you better
You have actually defined the methods size(),capacity(),isFull(),push() inside the innerclass "StackNode" which is defined inside "BSLinkedList".If that is what you were actually intending,then "StackNode" class should implement "BoundedStack" instead of "BSLinkedList" implementing "BoundStack",else the method should be defined inside "BSLinkedList".
`class BSLinkedList <T>{
public class StackNode<T> implements BoundedStack<T>{
private T value;
public StackNode<T> next;
private int capacity;
public StackNode<T> top;
private int size;
public StackNode(T x, StackNode<T> n){
value = x;
next = n;
}
public void BSLinkedList(int capacity) {
assert capacity >= 0;
LinkedList<T> stack = new LinkedList<T>();
size = 0;
top = (StackNode<T>)null;
}
public boolean isEmpty(){
assert size >= 0;
if (size == 0){
return true;
}
else{
return false;
}
}
#Override
public boolean isFull(){
if (size == capacity){
return true;
}
else{
return false;
}
}
#Override
public int capacity(){
return capacity;
}
#Override
public int size(){
return size;
}
#Override
public void push(T x) {
if (isFull()){
throw new FullStackException();
}
else{
++size;
top = new StackNode<T>(x, top);
}
}
public T top(){
if(isEmpty()){
throw new EmptyStackException();
}
else{
return top.value;
}
}
public T pop(){
if (isEmpty()){
throw new EmptyStackException();
}
else{
T e = top.value;
top = top.next;
--size;
return e;
}
}
}
}`

Cannot sort an array list using Collections.sort after implementing Comparable

As the title suggests, I am trying to Sort my ArrayList of objects, and those objects have implemented comparable and have overriden CompareTo
However when I got to sort my arraylist i get this error
I can't seem to understand why I am getting this problem? Can anybody help?
ItemList Class:
package stories.cs2800;
import java.util.ArrayList;
import java.util.Collections;
import javax.swing.AbstractListModel;
#SuppressWarnings("serial")
public class ItemList extends AbstractListModel<Item> {
private ArrayList<Item> items;
/**
* Constructor that initializes the array list.
*/
public ItemList() {
items = new ArrayList<Item>();
}
#Override
public int getSize() {
return items.size();
}
/**
* Method to get item based on the index.
* #param argIndex - Takes parameter of type int.
* #return Returns item at the index.
*/
#Override
public Item getElementAt(int argIndex) throws IndexOutOfBoundsException {
if (argIndex < 0 || argIndex >= items.size()) {
throw new IndexOutOfBoundsException();
}
return items.get(argIndex);
}
/**
* Method that gets and Item element based on the name.
*
* #param argName - takes parameter of type String.
* #return Returns the entire item object if name matches, else null.
*/
public Item getElementByName(String argName) {
for (Item i : items) {
if (i.getName().equals(argName)) {
return i;
}
}
return null;
}
/**
* Method to add another Item into the array list.
* #param Takes parameter of type item.
* #see ArrayList#add
*/
public void add(Item next) {
items.add(next);
Collections.sort(items);
}
/**
* Boolean method to check if list contains the item of type Item.
*
* #param Takes parameter of type item.
* #return returns boolean value of true or false if item is contained.
*/
public Boolean contains(Item argItem) {
return items.contains(argItem);
}
/**
* Boolean method remove to remove item of type Item from list.
*
* #param Takes parameter of type Item.
* #return returns boolean value of true or false if item is removed.
*/
public Boolean remove(Item argItem) {
return items.remove(argItem);
}
/**
* Boolean method that removes and item based on its index.
*
* #argIndex Takes a parameter of type int.
* #return returns boolean value of true or false if item was removed based on index.
*/
public Boolean remove(int argIndex) throws IndexOutOfBoundsException {
if (argIndex < 0 || argIndex >= items.size()) {
throw new IndexOutOfBoundsException();
}
return items.remove(items.get(argIndex));
}
/**
* Method to find the index of an item object.
*
* #param Takes parameter of type Item.
* #return Returns item index based on the item object entered.
*/
public int indexOf(Item argItem) {
return items.indexOf(argItem);
}
/**
* Method to check if item changed.
*
* #param Takes parameter of type Item.
*/
public void changed(Item argItem) {
fireContentsChanged(this, items.indexOf(items), items.indexOf(items));
/*Method called when one or more items have changed */
}
}
SingleItem Class:
package stories.cs2800
public class SingleItem implements Comparable<Item>, Item {
private String name;
private float value;
private Item child;
/**
* Constructor for the SingleItem object.
*
* #param argName Stores the name that is set in constructor
* #param argValue Stores the float value that is set in Constructor
* #param argChild Stores the value of the child element
*/
public SingleItem(String argName, float argValue, Item argChild) {
name = argName;
value = argValue;
child = argChild;
}
/**
* Getter method to get the value of the name variable.
*
* #return returns the name
*/
#Override
public String getName() {
return this.name;
}
/**
* Getter method to get the value of the Float variable.
*
* #return value set in the value variable
*
*/
#Override
public Float getValue() {
return this.value;
}
/**
* Setter method to set the value of the Float - No return type.
* #param argFloat - Takes parameter of type Float using Wrapper class.
*/
#Override
public void setValue(Float argFloat) {
this.value = argFloat;
}
/**
* Method to get the description.
*
* #return Returns the a string with the description
*/
#Override
public String getDescription() {
return "Single items have no description";
}
/**
* Getter method for child element.
*
* #return returns the value of child element
*/
public Item getChild() {
return this.child;
}
/**
* Method for adding items.
* #param child - Takes parameter of type Item.
* #return Returns Exception when child is null.
*
*/
#Override
public void add(Item child) {
if (this.child != null) {
throw new IllegalStateException();
}
this.child = child;
}
/**
* Method for ItemVisitor.
* #param argVisitor - Takes parameter of ItemVisitor to add current class.
* #return Currently no valid method!.
*
*/
#Override
public <T> void accept(ItemVisitor<T> argVisitor) {
argVisitor.add(this);
}
/**
* Method that takes Boolean as a parameter.
* #param argBool - Takes parameter of type boolean.
* #return Returns exception.
*/
#Override
public void open(boolean argBool) throws IllegalStateException {
throw new IllegalStateException();
}
/**
* Method that compares name to name entered as a parameter.
* #param item - Takes parameter of type item.
* #return Returns an int based on comparison of name. E.g. 0 = same, 1 = different.
*/
#Override
public int compareTo(Item item) {
return this.name.compareTo(item.getName());
}
/**
* Method to check if Open.
*
* #return Always returns true.
*/
#Override
public boolean isOpen() {
return true;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
SingleItem other = (SingleItem) obj;
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
return true;
}
/**
* toString method to get values of elements.
*
* #return Returns a sentence with the values of all elements.
*/
#Override
public String toString() {
return "Name: " + getName() + ", Value: " + getValue()
+ ", Description: "
+ getDescription();
}
}
In short, Item doesn't implement Comparable. And the list is a list of Item.
Details here. In the code above, items = new ArrayList<Item>();. Which means compiler only knows that in list items, the type is Item. So when invoke Collections.sort(items), java compiler found Item doesn't implement Comparable. And there will be an error as shown at the beginning.
How to fix? Change definition of Item, make it implement Comparable.
So as you can see, there is nothing about SingleItem. Because it is the impl and items sees only interface Item.

Trying to get this linked list started

Second programming class
So we have been tasked with a linked list, building each method from scratch.
Well I started on this day before yesterday and had a null pointer exception, I figured id iron it out later and continued.
Well after cutting my program down to nothing to find the culprit im left with code that SHOULD work as its copied from our lab (that worked).
If you guys think you can figure out why im getting a null pointer exception on my add method id greatly appreciate it and see if im doing the second constructor correctly. If I can get SOME traction on this to get started it would go allot easier but as is I cant even begin.
You will notice allot of blank methods, ill get to them once I can get my constructor + add method working
My code:
import java.util.Collection;
import java.util.Iterator;
/**
* Created by hhhh on 11/2/2014.
*/
public class Lset<R> implements Set151Interface<R> {
private Node head;
private int length;
/**In the first (following) constructor im trying to re use code and call my clear method.
*Should save space and make code look cleaner.
*/
public Lset(){
clear();
}
public Lset(Collection<? extends R> list){
this();
for (R object : list) {
add(object);
}
}
/**
* Copied from Lab7, this add method checks to see if there are more nodes than just the head.
* After the check if false, creates a new node and adds it to the end of the list.
* #param entry
* #return
*/
#Override
public boolean add(R entry) {
Node newNode = new Node(entry);
// empty list is handled differently from a non-empty list
if (head.next == null) {
head = newNode;
} else {
Node lastNode = getNodeAt(length - 1);
lastNode.next = newNode;
}
length++;
return true;
}
#Override
public void clear() {
this.length = 0;
this.head = null;
}
#Override
public boolean contains(Object o) {
return false;
}
#Override
public Iterator<R> iterator() {
return null;
}
#Override
public boolean containsAll(Collection<?> c) {
return false;
}
#Override
public boolean isEmpty() {
return false;
}
#Override
public boolean remove(Object o) {
return false;
}
#Override
public boolean addAll(Collection<? extends R> c) {
return false;
}
#Override
public boolean removeAll(Collection<?> c) {
return false;
}
#Override
public boolean retainAll(Collection<?> c) {
return false;
}
#Override
public int size() {
return length;
}
#Override
public Object[] toArray() {
return null;
}
#Override
public <T> T[] toArray(T[] array) {
return null;
}
/**
* Code used in Lab 7, getNodeAt uses the length field and starts at head to traverse array and arrive at the
* position desired.
* #param position
* #return
*/
private Node getNodeAt(int position) {
assert !isEmpty() && (position >= 0) && position < length;
Node cNode = head;
for (int i = 0; i < position; i++)
cNode = cNode.next;
assert cNode != null;
return cNode;
}
public String toString(){
String arrayString = "<";
for(int i = 0; i < length; i++){
String two = getNodeAt(i).toString();
arrayString += two;
if(i <= (length - 2)){
two = ", ";
arrayString += two;
}
}
arrayString += ">";
return arrayString;
}
//TODO comment better
public class Node {
/** Reference to the data */
public R data;
/** Reference to the next node is in the list */
public Node next;
/**
* Sets the data for this node.
* #param data data to be carried by this node.
*/
public Node(R data) {
this.data = data;
this.next = null;
}
/**
* Sets the data for the node and assigns the next node in the list.
* #param data data to be carried by this node.
* #param nextNode next node in the list.
*/
public Node(R data, Node nextNode) {
this.data = data;
this.next = nextNode;
}
/**
* Returns just the data portion of the node.
* #return The data portion of the node.
*/
public R getData() {
return this.data;
}
/**
* Modified just the data portion of the node.
* #param data new data to be contained within the node.
*/
public void setData(R data) {
this.data = data;
}
/**
* What node does this node point to.
* #return the node that this node points to or null if it does not
* point anywhere.
*/
public Node getNextNode() {
return this.next;
}
/**
* Change the node that this node points to.
* #param nextNode a new node for this node to point to.
*/
public void setNextNode(Node nextNode) {
this.next = nextNode;
}
/**
* Display the state of just the data portion of the node.
*/
public String toString() {
return this.data.toString();
}
}
}
This is the method in main thats killing it
private void testConstruction() {
System.out.println("\nTesting Constructor");
System.out.print("----------------------------------------");
System.out.println("----------------------------------------");
Set151Interface s = makeSet();
//added
s.add("Butterfinger");
test(s.size() == 0,
"size() should return 0: " + s.size());
test(s.toString().equals("<>"),
"toString returns \"<>\": " + s.toString());
ArrayList<String> temp = new ArrayList<String>();
temp.add("Butterfinger");
temp.add("Milky Way");
temp.add("Kit Kat");
temp.add("Three Muskateers");
Set151Interface s3 = makeSet(temp);
test(s3.size() == 4,
"size should return 4: " + s3.size());
test(s3.toString().equals("<Butterfinger, Milky Way, Kit Kat, Three Muskateers>"),
"toString should return\n "+
"\"<Butterfinger, Milky Way, Kit Kat, Three Muskateers>\":\n "
+ s3.toString());
}
as soon as butterfinger attempts to get added I get null pointer exception pointing to this line
if (head.next == null) {
You just declared private Node head; and it doesnt takes any value assigned . so the compiler throws NPE
Thanks for the help guys, I figured it out :).
On day one I had edited my driver (and forgot) once I re copied the driver everything works (so far) thanks again guys!

How do I call methods from a class with an arraylist to another class?

I'm in my first semester of Java and I need help in calling methods from the VotingMachine class below to the Candidate Class. The Voting Machine class is compiling properly. Thank you all for any help you can provide....
Mercedes
import java.util.ArrayList;
/**
* These are the fields for the Voting Machine Class.
*/
public class VotingMachine
{
private ArrayList<String> candidateList;
/**
* The following constructor will establish the Candidate List
*/
public VotingMachine()
{
candidateList = new ArrayList<String>();
}
/**
* This constructor will store the Candidates for the Candidate List
*/
public void setCandidateList()
{
candidateList.add("Darnell Woffard");
candidateList.add("Barack Obama");
candidateList.add("Hillary Clinton");
}
/**
* This method will display the entire Candidate List.
*/
public void printCandidateInfo()
{
for (int index=0; index < candidateList.size(); index++)
{
System.out.println(candidateList.get(index));
}
}
/**
* Method to the number of Candidates in the CandidateList Arraylist.
*/
public int getNumberofFiles()
{
return candidateList.size();
}
/**
* Method to select one candidate by first providing an index number.
*/
public void listFile(int index)
{
if(index >= 0 && index < candidateList.size()){
String filename = candidateList.get(index);
System.out.println(filename);
}
}
/**
* This method will enable a user to remove a candidate.
*/
public void removeFile(int index)
{
if(index >= 0 && index < candidateList.size()){
candidateList.remove(index);
}
}
/**
* This method will add a file to the Candidate List.
*
*/
public void addCandidate(String filename)
{
candidateList.add(filename);
}
//----------
//The Candidate Class:
public class Candidate{
private String name;
private char party;
private String candidateList;
// Add fields
/**
* Fields
* name - Candidate's name, stored in a String
* party - Candidate's political party, stored in a char
* as 'r' for Republican, 'd' for Democrat, and 'i' for Independent
*/
/**
* Constructor
*
* #param anyName - caller inputs Candidate name
* #param anyParty - caller inputs Candidate's party affiliation
* stored as a char
* chars are assigned with single quotes.
*/
public Candidate(String anyName, char anyParty)
{
name = anyName;
party = anyParty;
}
/**
* The method will enable method calls from the Voting Machine Class.
*/
public void main(String candidateList)
{
VotingMachine votingMachine = new VotingMachine();
}
/**
* This method will define the candidates party affiliation.
* public char setParty()
*/
//Complete the three methods and their comments.
/**
* Method to retrieve the Candidate's name for the caller.
* public String getName(String anyName)
*
*/
/**
* Method to retrieve the Candidate's party for the caller.
*
* #return
*/
/**
* Method to change the Candidate's party
*
* #param
*/
Actually what i got from this is you are trying to make a voting machine. VotingMachine is the main class here having info of different candidates. so we will make object of candidate in votingMachine class. Note: when we are supposed to make a java project, figure out what is it main class and subclass that means which depends on which. in the above example There is association in the classes. First of all declare an ArrayList for storing objects of candidate class. as shown below.
private ArrayList<candidate> candidateList;
/**
* The following constructor will establish the Candidate List
*/
public VotingMachine()
{
candidateList = new ArrayList<String>();
}
now for adding new candidate in the ArrayList I have modified your method
setCandidate()
as
public void addNewCandidate(String name, char partySymbol)
{
candidate candid = new candidate(name, partySymbol);// this will call the candidate constructor
candidateList.add(candid);//add that object in ArrayList
}
As ArrayList stores references of objects, the built-in function int get(int index) will return the reference of the object. to print the info of that object or you can say values, we should define a function as getName() and getParty(). instead of this System.out.println(candidateList.get(index)); you should call System.out.println(candidateList.get(index).getName()); and System.out.println(candidateList.get(index).getParty());in the following method
public void printCandidateInfo()
{
for (int index=0; index < candidateList.size(); index++)
{
System.out.println(candidateList.get(index));
}
}
so define functions in candidate class as
public String getName()
{
return name;
}
/**
* Method to retrieve the Candidate's party for the caller.
*
* #return
*/
public char getParty()
{
return party;
}
the following method will print the reference not the info of candidate, so modify it as described above
public void listFile(int index)
{
if(index >= 0 && index < candidateList.size()){
String filename = candidateList.get(index);
System.out.println(filename);
}
}
as i have modified it,
import java.util.ArrayList;
/**
* These are the fields for the Voting Machine Class.
*/
public class VotingMachine
{
private ArrayList<Candidate> candidateList;
/**
* The following constructor will establish the Candidate List
*/
public VotingMachine()
{
candidateList = new ArrayList<>();
}
/**
* This method will store the Candidates for the Candidate List
*/
public void addNewCandidate(String name, char partySymbol)
{
Candidate candid = new Candidate(name, partySymbol);// this will call the candidate constructor
candidateList.add(candid);//add that object in ArrayList
}
/**
* This method will display the entire Candidate List.
*/
public void printCandidateInfo()
{
for (int index=0; index < candidateList.size(); index++)
{
System.out.print(candidateList.get(index).getName());
System.out.println(" " + candidateList.get(index).getParty());
}
}
/**
* Method to the number of Candidates in the CandidateList Arraylist.
*/
public int getNumberofFiles()
{
return candidateList.size();
}
/**
* Method to select one candidate by first providing an index number.
*/
public void listFile(int index)
{
System.out.print(candidateList.get(index).getName());
System.out.println(" " + candidateList.get(index).getParty());
}
/**
* This method will enable a user to remove a candidate.
*/
public void removeFile(int index)
{
if(index >= 0 && index < candidateList.size()){
candidateList.remove(index);
}
}
}
in candidate class i have just added the above mentioned getName() and getParty() methods..
regards

Categories