JAVA:将对象从另一个类与对象进行比较

时间:2017-11-05 03:14:13

标签: java equals instanceof

我在课堂上有以下代码......

String processor()
{
  Stack<Character> stack = new Stack<>();
  while (curr < infixExpr.length())
  {
     // assigning the current index position of string in infix expression to a variable to reduce amount of repeated code
     Character element = infixExpr.charAt(curr);

     if (isOperand(element))
     {
        postfixExpr += "" + element;
     }
     else if (element == '(')
     {
        stack.push(element);
     }
     else if (element == ')')
     {
        while (!stack.peek().equals('('))
        {
           postfixExpr += stack.pop(); // adding all items in stack after ( and before )
        }
        stack.pop(); // this should pop the stack of the  waiting pushed ( paren and remove it from our postfix expression, basically ignoring it
        // right paren found to trigger this else if statement was never pushed onto the stack nor assigned to the postfix expression, also ignored
     }
     else //*must be an operator then
     {
        while (OrdOpsTable.getOperatorPrecedence(stack.peek(), true) > OrdOpsTable.getOperatorPrecedence(element, false)) // flag, 'true' to signify this is from the stack. ALso, compare if it has higher precedence over the current operator
        {
           postfixExpr += stack.pop(); // placing found operator to end of postfix expression
        }
        stack.push(element);
     }
     curr++;
  }
  while (!stack.isEmpty())
  {
     postfixExpr += stack.pop();
  }
  return postfixExpr;
}

在方法“getOperatorPrecedence”参数中,我有一个名为 stack 的Stack实例,调用方法 peek ,返回一个Character Object。正如字段元素所示,元素是字符对象类型。我在方法参数中创建了一个简单的标志布尔值,以使其变得简单。

因此,“getOperatorPrecedence”位于另一个名为“OrdOpsTable”的类文件中......

public final class OrdOpsTable<T> extends ArrayList
{
    // INITIALIZERS
    private static Character[] table = {'(','+','-','*','/','%','^'};
    private static ArrayList<OperatorValues> ON_stack = new ArrayList<>();
    private static ArrayList<OperatorValues> ON_curr = new ArrayList<>();
    private T FROM_stack = null;
    private T FROM_curr = null;

    // CONSTRUCTOR
    private OrdOpsTable(T curr)
    {
        setOperatorPrecedence();
        if (curr.getClass() == Stack.class)
            this.FROM_stack = curr;
        else
            this.FROM_curr = curr;
    }

    // METHODS
    private static void setOperatorPrecedence()
    {
        // this method just sets the unique values of each operator to two arrays
        int i = 0;
        for (char op : table)
        {
            switch(op)
            {
                case '(':
                    ON_stack.add(i, new OperatorValues(op, 0));
                    ON_curr.add(i, new OperatorValues(op, 100));
                    break;
                case '+':
                    ON_stack.add(i, new OperatorValues(op, 2));
                    ON_curr.add(i, new OperatorValues(op, 1));
                    break;
                case '-':
                    ON_stack.add(i, new OperatorValues(op, 2));
                    ON_curr.add(i, new OperatorValues(op, 1));
                    break;
                case '*':
                    ON_stack.add(i, new OperatorValues(op, 4));
                    ON_curr.add(i, new OperatorValues(op, 3));
                    break;
                case '/':
                    ON_stack.add(i, new OperatorValues(op, 4));
                    ON_curr.add(i, new OperatorValues(op, 3));
                    break;
                case '%':
                    ON_stack.add(i, new OperatorValues(op, 4));
                    ON_curr.add(i, new OperatorValues(op, 3));
                    break;
                case '^':
                    ON_stack.add(i, new OperatorValues(op, 5));
                    ON_curr.add(i, new OperatorValues(op, 6));
                    break;
            }
            i++;
        }
    }


    public static int getOperatorPrecedence(Object curr, boolean FROM_stack)
    {
        setOperatorPrecedence();
        if (FROM_stack)
        {
            return ON_stack.get(ON_stack.indexOf(curr)).value;
        }
        else
        {
            return ON_curr.get(ON_stack.indexOf(curr)).value;
        }
    }



    /* SUBCLASS */
    private static class OperatorValues
    {   
        // FIELDS
        private char operator;
        private int value;

        // CONSTRUCTOR
        OperatorValues(char operator, int value)
        {
            this.operator = operator;
            this.value = value;
        }

        // METHOD
        char getOperator()
        {
            return this.operator;
        }
        int getValue()
        {
            return this.value;
        }
        public String toString()
        {
            return this.operator;
        }
    }   

我需要帮助的是找到一种方法来正确返回

的两个实例的OperatorValue子类字段
return ON_stack.get(ON_stack.indexOf(curr)).value;
                      and
return ON_curr.get(ON_stack.indexOf(curr)).value;

我收到以下错误...

        Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
            at java.util.ArrayList.elementData(ArrayList.java:418)
            at java.util.ArrayList.get(ArrayList.java:431)
            at OrdOpsTable.getOperatorPrecedence(OrdOpsTable.java:79)
            at PostfixParser.processor(PostfixParser.java:57)
            at InfixPostfixTester.main(InfixPostfixTester.java:78)

当我调试并遵循此问题时,问题出在“Character”类“equals”中。首先,当我强制进入有问题的第一个return语句时,它会转到ArrayList中的indexOf()......

public int indexOf(Object o) {
    if (o == null) {
        for (int i = 0; i < size; i++)
            if (elementData[i]==null)
                return i;
    } else {
        for (int i = 0; i < size; i++)
            if (o.equals(elementData[i]))
                return i;
    }
    return -1;
}

当调试器在这里遇到.equals方法时,它会进入Character类......

public boolean equals(Object obj) {
    if (obj instanceof Character) {
        return value == ((Character)obj).charValue();
    }
    return false;
}

这里的问题是此equals方法中的IF语句在此比较中失败。它似乎将obj与我自定义的OperatorValues类的toString()进行比较,它显然不是Character类的实例。所以,它失败了,因为它将“(”作为一个字符进行比较。我需要它来比较'('在此方法中触发'true'。

举一个例子,我在方法setOperatorPrecedence()中的OrdOpsTable类中分配了char'('在一个数组中带有'0'的int,在另一个数组中有'100',如上所示。这里调用类equals()方法而不使用OperatorValues类的toString(),我的调试器说curr的内联值'('在这个相等的方法中显示',obj:OrdOpsTable $ OperatorValues @ 636。

如果有办法让OperatorValues中的toString()方法返回一个Character而不是String。如果我这样做,这当然会导致错误。关于你将在这里做什么的任何建议?

*注意:如果我需要为您提供更多信息,请与我们联系。这是一个班级的家庭作业,我花了很多时间坚持这一部分,我已经无情地尝试过。我需要一些外包帮助来理解我所缺少的东西。

1 个答案:

答案 0 :(得分:0)

我想通了,我将Character类的所有内容更改为String类,并在我的OrdOpsTable类中更改getOperatorPrecedence()方法,以强制从我的自定义OperatorValues类的本机类到String类进行比较,我这样做了...

return ON_stack.get(ON_stack.toString().indexOf(curr)).getValue();

感谢所有参与帮助的人,感谢他们。