public class QueueDemo<T> {
public static <T> ArrayUnbndQueue<T> mergeQueue(ArrayBndQueue<T> q1, ArrayBndQueue<T> q2) {
ArrayUnbndQueue<T> temp = new ArrayUnbndQueue<T>();
while (!q1.isEmpty()) {
T x = q1.dequeue();
temp.enqueue(x);
}
while (!q2.isEmpty()) {
temp.enqueue(q2.dequeue());
}
return temp;
}
public static void main(String[] args) {
ArrayBndQueue<Integer> q1 = new ArrayBndQueue<Integer>();
ArrayBndQueue<Integer> q2 = new ArrayBndQueue<Integer>();
ArrayUnbndQueue<Integer> q3 = new ArrayUnbndQueue<Integer>();
q1.enqueue(1);
q1.enqueue(2);
q2.enqueue(5);
q2.enqueue(6);
q3.mergeQueue(q1, q2); // i get an errorThe method
//mergeQueue(ArrayBndQueue<Integer>,
//ArrayBndQueue<Integer>) is undefined
//for the type ArrayUnbndQueue<Integer>
}
}
I have a method that adds two queues and returns them together as a new queue, I am not very experienced with generic datatypes which I believe its whats causing the error.
You do not have any method mergeQueue for ArrayUnbndQueue but for QueueDemo.
Therefore you have to do this statement within your main method of QueueDemo:
ArrayUnbndQueue<Integer> q3 = mergeQueue(q1, q2);
The problem does not relate to generics.
Related
I have created an array which I wanted to control from main. My code runs, but I don't know how to add integers to the array from the main class. Also as each ConcreteSubject has its own storage array, how would i change this to store them all in the same array?
public class ConcreteSubject extends AbstractSpy
{
private AbstractSpy[] spies = new AbstractSpy[10];
private int i = 0;
public void addSpy(AbstractSpy s) {
if (i < spies.length) {
spies[i] = s;
System.out.println("spy added at index " + i);
i++;
}
}
}
public class TestClass
{
public static void main(String[] args) {
ConcreteSubject cs = new ConcreteSubject();
AbstractSpy spies = new AbstractSpy() {
#Override
public void addSpy(AbstractSpy spies) {
}
};
cs.addSpy(cs);
spies.addSpy(spies);
}
}
It seems like your program logic is a little borked. This bit in particular doesn't make much sense:
***AbstractSpy spies = new AbstractSpy() {
#Override
public void addSpy(AbstractSpy spies) {
}
};
cs.addSpy(cs);
***spies.addSpy(spies);
What you're doing is creating TWO AbstractSpy instances, one named cs and one named spies. On that last line you're adding spies to itself! That doesn't help you at all.
Note that AbstractSpy is the most granular unit in your setup - it shouldn't have an addSpy() method and its own internal array, it should be the thing that's added to something else's array!
Here's the same code, but cleaned up a bit:
public abstract class AbstractSpy { }
public class ConcreteSpy extends AbstractSpy { }
public class ConcreteSubject {
private AbstractSpy[] spies = new AbstractSpy[10];
private int i = 0;
public void addSpy(AbstractSpy spy) {
if (i < spies.length)
{
spies[i] = spy;
System.out.println("spy added at index " + i);
i++;
}
}
}
public class TestClass {
public static void main(String[] args) {
ConcreteSubject cs = new ConcreteSubject();
AbstractSpy spy = new ConcreteSpy();
cs.addSpy(spy);
}
}
The big difference here is that ConcreteSpy is an implementation of AbstractSpy that you can add to your ConcreteSubject's array of spies. I think you might have been confused by Java's insistence that you can't create an instance of an abstract class on its own unless you supply an anonymous class that inherits from the abstract class.
My program is structured as follows: a class that represents an atomic concept which is essentially a String and another class that is made of a list of general concepts. Both classes extends the class Concept that is an abstract class, this means that in the list I could have both atomic concepts and intersection of concepts arbitrary nested.
Each concept, atomic or composed, is printed out by toString method.
Roughly speaking, this is based on this context-free grammar:
C : atom | (C and)+ C
Where C is the abstract class Concept, atom is AtomicConcept and (C and)+ C is Intersection.
This is the AtomicConcept class:
public class AtomicConcept extends Concept{
private String atomicConceptName;
public AtomicConcept(String c) {
this.atomicConceptName = c;
}
#Override
public String toString() {
return atomicConceptName;
}
}
This is che ConceptIntersection class:
import java.util.List;
public class ConceptIntersection extends Concept{
private List<Concept> list;
public ConceptIntersection(List<Concept> l) throws Exception {
if(l.size()>1)
{
this.list = l;
}
else
{
throw new Exception("Intersection needs at least two concepts!");
}
}
public String toString()
{
return Utils.conceptIntersection + Utils.lparen + Utils.splitConcepts(list) + Utils.rparen;
}
}
As you can see in toString function, I also created a method called splitConcepts that takes in input a list of general concepts and returns one string made of each concept separated by comma.
public static String splitConcepts(List<Concept> list)
{
String result = "";
for (Concept item : list) {
System.out.println(item);
result += item.toString() + comma;
}
result = result.substring(0, result.length() - 1);
return result;
}
Where is the problem?
I have trouble with this function because when I call a nested intersection in another one, this function never ends!
One example:
public static void main(String[] args) throws DLRException {
// TODO Auto-generated method stub
AtomicConcept atom = new AtomicConcept("one");
AtomicConcept at = new AtomicConcept("two");
List<Concept> list = new LinkedList<Concept>();
list.add(at);
list.add(atom);
DLRConceptIntersection intersection = new DLRConceptIntersection(list);
System.out.println(intersection); // works fine
list.add(intersection);
DLRConceptIntersection intersection2 = new DLRConceptIntersection(list);
System.out.println(intersection2); //loop never ends!
}
Is a correct approach to fix this problem?
You have a circular reference :
DLRConceptIntersection intersection = new DLRConceptIntersection(list);
list.add(intersection);
This causes the intersection's List to contain a reference to the same instance referred by intersection, which is why toString() run into infinite recursion.
I'm assuming you didn't intend intersection and intersection2 to share the same List.
You can avoid it if you create a copy of the List in the DLRConceptIntersection constructor:
public ConceptIntersection(List<Concept> l) throws Exception {
if(l.size()>1) {
this.list = new ArrayList<>(l);
} else {
throw new Exception("Intersection needs at least two concepts!");
}
}
I am trying to apply varargs. I have declared a method which requires an indefinite amount of variables like this:
private Subject carMonitor;
public AdvancedMonitor(Subject ... carMonitors){
for (Subject carMonitor : carMonitors){
this.carMonitor = carMonitor;
carMonitor.registerObserver(this);
}
}
However, when I try to call it in my main method, I am not able to use anything other than one argument:
BigCar bigCar = new BigCar();
SmallCar smallCar = new SmallCar();
AdvancedMonitor doubleAdvancedDisplay1 = new AdvancedMonitor();
AdvancedMonitor doubleAdvancedDisplay2 = new AdvancedMonitor(bigCar);
AdvancedMonitor doubleAdvancedDisplay3 = new AdvancedMonitor(bigCar, smallCar);
Only the second one works. Why is this?
Is it related to my interface?
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}
big car interface -- small car is pretty much the same for now :
public class BigCar implements Subject {
private ArrayList observers;
private int state;
public BigCar(){
observers = new ArrayList();
}
public void registerObserver(Observer o){
observers.add(o);
}
public void removeObserver(Observer o){
int i = observers.indexOf(o);
if (i >= 0){
observers.remove(i);
}
}
public void notifyObservers(){
for (int i = 0; i < observers.size(); i++){
Observer observer = (Observer)observers.get(i);
observer.update(state);
}
}
public void stateChanged() {
notifyObservers();
}
public void setState(int state){
this.state = state;
stateChanged();
}
}
I write following code:
public class Test {
public static class AdvancedMonitor {
private String carMonitor;
public AdvancedMonitor(String... carMonitors) {
for (String carMonitor : carMonitors) {
this.carMonitor = carMonitor;
System.out.println(this.carMonitor);
}
}
}
public static void main(String[] args) {
String bigCar = "bigCar";
String smallCar = "smallCar";
System.out.println("step 1");
AdvancedMonitor doubleAdvancedDisplay1 = new AdvancedMonitor();
System.out.println();
System.out.println("step 2");
AdvancedMonitor doubleAdvancedDisplay2 = new AdvancedMonitor(bigCar);
System.out.println();
System.out.println("step 3");
AdvancedMonitor doubleAdvancedDisplay3 = new AdvancedMonitor(bigCar, smallCar);
}
}
And I have following result:
step 1
step 2
bigCar
step 3
bigCar
smallCar
In my opinion, all correct. What is wrong in your case? Do you use logging or System.out.println to debug your problem? It's look like your problem isn't with Java varagrs, but you have some exception in carMonitor.registerObserver(this).
P.S. Also, you understand that every AdvancedMonitor has only a one varible carMonitor? And using new AdvancedMonitor(bigCar, smallCar); in result you have AdvancedMonitor only with smallCar in private String carMonitor;?
P.P.S. Also bad idea to use this in construstor, because object isn't really create when running construstor.
Actually the Constructor works.
Please check these statements:
SmallCar and BigCar both implements Subject
class AdvancedMonitor implements Observer
AdvancedMonitor doubleAdvancedDisplay is not declared several times but in your code it is. It should be smth like:
AdvancedMonitor doubleAdvancedDisplay1 = new AdvancedMonitor();
AdvancedMonitor doubleAdvancedDisplay2 = new AdvancedMonitor(bigCar);
AdvancedMonitor doubleAdvancedDisplay3 = new AdvancedMonitor(bigCar, smallCar);
I hope it'll help you
I created these two files in java and they don't compile. This error comes up:
cannot find symbol C02FootprintV1".
Why doesn't the program recognize the object? I am new to this.
How could I fix this problem?
public class CO2FootprintV1 {
private double myGallonsUsed;
private double myTonsCO2;
private double myPoundsCO2;
CO2FootprintV1(double gals) {
myGallonsUsed = gals;
}
public void calcTonsCO2() {
myTonsCO2 = myGallonsUsed * 0.878;
}
public double getTonsCO2() {
return myTonsCO2;
}
public void convertTonsToPoundsCO2() {
myPoundsCO2 = myTonsCO2 * 220462262;
}
public double getPoundsCO2() {
return myPoundsCO2;
}
}
public class CO2FootprintV1Tester {
public static void main(String[] args) {
double gals;
double tonsCO2, poundsCO2;
gals = 1300;
CO2FootprintV1 object = new C02FootprintV1(gals);
object.calcTonsCO2();
tonsCO2 = object.getTonsCO2();
object.convertTonsToPoundsCO2();
poundsCO2 = object.getPoundsCO2();
}
}
On the line
CO2FootprintV1 object = new C02FootprintV1(gals);
you have C02 (see zero two) on the right hand side, you meant for it to be
CO2FootprintV1 object = new CO2FootprintV1(gals);
or CO2 (see oh two). Also, you should consider that the error messages your tools give you might be correct.
Just change:
CO2FootprintV1 object = new C02FootprintV1(gals);
to:
CO2FootprintV1 object = new CO2FootprintV1(gals);
That's why it is important to have good naming practice.
You put a "0" (cero) instead of an "O" (letter):
CO2FootprintV1 object = new C02FootprintV1(gals);
Try this:
CO2FootprintV1 object = new CO2FootprintV1(gals);
I made this class ArrayBuilder with generics to make some basic operation to manage an array of T objects.
public class ArrayBuilder<T> {
#SuppressWarnings("unchecked")
public ArrayBuilder(Class<T> ct, int dim){
container = (T []) Array.newInstance(ct, dim);
}
public T getElement(int index){
return container[index];
}
public void setElement(int index, T value){
container[index] = value;
}
public T[] getContainer(){
return container;
}
T[] container;
public static void main(String[] args) throws ClassNotFoundException {
PrintStream ps = new PrintStream(System.out);
Scanner sc = new Scanner(System.in);
ps.print("che array desidera? ");
String nameClass = "discover.";
nameClass = nameClass + sc.nextLine();
Class<?> toManipulate = Class.forName(nameClass);
//Type type = toManipulate.getGenericSuperclass();
ArrayBuilder<toManipulate> ab = new ArrayBuilder<toManipulate>(toManipulate, 10);
}
}
in main, program asks to the user to insert the name of the Class wich he prefers, so I want to use ArrayBuilder constructor to create this kind of array but compiler doesn't accept variable toManipulate in the angular brackets. Maybe Do I have to extract generic Type from the instance toManipulate?
Generics are a compile time feature. What you have can equally be handled by raw types as you don't know what the type is at compile time.
Class toManipulate = Class.forName(nameClass);
ArrayBuilder ab = new ArrayBuilder(toManipulate, 10);
or if you really want to use generics you can do
Class<?> toManipulate = Class.forName(nameClass);
ArrayBuilder<?> ab = new ArrayBuilder<Object>(toManipulate, 10);