So I have a class:
public static class AVLTreeNode <E extends Comparable<E>> extends BST.TreeNode<E> {
protected int height;
public AVLTreeNode(E e) {
super(e);
}
}
That extends another class:
public static class TreeNode<E extends Comparable<E>> {
protected E element;
protected TreeNode<E> left;
protected TreeNode<E> right;
public TreeNode(E e) {
element = e;
}
}
And I am creating an ArrayList of type TreeNode, and trying to cast it to AVLTreeNode:
public void balancePath(E e) {
ArrayList<TreeNode<E>> path = path(e);
for (int i = path.size() - 1; i >= 0; i--) {
AVLTreeNode<E> a = (AVLTreeNode<E>)(path.get(i));
//continued code not important...
Note that my path method returns an ArrayList of type TreeNode<E>. But when I try to cast the node that I get at position i in the list to AVLTreeNode<E> (a subtype of TreeNode) I get a ClassCastException.
What is the problem here?
Edit Here is the full stack trace
Exception in thread "main" java.lang.ClassCastException: com.jeffsite.chapter27.BinarySearchTree$TreeNode cannot be cast to com.jeffsite.chapter29.AVLTree$AVLTreeNode
at com.jeffsite.chapter29.AVLTree.balancePath(AVLTree.java:102)
at com.jeffsite.chapter29.AVLTree.insert(AVLTree.java:19)
at com.jeffsite.chapter29.TestAVLTree.main(TestAVLTree.java:10)
It isn't a safe thing to cast because it is true that every AVLTreeNode is a TreeNode, but it is not necessarily true that every TreeNode is a AVLTreeNode. You could your List only hold AVLTreeNode(s), by changing from
ArrayList<TreeNode<E>> path = path(e);
to
List<AVLTreeNode<E>> path = path(e);
But I you should program to an interface (that's why List instead of ArrayList), so I think you really want
List<TreeNode<E>> path = path(e);
and then you can use
TreeNode<E> a = path.get(i);
And if you must know
if (a instanceof AVLTreeNode) {
// now you can cast a
AVLTreeNode<E> b = (AVLTreeNode<E>) a;
}
It depends on the what path returns. If the the path method/func returns a List of TreeNode then the conversion is not possible as the AVLTreeNode has extra params involved.
You can create the ArrayList or List of AVLTreeNode which should help solve the problem at hand (Only in the case path (method) returns the same).
ArrayList<AVLTreeNode<E>> path = path(e);
Can you show the path method, this dummy method works:
public ArrayList<? extends TreeNode<E>> path(E e) {
AVLTreeNode<E> tn = new AVLTreeNode<E>(e);
ArrayList<AVLTreeNode<E>> list = new ArrayList<AVLTreeNode<E>>();
list.add(tn);
return list;
}
Related
I am trying to write an itertor for a type of ArrayList, where Number is a class.
I can almost do it, but I get errors:
This is the class definition
public class History implements Iterable<ArrayList<Number>> {
This is the definition of the type I wish to iterate over:
private ArrayList<Number> spins = new ArrayList<Number>();
... and here are the iterator functions:
#Override
public Iterator<ArrayList<Number>> iterator() {
Iterator<ArrayList<Number>> it = new Iterator<ArrayList<Number>>() {
private int currentIndex = 0;
#Override
public boolean hasNext() {
return currentIndex < gethistorySize() && spins.get(currentIndex) != null;
}
#Override
public ArrayList<Number> next() {
return spins.get(currentIndex++); // ** ERROR **
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
};
return it;
}
I get an error at the lines marked ** ERROR **
The error I get is:
Multiple markers at this line
- The type of expression must be an array type but it resolved to ArrayLisy
- Type mismatch: Cannot convert from Number to ArrayList
I am not quite sure what to return here.
Can anybody help?
Thx
In order for spins.get(currentIndex++) to return an ArrayList<Number>, the type of spins would have to be List<ArrayList<Number>>, not ArrayList<Number>.
If the type of spins is correct, perhaps what you need is to implement an Iterator<Number>, not an Iterator<ArrayList<Number>> (and History should implement Iterable<Number>).
Change
#Override
public ArrayList<Number> next() {
return spins.get(currentIndex++); // ** ERROR **
}
To
#Override
public Number next() {
return spins.get(currentIndex++); // ** ERROR **
}
Return type is wrong hence the compile error.
When you call next() method, you want to iterate each Number object within An ArrayList<Number>.
I'll get right to it.
So I have code that gets a Null Pointer Exception. I've tried looking up what causes it and how to fix it, but that's why I'm confused with this particular code. It was working just fine earlier today and now its throwing the exception. Any help? I'm probably just overlooking something silly but it's quite frustrating. Code follows:
import java.util.*;
import java.io.*;
public class ShopMain<T> {
List<T> stock;
public void Shop() { stock = new LinkedList<T>(); }
public T buy() { return stock.remove(0); }
void sell(T item) { stock.add(item); }
void buy(int n, Collection<? super T>items) {
for (T e : stock.subList(0, n)) {
items.add(e);
}
for (int i=0; i<n; ++i) stock.remove(0);
}
void sell(Collection<? extends T> items) {
for (T e : items) {
stock.add(e);
}
}
public static void main (String[] args) {
ShopMain<Marker> paintballShop = new ShopMain<Marker>();
Console console = System.console();
System.out.println("1 - Test Suite");
String input = console.readLine("Please select the corresponding number to your choice.\n");
if(input.equals("1")){
Stack<Marker> stack = new Stack<Marker>();
Set<Marker> hashset = new HashSet<Marker>();
System.out.println("Test Suite : Tests List, Stack, HashSet");
paintballShop.sell(new Geo3());
paintballShop.sell(new Ego11());
paintballShop.buy();
paintballShop.buy(2, stack); //Stack use
paintballShop.sell(stack); //Stack use
paintballShop.buy(3, hashset); //HashSet
paintballShop.sell(hashset); //HashSet
System.out.println("Tests Complete");
}
}
}
Exception error occurring at runtime:
Exception in thread "main" java.lang.NullPointerException
at ShopMain.sell(ShopMain.java:14)
at ShopMain.main(ShopMain.java:39)
These last bits are just class 'placeholders' for the objects and their parent class.
public class Marker{}
public class Geo3 extends Marker{}
public class Ego11 extends Marker{}
Thanks again for any help.
That's because your List List<T> stock; is still uninitialized. You need to initialize it for you to be able to add, remove elements to/from it. By default, its null and thus, when you try to call a method on it, you get the NullPointerException.
This happens because you don't have a constructor at all. Shop() is not the constructor of your class. A constructor has the same name as the class, and thus you need to have your constructor like this
public ShopMain() { stock = new LinkedList<T>(); }
Incase, Shop() is a valid method, then you need to call this method so that your list is initialized and only then call the other methods.
paintballShop.Shop(); // Call this method to init your list.
change to constructor..
public ShopMain() { stock = new LinkedList<T>(); }
You probably need to change:
public void Shop() { stock = new LinkedList<T>(); }
//doesn't look a method name, may be this is what you missed
to
public ShopMain() { stock = new LinkedList<T>(); }
You don't have a constructor for ShopMain that initializes your List.
Add this:
ShopMain() {
stock<T> = new ArrayList<T>();
}
Basically it comes do to the fact that stock is never initialised. I imagine that the class use to be called Shop
You could change...
public class ShopMain<T> {
List<T> stock;
public void Shop() {
stock = new LinkedList<T>();
}
To...
public class ShopMain<T> {
List<T> stock;
public ShopMain() {
stock = new LinkedList<T>();
}
Which will initialise the List when the class is constructored...
public class Ctrl {
LinkedStack<T> x = new LinkedStack<T>();
I'm trying to use generics for the first time and I get the error "Multiple markers at this line - T cannot be resolved to a type" for the line above.What am I not doing right?
public class LinkedStack<E> {
private static class LinkedNode<T>
{
private T item;
private LinkedNode<T> next;
private LinkedNode(T value)
{
item = value;
next = null;
}
private LinkedNode(T value, LinkedNode<T> reference)
{
item = value;
next = reference;
}
}
protected LinkedNode<E> top;
public LinkedStack()
{
top = null; // empty stack
}
Use the same type parameter name everywhere.
Then add it to your Ctrl class as a parameter.
public class Ctrl<T> {
LinkedStack<T> x = new LinkedStack<T>();
Now all concrete implementations must define T. For example:
public class AppCtrl extends Ctrl<Integer> {
}
Or instantiate it with a concrete type.
Ctrl myctrl = new Ctrl<Integer>();// + necessary constructor params
Or if you don't want to pass it, specify it directly inside Ctrl
public class Ctrl {
LinkedStack<Integer> x = new LinkedStack<Integer>();
I'll get straight into it. Below is a code snippet from my GeneralSearch class I am implementing in an AI application for solving a word puzzle. I am wondering how to instantiate the subclass within the abstract class. I feel I have implemented all relevant abstract methods in my BreadthFirstSearch class as well as its constructor calling its super-constructor. (Nested subclass)
I understand you cant instantiate an abstract class but from previous threads and information you can instantiate a subclass with an abstract super-class.
I try the following calls to no avail:
GeneralSearch bfs = new BreadthFirstSearch(now.getState(), info); //Correct parameters
OR.
GeneralSearch bfs = GeneralSearch.BreadthFirstSearch(now.getState(), info);
Errors received:
1)BreadthFirstSearch cannot be resolved to a type
2)The method BreadthFirstSearch(WordState, WordNodeInfo) is undefined for the type GeneralSearch
I cant seem to get a working instantiation for the subclass so I can perform such searches. If anyone could shed some light on my confusion and understanding that would be great. (Code below)
public abstract class GeneralSearch {
NodeInfo nodeInfo;
ArrayList unvisited, visited;
public GeneralSearch (State startState, NodeInfo nodeInfo) {
this.nodeInfo = nodeInfo;
unvisited = new ArrayList();
unvisited.add(new Node(startState, new Actions()));
visited = new ArrayList();
}
public Node search() {
Actions moves;
Action move;
//Iterating through arrayList for unvisited and possible arcs
Node visit, successor;
if(unvisited.isEmpty()) return null;
while( !unvisited.isEmpty() ) {
visit = select();
if(nodeInfo.isGoal(visit)) return visit;
moves = visit.getState().getActions();
Iterator<Action> it = moves.iterator();
while(it.hasNext()) {
successor = (Node) visit.clone();
move = it.next();
successor.getState().update(move);
insert(successor);
}
visited.add(visit);
}
return null;
}
public abstract Node select ();
public abstract void insert (Node node);
public class BreadthFirstSearch extends GeneralSearch {
public BreadthFirstSearch(State startState, NodeInfo nodeInfo) {
super(startState, nodeInfo);
}
public Node select() {
return (Node) visited.get(0);
}
public void insert(Node node) {
unvisited.add(node);
}
}
}
Put the BreadthFirstSearch class in a separate file, outside of the GeneralSearch class.
If you want to keep it there, try instantiating GeneralSearch.BreadthFirstSearch instead of just BreadthFirstSearch, but I'm not even sure it's possible to have a subclass within it's own parent.
In your second try you're missing a new statement:
GeneralSearch bfs = new GeneralSearch.BreadthFirstSearch(now.getState(), info);
I'm trying to design an undo/redo mechanism to my Chess game.. I decided to use stack data structure which is going to build on an ArrayList.. I also want that my UndoStack and RedoStack classes should be singleton.. However i'm getting
method does not override or implement a method from a supertype
pop() in UndoStack cannot implement pop() in IStackable
return type Move is not compatible with cgas5.Move
where Move is a type-variable:
Move extends Object declared in class UndoStack
error..
Here is my IStackable interface:
package cgas5;
public interface IStackable {
abstract public Move pop();
abstract public void push(Move m);
}
and my UndoStack class
package cgas5;
import java.util.ArrayList;
public class UndoStack<Move> extends ArrayList<Move> implements IStackable {
UndoStack undoStack;
private UndoStack() {
undoStack = new UndoStack();
}
public UndoStack getUndoStack() {
if (undoStack == null) {
undoStack = new UndoStack();
}
return undoStack;
}
#Override
public Move pop() {
Move m = get(size() - 1);
remove(size() - 1);
return m;
}
#Override
public void push(Move m) {
add(m);
}
}
and if it's necessary my Move class:
package cgas5;
public class Move {
private Piece pieceToMove;
private Square currentSquare;
private Square targetSquare;
private Piece capturedPiece;
private Piece promotedPiece;
public Move(){
}
public Move(Piece pieceToMove, Square currentSquare, Square targetSquare){
this.pieceToMove = pieceToMove;
this.currentSquare = currentSquare;
this.targetSquare = targetSquare;
}
public Piece getPieceToMove() {
return pieceToMove;
}
public void setPieceToMove(Piece pieceToMove) {
this.pieceToMove = pieceToMove;
}
public Square getCurrentSquare() {
return currentSquare;
}
public void setCurrentSquare(Square currentSquare) {
this.currentSquare = currentSquare;
}
public Square getTargetSquare() {
return targetSquare;
}
public void setTargetSquare(Square targetSquare) {
this.targetSquare = targetSquare;
}
public Piece getCapturedPiece() {
return capturedPiece;
}
public void setCapturedPiece(Piece capturedPiece) {
this.capturedPiece = capturedPiece;
}
public Piece getPromotedPiece() {
return promotedPiece;
}
public void setPromotedPiece(Piece promotedPiece) {
this.promotedPiece = promotedPiece;
}
}
Thanks in advance..
This is the problem:
public class UndoStack<Move> extends ArrayList<Move>
That's using Move as a generic type parameter, whereas really you don't want a generic type at all - you just want to use Move as the type argument for ArrayList<E>. You want:
public class UndoStack extends ArrayList<Move>
That should fix the problem - although personally I'd strongly recommend using composition instead of inheritance here. (In other words, make your UndoStack type contain an ArrayList<Move> - or something similar - rather than subclassing it.)
Additionally, this is never going to work:
UndoStack undoStack;
private UndoStack() {
undoStack = new UndoStack();
}
That means that to create an UndoStack, you need to create another UndoStack... how do you expect that to happen? You'll currently get a stack overflow exception... why do you need the variable at all?