简体   繁体   中英

Type-casting and getting an array to peek generic results

I am writing a program that inherits some traits from MyStackGeneric called MyStackInteger. I am almost done with the assignment, but I am running into an issue. As soon as I get my two variables in the method binaryOperator, it tries to add, subtract or multiply strings which returns and error. I've tried type casting and moving things around but I cannot get it to work. One of the constraints of my work is that all the methods that are currently in MyStackGeneric have to stay in there. I cannot have them in MyStackInteger as we are going to be using this for Complex numbers in the future.

class `MyStackInteger`:

import java.util.ArrayList;
import java.util.Scanner;
import java.util.Iterator;

public class MyStackInteger extends MyStackGeneric<java.lang.Integer>{

//Creates a new ArrayList and runs readInput as long as there is input
public static void main(String[] args){
  MyStackInteger my = new MyStackInteger(){};
  my.readInput(new Scanner(System.in));
}

//Subtracts two variables
@Override
protected java.lang.Integer minus(java.lang.Integer o1, java.lang.Integer o2){
    o2 = o2-o1;
    return o2;
}

//Multiplies two variables
@Override
protected java.lang.Integer multiply(java.lang.Integer o1, java.lang.Integer o2){
    o2 = o2*o1;
    return o2;
}

//Creates a new element in the Array
@Override
protected java.lang.Integer newElement(java.lang.String w){
    return new Integer(w);
}

//Adds two variables
@Override
protected java.lang.Integer plus(java.lang.Integer o1, java.lang.Integer o2){
    o2 = o2+o1;
    return o2;
}

//Adds a zero to the array
@Override
protected java.lang.Integer zero(){
    Integer blank = 0;
    return blank;
}
}

class MyStackGeneric<E>:

abstract class MyStackGeneric<E> extends ArrayList<E>{

//Generics being implemented by MyStackInteger
protected abstract E multiply(E o1, E o2);

protected abstract E minus(E o1, E o2);

protected abstract E plus(E o1, E o2);

protected abstract E zero();

protected abstract E newElement(java.lang.String w);

//Grabs the top element of the ArrayList
public E peek(){
   return this.get(getSize()-1);
}  

//Removes the top element of the ArrayList
public E pop(){
    E o = this.get(getSize()-1);
    this.remove(getSize()-1);
    return o;
} 

//Pushes an element onto the ArrayList
public void push(E o) {
    this.add(o);
}

//Makes the ListArray A string
@Override
public String toString() {
    return "stack: " + this.toString();
}   

//Iterates while there is input
public void readInput(Scanner s) {
    while (s.hasNext()) {
        String s2 = s.next();
            //Pushes any numerical input to the stack
            if (s2.matches("[+-]?\\d+")) {
                push((E) s2);
            //Goes to binaryOperator if +, - or * is implemented
            } else if (("+".equals(s2)) || 
                      ("-".equals(s2)) || 
                      ("*".equals(s2))) {
                binaryOperator(s2);
            //Prints the stack
            } else if (s2.matches("p")) {
                print();
            //Runs an error if the input is too long
            } else if (s2.length() > 1) {
                System.out.println("Exception: too long: " + s2);
            //Runs an error if there is one unknown char
            } else if (s2.length() == 1) {
                System.out.println("Exception: Unknown Command " + s2);
            }

    }
}

//Prints the stack
public void print(){
   System.out.println("Print Stack: ");
   Iterator<E> s = this.iterator();

   while(s.hasNext()){
       System.out.print(s.next() + (s.hasNext() ? ", " : "\n" ));
   System.out.println("");
   }
}

//Checks if the ArrayList is empty
public boolean empty(){
    return this.isEmpty();
}

//Gets the total size of the ArrayList
public int getSize(){
    return this.size();
}

//Tries to grab the top two elements of the ArrayList, then execute a 
//arithmetic operation on them.
public void binaryOperator(java.lang.String op){
    E var1; 
    E var2;
    boolean exist = true;
    try {
        var1 = peek();
        }catch (ArrayIndexOutOfBoundsException e) {
        System.out.println("Exception: Need two operands");
        var1 = null;
        exist = false;
    }
    if (exist)
       pop();
    try {
        var2 = peek();
        }catch (ArrayIndexOutOfBoundsException e) {
        System.out.println("Exception: Need two operands");
        var2 = null;
        exist = false;
    }
    if (exist)
        pop();
    //This is where the program breaks. At this point, both var1
    //and var2 are Strings so when it tries to run plus or minus
    //or multiply, it returns the error of not being able to turn
    //a string into an int.
    if ("+".equals(op)){
       push(plus(var1, var2));
    }
    if ("-".equals(op)){
       push(minus(var1, var2));
    }
    if ("*".equals(op)){
       push(multiply(var1, var2));
    }  
}
}
        if (s2.matches("[+-]?\\d+")) {
            push((E) s2);

You cannot do this. You cannot take a String and execute an arbitrary cast on it. If you were paying attention to the compiler you would see the warning message

Type safety: Unchecked cast from String to E

The primary issue is with your design. The method readInput has no business being in the MyStackGeneric class. The class should do one thing only, which is serve as the base for implementing concrete stacks. Input and output should be handled by the users of the class, who could do the correct parsing/conversion for the input data.

Or, to put it another way, converting input data to match the generic type requires information (the concrete parameter type) that is not available to the MyStackGeneric class because of type erasure. You could put concrete versions of readInput() in your concrete classes. For MyStackInteger those lines would become

        if (s2.matches("[+-]?\\d+")) {
            push(Integer.valueOf(s2));

But that still violates the single-responsibility principle.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM