I'm having a hard time to understand the ClassCastException and it is crashing the line that it is commented. Please explain why its doing in that? Thanks
public class tester {
private static B<Data> build(char[] ss, double[] f) {
B<Data> res = new B<Data>();
PriorityQueue<String> q = new PriorityQueue<String>();
...
double c_x = 20.1;
Data h = res.getElement(); //throws ClassCastException
if(h.getFreq()==c_x){
...
}
}//end of method
}//end of class tester
public class Data{
private char symbol;
private double freq;
public Data(char c, double f){
symbol = c;
freq = f;
}
public char getSymbol(){
return symbol;
}
public double getFreq(){
return freq;
}
public String toString(){
return freq + ":" + symbol;
}
public int compareTo(Data o) {
return (int) (this.freq-o.freq);
}
}//end of class Data
public class B<T> {
// the fields
private T element;
private B<T> left;
private B<T> right;
// create an empty node
public B() {
this(null, null, null);
}
public B(T theElement, B<T> lt, B<T> rt) {
element = theElement;
left = lt;
right = rt;
}
// return the element
public T getElement() {
return element;
}
public void setElement(T x) {
element = x;
}
}//end of class B
Exception:
Exception in thread "main" java.lang.ClassCastException: java.lang.Double cannot be cast to Data
at tester.build(tester.java:40)
at tester.main(tester.java:83)
Do you happen to have some method that takes a raw type B? Because if you do, you can assign any value to element in that method.
Example
static void rawSet(B b) {
b.setElement(1.0); // you can put anything here
}
public static void main(String [] args) {
B<Integer> b = new B<>();
rawSet(b);
Integer x = b.getElement(); // ClassCastException
}
Since you didn't post complete code I could run, I have to make my own.
Data.java:
package test;
public class Data {
private char symbol;
private double freq;
public Data(char c, double f){
symbol = c;
freq = f;
}
public char getSymbol(){
return symbol;
}
public double getFreq(){
return freq;
}
public String toString(){
return freq + ":" + symbol;
}
public int compareTo(Data o) {
return (int) (this.freq-o.freq);
}
}
GenericType.java (replacing B):
package test;
public class GenericType<T> {
private T element;
public GenericType() {
element = null;
}
public T getElement() {
return element;
}
public void setElement(T x) {
element = x;
}
}
Test.java (main program):
package test;
public class Test {
public static void main(String[] args) {
GenericType<Data> obj = new GenericType<Data>();
Data d = obj.getElement();
System.out.println("Data retrieved");
}
}
When executed:
> java test.Test
Data retrieved
So there's a problem somewhere, and you omitted it.
How to create a Minimal, Complete, and Verifiable example
https://stackoverflow.com/help/mcve
Generics is only a compile-time concept. At runtime they are just Objects. Your problem most likely lies in how you instantiate B.
Related
I have the following class, superclass and main codes below. I am unsure as to what 'peek().min' is doing. I get that if its the first number that is being passed in, Integer.MAX_VALUE is returned, thereby making the Math.min() output select the value that it was passed in as. However, I don't get what peek().min does since the return is a value from a stack node (top.data). Top being the node and data being the value. What then does '.min' do?
superclass:
import java.util.EmptyStackException;
public class Stack<NodeWithMin>{
private static class StackNode<T>{
private T data;
private StackNode<T> next;
public StackNode(T data){
this.data = data;
}
}
private StackNode<NodeWithMin> top;
public NodeWithMin pop() throws EmptyStackException {
if(top == null) throw new EmptyStackException();
NodeWithMin item = top.data;
top = top.next;
return item;
}
public void push(NodeWithMin item){
StackNode<NodeWithMin> t = new StackNode<NodeWithMin>(item);
t.next = top;
top = t;
}
public NodeWithMin peek() throws EmptyStackException {
if(top==null) throw new EmptyStackException();
return top.data;
}
public boolean isEmpty(){
return top == null;
}
}
class:
public class StackWithMin extends Stack<NodeWithMin>{
public void push(int value){
int newMin = Math.min(value, min());
super.push(new NodeWithMin(value, newMin));
}
public int min(){
if(this.isEmpty()){
return Integer.MAX_VALUE;
}
else{
return peek().min;
}
}
}
class NodeWithMin{
public int value;
public int min;
public NodeWithMin(int v, int min){
value = v;
this.min = min;
}
}
Main:
public class Main {
public static void main(String[] args)
{
StackWithMin obj = new StackWithMin();
obj.push(8);
obj.push(3);
obj.push(5);
System.out.println(obj.min());
}
}
Given
class A {
public static A newInstance(int x) { ... }
}
And several classes containing static fields of type A
class B1 {
public static A MIN = A.newInstance(10);
}
class B2 {
public static A MIN = A.newInstance(15);
}
I would like to parameterize a class with B1 or B2 to get MIN field of type A from class B in the class C:
class C <T, P> {
private T t = ???;
}
When C<A, B1> c = new C(); what should be placed instead ??? to get B1.MIN?
Is it possible?
EDIT:
Thank you for the answers, I have upvoted both.
I have arrived simply at
class C <T, P> {
private T t;
public C(T min) {
this.t = min;
}
}
This will be just C<A, B1> c = new C<A, B1>(B1.MIN); because as you can see it is hard to avoid a constructor for C taking an instance of B1 or smth like that. But in this case B1 at least not instantiated.
You can use an interface to achieve this behavior:
class A {
public static A newInstance() { return new A(); }
}
interface HasMin {
public static A MIN = null;
}
class B1 implements HasMin {
public static A MIN = A.newInstance();
}
class B2 implements HasMin {
public static A MIN = A.newInstance();
}
class C<T extends HasMin> {
private A t = T.MIN;
}
Then you can create: C<B1> and C<B2> and use both.
As Tom suggested in the comments below, this approach is limited to use static fields. An even better approach would be:
public class Play {
public static void main(String[] args) {
B1 b1 = new B1();
C<B1> c = new C<>(b1);
System.out.println(c.getA()); // prints: A{ x=10 }
B2 b2 = new B2();
C<B2> c2 = new C<>(b2);
System.out.println(c2.getA()); // prints: A{ x=20 }
}
}
class A {
private int x;
public A(int x) {
this.x = x;
}
#Override
public String toString() {
return "A{ x=" + x + " }";
}
public static A newInstance(int x) {
return new A(x);
}
}
interface GetMin {
public A getMin();
}
class B1 implements GetMin {
public A MIN = A.newInstance(10);
#Override
public A getMin() {
return MIN;
}
}
class B2 implements GetMin {
public A MIN = A.newInstance(20);
#Override
public A getMin() {
return MIN;
}
}
class C<T extends GetMin> {
private A a = null;
public C(T t) {
a = t.getMin();
}
public A getA() {
return a;
}
}
I would forget static and have a concrete instance of an interface:
public interface Bounds<T> {
T min();
}
The concrete instance could be singleton, so next best thing to a static:
public enum B implements Bounds<A> {
INSTANCE;
private final A min = A.newInstance(10);
#Override
public A min() {
return min;
}
}
C then defined like so:
public class C<T, P extends Bounds<T>> {
private T min;
public C(P bounds) {
min = bounds.min();
}
public T getMin() {
return min;
}
}
Usage:
C<A, B> c = new C(B.INSTANCE);
Self describing
Maybe you don't want this meta data type (B), maybe you want types to describe themselves. So C could be defined for types that can describe their own bounds:
public class C<T extends Bounds<T>> {
private T min;
public C(T anyT) {
min = anyT.min();
}
public T getMin() {
return min;
}
}
Usage:
C<A> c = new C(A.zero); //any A will do
Where A is:
public class A implements Bounds<A>{
public final static A zero = A.newInstance(0);
private final static A min = A.newInstance(10);
public static A newInstance(int x) {
return new A(x);
}
private int x;
public A(int x) {
this.x = x;
}
#Override
public A min() {
return min;
}
}
I have a class Zeitpunkt which implements a date with time and in addition a class Suchbaum which represents a binary search tree.
I want to use a Comparator-Object in Suchbaum to sort a tree by the day of Zeitpunkt, but when I want to create a Suchbaum object, it prints the named error.
Zeipunkt
public class Zeitpunkt<T> implements Comparable<T>
{
private int jahr;
private int monat;
private int tag;
private int stunden;
private int minuten;
private double sekunden;
public int vergleich(Zeitpunkt a) { ... }
#Override
public int compareTo(T o) {
if(o instanceof Zeitpunkt)
return vergleich((Zeitpunkt)o);
return 0;
}
...
}
Suchbaum
public class Suchbaum<T extends Comparable<T>> {
private class Element {
private T daten;
private Element links;
private Element rechts;
public Element(T t) {
daten = t;
links = null;
rechts = null;
}
}
private Element wurzel;
private Comparator<T> comp;
...
}
Testclass
public class BaumTest {
public static void main(String[] args) {
// error in the following line (IntelliJ underlines the first
// "Zeitpunkt"). Suchbaum<Zeitpunkt<?>> = ... doesn't work either..
// *Completely confused*
Suchbaum<Zeitpunkt> sb = new Suchbaum<>((Zeitpunkt z1, Zeitpunkt z2) -> {
if(z1.getTag() > z2.getTag())
return 1;
else if(z1.getTag() == z2.getTag())
return 0;
else
return -1;
});
}
}
Any ideas? (the other threads with this topic didn't help me out)
Seems that you don't want to make your Zeitpunkt class parametrized, you just want it to implement Comparable interface. So change it like this:
public class Zeitpunkt implements Comparable<Zeitpunkt> {
private int jahr;
private int monat;
private int tag;
private int stunden;
private int minuten;
private double sekunden;
public int vergleich(Zeitpunkt a) {
return 0;
}
#Override
public int compareTo(Zeitpunkt o) {
return vergleich(o);
}
}
Also you need to define a constructor in your Suchbaum class:
public Suchbaum(Comparator<T> comp) {
this.comp = comp;
}
I have made a class called Fish:
public class Fish {
private String species;
private int size;
//Constructor
public Fish(int x, String s) {
size = x;
species = s;
}
public String getSpecies() { return species; }
public int getSize() { return size; }
public String toString() {
return String.format("A %dcm %s", size, species);
}
}
And I have also started to make a class called pond that is meant to have an attribute called 'fish' that holds an array of Fish objects. I am unsure of how to do this. Here is my attempt so far. I am
public class Pond {
private int capacity;
private Object[] fish; //This is what I am trying to initialize. list of Fish.
private int numFish;
//Capacity Constructor
public Pond(int n, int c) {
n = numFish;
c = capacity;
}
public int getNumFish() { return numFish; }
public boolean isFull() {
boolean isFull = false;
if (numFish >= capacity) {
isFull = true;
}
else {
isFull = false;
}
return isFull;
}
public String toString() {
return String.format("Pond with %d fish", numFish);
}
public void add(Fish aFish) {
if (numFish <= capacity) {
numFish += 1;
fish.add Fish;
}
else {
numFish += 0;
}
}
}
Change this:
private Object[] fish;
as follows:
private Fish[] fish;
i.e. these are fishes and not just any
kinds of objects (they not mammals e.g.).
Following is invalid -
fish.add aFish;
with arrays you do
fish[numFish] = aFish; //increment numFish after this
You also need to initialize your array
fish = new Fish[capacity];
in your constructor.
In the Pond constructor you're assigning private fields to constructor arguments. I think it should be the other way around:
public Pond(final int n, final int c) {
numFish = n;
capacity = c;
}
A side note: declaring Pond constructor arguments final would prevent these kind of error at compile time.
Also, if you want to expand fish array at runtime then array is not the best choice of the container type. ArrayList<Fish> is a better choice as it can expand at runtime.
You need to use ArrayList instead of Array since an ArrayList can grow according to requirements.
Take a look at this code.Should help you:
public class Fish {
String name;
public Fish(String name) {
this.name=name;
}
public String toString() {
return name;
}
}
And then:
import java.util.*;
public class Pond {
ArrayList<Fish> fishInPond = new ArrayList<>();
public void addFish(Fish e) {
fishInPond.add(e);
}
public void showFishes() {
for (int i= 0; i<fishInPond.size();i++) {
fishInPond.get(i);
}
System.out.println("Fishes in my pond: " + fishInPond);
}
public static void main(String[]args) {
Pond myPond = new Pond();
myPond.addFish(new Fish("Tilapia"));
myPond.addFish(new Fish("cat fish"));
myPond.showFishes();
}
}
There's something wrong in my code, but i don't know why. I have two class:
public class MyClass extends MySuperClass {
potected int field1;
public MyClass() {
super();
}
#Override
public int getField1() {
return this.field1;
}
public void setField1(int f) {
this.field1 = f;
}
}
public class MySuperClass {
potected int field1, field2;
public MySuperObject() {
}
public int getField1() {
return this.field1;
}
public void setField1(int f) {
this.field1 = f;
}
public void setField2(int f) {
this.field2 = f;
}
public int getField2() {
return this.field2;
}
}
When i create different new MyClass object (i.e. for insert inside an ArrayList) something go wrong:
ArrayList<MyClass> list = new ArrayList<MyClass>();
while(condidion) {
MyClass obj = new MyClass();
obj.setField1(value1);
obj.setField2(value2);
list.add(obj);
}
If value1 and value2 assume the sequent value
1 and 50
2 and 70
3 and 80
After my code is executed, my list contains
1 and 80
2 and 80
3 and 80
It looks like that every time i create new MyClass object, only an instance of MySuperClass it's created (field2 assume the value of last input value).
How can i fix it?
Here is the code which you have given. It is working perfectly if you give correct input.
import java.util.ArrayList;
class MyClass extends MySuperClass {
protected int field1;
public MyClass() {
super();
}
#Override
public int getField1() {
return this.field1;
}
public void setField1(int f) {
this.field1 = f;
}
}
class MySuperClass {
protected int field1, field2;
public MySuperClass() {
}
public int getField1() {
return this.field1;
}
public void setField1(int f) {
this.field1 = f;
}
public void setField2(int f) {
this.field2 = f;
}
public int getField2() {
return this.field2;
}
}
public class Tryouts {
public static void main(String[] args) {
int i = 0;
ArrayList<MyClass> list = new ArrayList<MyClass>();
while(i < 3) {
MyClass obj = new MyClass();
obj.setField1(40 + i);
obj.setField2(80+ i);
list.add(obj);
i++;
}
for (MyClass c : list) {
System.out.println(c.getField1() + "::" + c.getField2());
}
}
}
The output is
40::80, 41::81, 42::82