I have started to learn Java and I need your critique for my first program. It is an interpreter that can calculate any expression including abs(), sqrt(), min(), max(), round() and pow().What can you say about this? Are there any code defects or pointless comments?Main classimport java.io.*;public class Main {    static boolean Error=false;    public static void main(String args[]) throws Exception{        System.out.println(Type an expression to calculate \n +                abs(x) function returns absolute value of x\n +                sqrt(x) function returns square root of value x\n +                min(x,y,) function returns a minimum value between x,y,...\n +                max(x,y,) function returns a maximum value between x,y,...\n +                round(x) function returns a round value of x\n +                pow(x,y) function returns an exponentiation of x,y\n +                Type \exit\ to exit);        while (true){            BufferedReader read = new BufferedReader(new InputStreamReader(System.in));            String stringForProcessing =read.readLine(); //Input a string to work with it            String output= Calculating.calculating(stringForProcessing); //Calculating            System.out.println(output);//Output            Error=false;        }    }}Calculating classimport java.lang.Math;import java.util.ArrayList;public class Calculating {    static String calculating(String workingString){        ArrayList<String> separatedString = new ArrayList<>();        int Position=0;        boolean Negative=false;        if(Main.Error){                                                //return error report            return(workingString);        }        while(Position<workingString.length()){                        //reducing spaces            if(workingString.charAt(Position)==' '){                while (((Position)<workingString.length())                        &&(workingString.charAt(Position)==' ')){                    Position++;                }            }            else if (workingString.charAt(Position)=='-'&&(Position==0 //checking value for negativity                    || workingString.charAt(Position-1)=='-'                    || workingString.charAt(Position-1)=='+'                    || workingString.charAt(Position-1)=='*'                    || workingString.charAt(Position-1)=='/')){                Negative=true;                Position++;            }            else  if ((workingString.charAt(Position)=='-'             //checking for repeating operators                    || workingString.charAt(Position)=='+'                    || workingString.charAt(Position)=='*'                    || workingString.charAt(Position)=='/')                    &&(Position==0                    || workingString.charAt(Position-1)=='-'                    || workingString.charAt(Position-1)=='+'                    || workingString.charAt(Position-1)=='*'                    || workingString.charAt(Position-1)=='/')){                Main.Error=true;return(Error: two or more operators in a row);            }            separatedString.add(Character.toString(workingString.charAt(Position)));            if (workingString.charAt(Position)=='('){                 //Creating bracer stack to parse                int BrcrStack=1;                String Temp=;                while (((Position+1)<workingString.length())){                    switch (workingString.charAt(Position+1)){                        case '(':BrcrStack++;break;                        case ')':BrcrStack--;break;                    }                    Position++;                    if(BrcrStack!=0){                        Temp+=workingString.charAt(Position);                    }                    else {break;}                }                if(BrcrStack!=0){                    Main.Error=true;return(Error: missing \)\);                }                separatedString.set(separatedString.size()-1, calculating(Temp));            }            else if (Character.isDigit(workingString.charAt(Position))){    //Bolting numbers                while (((Position+1)<workingString.length())&&(Character.isDigit(workingString.charAt(Position+1))                        || workingString.charAt(Position+1)=='.') ){                    separatedString.set(separatedString.size()-1,                            separatedString.get(separatedString.size()-1)+workingString.charAt(Position+1));                    Position++;                }                try {                    Float.valueOf(separatedString.get(separatedString.size()-1));}                catch(Exception e){                    Main.Error=true;return(Error: multiple points);                }                if(Negative){                                      //Negate parameter                    separatedString.set(separatedString.size()-1,Float.toString(-(Float.valueOf(separatedString.get(separatedString.size()-1)))));                    Negative=false;                }            }            else if (Character.isAlphabetic(workingString.charAt(Position))){  //Bolting functions                while (((Position+1)<workingString.length())                        &&(Character.isAlphabetic(workingString.charAt(Position+1))) ){                    separatedString.set(separatedString.size()-1,                            separatedString.get(separatedString.size()-1)+workingString.charAt(Position+1));                    Position++;                }                switch (separatedString.get(separatedString.size()-1)){        //Checking functions                    case abs:break;                    case sqrt:break;                    case min:break;                    case max:break;                    case round:break;                    case pow:break;                    case exit:System.exit(0);                    default: {                        Main.Error=true;return(Error: unknown function \+separatedString.get(separatedString.size()-1)+\);                    }                }                if ((Position+1)==workingString.length()||workingString.charAt(Position+1)!='(')   //Parsing function parameters                {                    Main.Error=true;return(Error: missing \(\ after +\+separatedString.get(separatedString.size()-1)+\ + function);                }                ArrayList<String> Temp = new ArrayList<>();                int BrcrStack=1;                Temp.add();                while (((Position+2)<workingString.length())){                    switch (workingString.charAt(Position+2)){                        case '(':BrcrStack++;break;                        case ')':BrcrStack--;break;                        case ',': if (BrcrStack==1){Temp.add();Position++;continue;}break;                    }                    Position++;                    if(BrcrStack!=0){Temp.set(Temp.size()-1,Temp.get(Temp.size()-1)+Character.toString(workingString.charAt(Position+1)));}                    else {break;}                }                if(BrcrStack!=0){                    Main.Error=true;return(Error: missing \)\);}                Position++;                float FuncArr[]=new float[Temp.size()];                for (int i=0;i<Temp.size();i++){                    Temp.set(i, Calculating.calculating(Temp.get(i)));                    if (Temp.get(i).length()==0){                        Main.Error=true;return(Error: missing expression);}                    FuncArr[i]=Float.valueOf(Temp.get(i));                }                switch (separatedString.get(separatedString.size()-1)){     //Calculating functions                    case abs:if (FuncArr.length==1) {                        separatedString.set(separatedString.size()-1,Float.toString(Math.abs(FuncArr[0])));}                    else {                        Main.Error=true;return(Error: \abs\ function needs only one argument);}break;                    case sqrt:if (FuncArr.length==1) {                        double a=FuncArr[0];                        separatedString.set(separatedString.size()-1,Double.toString(Math.sqrt(a)));}                    else {                        Main.Error=true;return(Error: \sqrt\ function needs only one argument);}break;                    case min:separatedString.set(separatedString.size()-1,Float.toString(Min(FuncArr))) ;break;                    case max:separatedString.set(separatedString.size()-1,Float.toString(Max(FuncArr))) ;break;                    case round:if (FuncArr.length==1) {                        separatedString.set(separatedString.size()-1,Float.toString(Math.round((FuncArr[0]))));}                    else {                        Main.Error=true;return(Error: \round\ function needs only one argument);}break;                    case pow:if (FuncArr.length==2) {                        separatedString.set(separatedString.size()-1,Double.toString(Math.pow(FuncArr[0],FuncArr[1])));}                    else {                        Main.Error=true;return(Error: \pow\ function needs only two arguments);}break;                }            }            Position++;        }        ArrayList<String> ResultArr = new ArrayList<>();        if(Negative){                                      //Negate parameter            separatedString.set(separatedString.size()-1,Float.toString(-(Float.valueOf(separatedString.get(separatedString.size()-1)))));        }        ArrayList<String> Stack = new ArrayList<>();        int i=0;        while (i<separatedString.size()){               //Converting expression to postfix notation            if (separatedString.get(i).length()==1&&(separatedString.get(i).charAt(0)=='+'||separatedString.get(i).charAt(0)=='-'||separatedString.get(i).charAt(0)=='/'||separatedString.get(i).charAt(0)=='*')){                if(Stack.size()==0){                    Stack.add(separatedString.get(i));                }else {                    if ((separatedString.get(i).charAt(0) == '+' || separatedString.get(i).charAt(0) == '-') && (Stack.get(Stack.size() - 1).charAt(0) == '*' || Stack.get(Stack.size() - 1).charAt(0) == '/')) {                        Stack.add(separatedString.get(i));                    } else {                        Stack.add(separatedString.get(i));                        Stack.add(separatedString.get(i+1));                        i++;                        while (Stack.size() > 0) {                            ResultArr.add(Stack.get(Stack.size()-1));                            Stack.remove(Stack.size() - 1);                        }                    }                }            }            else{                ResultArr.add(separatedString.get(i));            }            i++;        }        while (Stack.size() > 0) {            ResultArr.add(Stack.get(Stack.size()-1));            Stack.remove(Stack.size() - 1);        }        i=0;        while (ResultArr.size()>1){       //Calculating postfix expression            if (ResultArr.get(i).length()==1&&(ResultArr.get(i).charAt(0)=='+'||ResultArr.get(i).charAt(0)=='-'||ResultArr.get(i).charAt(0)=='/'||ResultArr.get(i).charAt(0)=='*')){                switch (ResultArr.get(i).charAt(0)){                    case '+':ResultArr.set(i-2,Float.toString(Float.valueOf(ResultArr.get(i-2))+Float.valueOf(ResultArr.get(i-1))));ResultArr.remove(i);ResultArr.remove(i-1);break;                    case '-':ResultArr.set(i-2,Float.toString(Float.valueOf(ResultArr.get(i-2))-Float.valueOf(ResultArr.get(i-1))));ResultArr.remove(i);ResultArr.remove(i-1);break;                    case '*':ResultArr.set(i-2,Float.toString(Float.valueOf(ResultArr.get(i-2))*Float.valueOf(ResultArr.get(i-1))));ResultArr.remove(i);ResultArr.remove(i-1);break;                    case '/':ResultArr.set(i-2,Float.toString(Float.valueOf(ResultArr.get(i-2))/Float.valueOf(ResultArr.get(i-1))));ResultArr.remove(i);ResultArr.remove(i-1);break;                }                i=0;            }            i++;        }        String Result=;        for (String aResultArr : ResultArr) {            Result += aResultArr;        }        if (Float.valueOf(Result)==Math.floor(Float.valueOf(Result))){            Result=Integer.toString(Math.round(Float.valueOf(Result)));        }        return Result;    }    static float Min(float Arr[]){        float Min=Arr[0];        for (int i=1;i<Arr.length;i++){            if (Arr[i]<Min){Min=Arr[i];            }        }        return Min;    }    static float Max(float Arr[]){        float Max=Arr[0];        for (int i=1;i<Arr.length;i++){            if (Arr[i]>Max){Max=Arr[i];            }        }        return Max;    }}
Evaluating expressions with various mathematical methods
java;beginner;math expression eval
FormattingYour variable names should start with a lower case letter by convention.Try to have spaces around operators (+, == etc.)Try to have spaces after if, while etc.don't have superlong lines. Somebdoy recommends hardlimit on 80 chars, somebody a soft limit on 120 chars, it doesn't matter. Simply try to have shorter lines if it's possible.generally, these formatting conventions are good to follow (As a baseline, not as a hard rule. They are quite aged, don't contain information about some of the newer Java features (annotations, generics...), enforce the nowadays-controversial spaces instead of tabs and a hard limit of 80 chars-per line.)instead of ArrayList<Something> list = new ArrayList<>();, use List<Something> list = new ArrayList<>(); See here or here.anyway, you got the formatting pretty much rightCodeThis:String result = ;for (String aResultArr : resultArr) {    result += aResultArr;}is horribly wrong. Strings in Java are immutable, which means that you can't add anything to an existing String. What happens instead is that a new String is allocated and all the characters are copied. This is a killer when used in a loop.The right way is to use a StringBuilder:StringBuilder resultBuilder = new StringBuilder();for (String aResultArr : resultArr) {    resultBuilder.append(aResultArr);}String result = resultBuilder.toString();By the way, some + thing gets internally compiled to new StringBuilder().append(some).append(thing).toString() anyway (because of the String immutability I talked about).You should generally split your code to have fewer loops, less indenting, much more methods. That way, it will be a lot more readable, maintainable (and therefore less error-prone). For example, this code in the main parsing while loop:// reducing spacesif (workingString.charAt(position) == ' ') {    while ((position < workingString.length())            && (workingString.charAt(position) == ' ')) {        position++;    }}This could be a separate method skipSpaces().Or, even better, move it out from the main loop. Do you want to strip the user input of all spaces? Do it right away when you read it!// Input a string to work with it, strip it of all spacesString stringForProcessing = read.readLine().replace( , );Or, again, in a method, so it's possible to have a high-level overview over the code:// Input a string to work with itString stringForProcessing = read.readLine();stringForProcessing = stripOfSpaces(stringForProcessing);Comment your code. Don't explain what it does. For example,// CalculatingString output = Calculating.calculating(stringForProcessing);this one is pretty redundant. The code is self-explanatory. Or at least should be (again, split it into multiple methods).So don't explain what. Explain why.//checking value for negativityif ((workingString.charAt(position) == '-')        && (position == 0                || workingString.charAt(position - 1) == '-'                || workingString.charAt(position - 1) == '+'                || workingString.charAt(position - 1) == '*'                || workingString.charAt(position - 1) == '/')) {So this one checks for negativity. Cool. That comment should have been a method name private static boolean checkNegative(String workingString, int pos). Or something similar.The comment? Not needed.What I don't understand (usually until I dive really deep into the code) is why is the condition so long and why is it checking previous characters, too. That should be commented: // checking previous chars, because of ...Cache often used values.If you wrote workingString.charAt(position - 1) four times in a condition, you probably should have usedchar previousChar = workingString.charAt(position - 1);And then use this cached value in your condition. Your lines will be shorter, your code will be more clear and faster.Same problem:if (Float.valueOf(result) == Math.floor(Float.valueOf(result))) {    result = Integer.toString(Math.round(Float.valueOf(result)));}return result;Use:float numResult = Float.valueOf(result);if (numResult == Math.floor(numResult)) {    result = Integer.toString(Math.round(numResult));}return result;This issue is all around your code and would help quite a lot when gotten right. However, don't obsess about caching too much - it can hurt readability when used excessively. And readability should be one of your main concerns.If you want to use something as a stack, look for a implemetation of stack, don't use a List. Your code will be much more readable, because you won't have to call stack.get(stack.size() - 1), but will use stack.getLast() instead.Also, try to avoid java.util.Stack for reasons you don't yet understand (think it's old). Use a Deque interface and a ArrayDeque (preferred) or LinkedList implementation.Deque<String> stack = new ArrayDeque<>();When done with this, instead of your oldwhile (Stack.size() > 0) {    ResultArr.add(Stack.get(Stack.size()-1));    Stack.remove(Stack.size() - 1);}you'll end up with code like this:while (stack.size() > 0) {    resultArr.add(stack.getLast());    stack.removeLast();}While visibly better, it can still be improved to:while (!stack.isEmpty()) {    resultArr.add(stack.removeLast());}You're parsing strings to numbers, then performing operations on them and then converting them back to strings. Highly inefficient and confusing both for you and for me. Consider storing numbers as ... numbers. I admit that to do this effectively and nicely, you'll probably need to write some classes or enums. That is a step up from your current programming level, so don't bother with it until you're sure what you're doing at the current level. But it's something to consider. The same applies to operations which can be implemented as enums/classes.Wow. I didn't expect this to get so long. It's definitely not all the things that could use some polishing, but it's what caught my eye while going through. I think it's enough for today :).