2
\$\begingroup\$

I am working on a tax calculator for a school assignment and was hoping to get some feedback on my current progress. I kind of feel like I over-complicated the code.

NOTE: I am required to do all of this in one single .java file otherwise I would have broken it up into separate files.

2016 Tax Calculator

import java.util.Scanner;

class TaxCalculator {

    private static double taxableIncome;

    public static void main(String[] args){
        Scanner input = new Scanner(System.in);

        System.out.println("*****2016 Annual Tax Calculator*****\n");
        System.out.println("0 = Single\n1 = Married\n2 = Head of Household\n");
        System.out.print("Please enter your filing status: ");
        int filingStatus = input.nextInt();

        if (filingStatus != 0 && filingStatus != 1 && filingStatus != 2)
        {
            System.out.println("You must enter either 0, 1 or 2");
        }

        System.out.print("\nPlease enter your total taxable income: $");
        taxableIncome = input.nextDouble();

        switch (filingStatus)
        {
            /*Single Filing Status*/
            case 0:
                //TierOne()
                if (
                        taxableIncome >= singleFiler[0].minSalary &&    //$0
                        taxableIncome <= singleFiler[0].maxSalary &&    //$9,075
                        taxableIncome <= singleFiler[1].maxSalary       //36,900
                    )
                {
                   SingleFilers.TierOne();
                }
                //TierTwo()
                else if (
                        taxableIncome >= singleFiler[1].minSalary &&    //$9,076
                        taxableIncome <= singleFiler[1].maxSalary &&    //$36,900
                        taxableIncome <= singleFiler[2].maxSalary       //$89,350
                        )
                {
                    SingleFilers.TierTwo();
                }
                //TierThree()
                else if (
                        taxableIncome >= singleFiler[2].minSalary &&    //$36,901
                        taxableIncome <= singleFiler[2].maxSalary &&    //$89,350
                        taxableIncome <= singleFiler[3].maxSalary       //$186,350
                        )
                {
                    SingleFilers.TierThree();
                }
                //TierFour()
                else if (
                        taxableIncome >= singleFiler[3].minSalary &&    //$89,351
                        taxableIncome <= singleFiler[3].maxSalary &&    //$186,350
                        taxableIncome <= singleFiler[4].maxSalary       //$405,100
                        )
                {
                    SingleFilers.TierFour();
                }
                //TierFive()
                else if (
                        taxableIncome >= singleFiler[4].minSalary &&    //$186,351
                        taxableIncome <= singleFiler[4].maxSalary &&    //$405,100
                        taxableIncome <= singleFiler[5].maxSalary       //$406,750
                        )
                {
                    SingleFilers.TierFive();
                }
                //TierSix()
                else if (
                        taxableIncome >= singleFiler[5].minSalary &&    //$405,101
                        taxableIncome <= singleFiler[5].maxSalary &&    //$406,750
                        taxableIncome > singleFiler[6].minSalary        //$406,751
                        )
                {
                    SingleFilers.TierSix();
                }
                //TierSeven()
                else if (
                        taxableIncome >= singleFiler[6].minSalary &&    //$406,751
                        taxableIncome <= singleFiler[6].maxSalary       //Double.MAX_VALUE
                        )
                {
                    SingleFilers.TierSeven();
                }
            break;

            case 1:
                //TierOne()
                if (
                        taxableIncome >= jointFiler[0].minSalary &&    //$0
                        taxableIncome <= jointFiler[0].maxSalary &&    //$18,150
                        taxableIncome <= jointFiler[1].maxSalary       //$73,800
                    )
                {
                    JointFilers.TierOne();
                }
                //TierTwo()
                else if (
                        taxableIncome >= jointFiler[1].minSalary &&    //$18,151
                        taxableIncome <= jointFiler[1].maxSalary &&    //$73,800
                        taxableIncome <= jointFiler[2].maxSalary       //$148,850
                        )
                {
                    JointFilers.TierTwo();
                }
                //TierThree()
                else if (
                        taxableIncome >= jointFiler[2].minSalary &&    //$73,801
                        taxableIncome <= jointFiler[2].maxSalary &&    //$148,850
                        taxableIncome <= jointFiler[3].maxSalary       //$226,850
                        )
                {
                    JointFilers.TierThree();
                }
                //TierFour()
                else if (
                        taxableIncome >= jointFiler[3].minSalary &&    //$148,851
                        taxableIncome <= jointFiler[3].maxSalary &&    //$226,850
                        taxableIncome <= jointFiler[4].maxSalary       //$405,100
                        )
                {
                    JointFilers.TierFour();
                }
                //TierFive()
                else if (
                        taxableIncome >= jointFiler[4].minSalary &&    //$226,851
                        taxableIncome <= jointFiler[4].maxSalary &&    //$405,100
                        taxableIncome <= jointFiler[5].maxSalary       //$457,600
                        )
                {
                    JointFilers.TierFive();
                }
                //TierSix()
                else if (
                        taxableIncome >= jointFiler[5].minSalary &&    //$226,851
                        taxableIncome <= jointFiler[5].maxSalary &&    //$405,100
                        taxableIncome > jointFiler[6].minSalary          //$457,601
                        )
                {
                    JointFilers.TierSix();
                }
                //TierSeven()
                else if (
                        taxableIncome >= jointFiler[6].minSalary &&    //$457,601
                        taxableIncome <= jointFiler[6].maxSalary       //Double.MAX_VALUE
                        )
                {
                    JointFilers.TierSeven();
                }
                break;

            case 2:
                //TierOne()
                if (
                        taxableIncome >= hohFiler[0].minSalary &&    //$0
                        taxableIncome <= hohFiler[0].maxSalary &&    //$12,950
                        taxableIncome <= hohFiler[1].maxSalary       //$49,400
                        )
                {
                    HeadOfHouseFilers.TierOne();
                }
                //TierTwo()
                else if (
                        taxableIncome >= hohFiler[1].minSalary &&    //$12,951
                        taxableIncome <= hohFiler[1].maxSalary &&    //$49,400
                        taxableIncome <= hohFiler[2].maxSalary       //$127,550
                        )
                {
                    HeadOfHouseFilers.TierTwo();
                }
                //TierThree()
                else if (
                        taxableIncome >= hohFiler[2].minSalary &&    //$49,401
                        taxableIncome <= hohFiler[2].maxSalary &&    //$127,550
                        taxableIncome <= hohFiler[3].maxSalary       //$206,600
                        )
                {
                    HeadOfHouseFilers.TierThree();
                }
                //TierFour()
                else if (
                        taxableIncome >= hohFiler[3].minSalary &&    //$127,551
                        taxableIncome <= hohFiler[3].maxSalary &&    //$206,600
                        taxableIncome <= hohFiler[4].maxSalary       //$405,100
                        )
                {
                    HeadOfHouseFilers.TierFour();
                }
                //TierFive()
                else if (
                        taxableIncome >= hohFiler[4].minSalary &&    //$206,601
                        taxableIncome <= hohFiler[4].maxSalary &&    //$405,100
                        taxableIncome <= hohFiler[5].maxSalary       //$432,200
                        )
                {
                    HeadOfHouseFilers.TierFive();
                }
                //TierSix()
                else if (
                        taxableIncome >= hohFiler[5].minSalary &&    //$405,101
                        taxableIncome <= hohFiler[5].maxSalary &&    //$432,200
                        taxableIncome > hohFiler[6].minSalary        //$432,201
                        )
                {
                    HeadOfHouseFilers.TierSix();
                }
                //TierSeven()
                else if (
                        taxableIncome >= hohFiler[6].minSalary &&    //$432,201
                        taxableIncome <= hohFiler[6].maxSalary       //Double.MAX_VALUE
                        )
                {
                    HeadOfHouseFilers.TierSeven();
                }
                break;

            default:

        }
    }

    private static class TaxBracket {

        final double minSalary;
        final double maxSalary;
        final double taxRate;

        TaxBracket(double minSalary, double maxSalary, double taxRate) {
            this.minSalary = minSalary;
            this.maxSalary = maxSalary;
            this.taxRate = taxRate;
        }
    }
    //This is the data structure which holds the values for each tier of each filing status
    //Changing values in these arrays will affect the output of the entire program
    private static TaxBracket[] singleFiler;
    static {
        singleFiler = new TaxBracket[]
            {
                new TaxBracket(0, 9075, 0.10),      //Index 0 TierOne
                new TaxBracket(9076, 36900, 0.15),  //Index 1 TierTwo
                new TaxBracket(36901, 89350, 0.25), //Index 2 TierThree
                new TaxBracket(89351, 186350, 0.28),//Index 3 TierFour
                new TaxBracket(186351, 405100, 0.33),//Index 4 TierFive
                new TaxBracket(405101, 406750, 0.35),//Index 5 TierSix
                new TaxBracket(406751, Double.MAX_VALUE, 0.396)//Index 6 TierSeven
            };
    }
    private static TaxBracket[] jointFiler;
    static {
        jointFiler = new TaxBracket[]
            {
                new TaxBracket(0, 18150, 0.10),      //Index 0 TierOne
                new TaxBracket(18151, 73800, 0.15),  //Index 1 TierTow
                new TaxBracket(73801, 148850, 0.25), //Index 2 TierThree
                new TaxBracket(148851, 226850, 0.28),//Index 3 TierFour
                new TaxBracket(226851, 405100, 0.33),//Index 4 TierFive
                new TaxBracket(405101, 457600, 0.35),//Index 5 TierSix
                new TaxBracket(457601, Double.MAX_VALUE, 0.396)//Index 6 TierSeven
            };
    }
    private static TaxBracket[] hohFiler;
    static {
        hohFiler = new TaxBracket[]
            {
                new TaxBracket(0, 12950, 0.10),      //Index 0 TierOne
                new TaxBracket(12951, 49400, 0.15),  //Index 1 TierTow
                new TaxBracket(49401, 127550, 0.25), //Index 2 TierThree
                new TaxBracket(127551, 206600, 0.28),//Index 3 TierFour
                new TaxBracket(206601, 405100, 0.33),//Index 4 TierFive
                new TaxBracket(405101, 432200, 0.35),//Index 5 TierSix
                new TaxBracket(432201, Double.MAX_VALUE, 0.396)//Index 6 TierSeven
            };
    }
    private static class SingleFilers {

        static void TierOne() {
            double totalTax;
            double temp;
            if (taxableIncome >= singleFiler[0].minSalary && taxableIncome <= singleFiler[0].maxSalary) {
                totalTax = taxableIncome * singleFiler[0].taxRate;
                System.out.println("Your total tax is: $" + totalTax);
            }

            else if (taxableIncome > singleFiler[0].maxSalary && taxableIncome <= singleFiler[1].maxSalary)
            {
                temp = taxableIncome - singleFiler[0].maxSalary;
                totalTax = (singleFiler[0].maxSalary * singleFiler[0].taxRate) + temp * singleFiler[1].taxRate;
                System.out.println("Your total tax is: $" + totalTax);
            }
        }

        static void TierTwo() {
            double totalTax;
            double temp;

            if (taxableIncome >= singleFiler[1].minSalary && taxableIncome <= singleFiler[1].maxSalary) {
                totalTax = taxableIncome * singleFiler[1].taxRate;
                System.out.println("Your total tax is: $" + totalTax);
            }

            else {
                if (taxableIncome > singleFiler[1].maxSalary && taxableIncome <= singleFiler[2].maxSalary) {
                    temp = taxableIncome - singleFiler[1].maxSalary;
                    totalTax = (singleFiler[1].maxSalary * singleFiler[1].taxRate) + temp * singleFiler[2].taxRate;
                    System.out.println("Your total tax is: $" + totalTax);
                }
            }
        }
        static void TierThree() {
            double totalTax;
            double temp;

            if (taxableIncome >= singleFiler[2].minSalary && taxableIncome <= singleFiler[2].maxSalary) {
                totalTax = taxableIncome * singleFiler[2].taxRate;
                System.out.println("Your total tax is: $" + totalTax);
            }

            else {
                if (taxableIncome > singleFiler[2].maxSalary && taxableIncome <= singleFiler[3].maxSalary) {
                    temp = taxableIncome - singleFiler[2].maxSalary;
                    totalTax = (singleFiler[2].maxSalary * singleFiler[2].taxRate) + temp * singleFiler[3].taxRate;
                    System.out.println("Your total tax is: $" + totalTax);
                }
            }
        }
        static void TierFour() {
            double totalTax;
            double temp;

            if (taxableIncome >= singleFiler[3].minSalary && taxableIncome <= singleFiler[3].maxSalary) {
                totalTax = taxableIncome * singleFiler[3].taxRate;
                System.out.println("Your total tax is: $" + totalTax);
            }

            else {
                if (taxableIncome > singleFiler[3].maxSalary && taxableIncome <= singleFiler[4].maxSalary) {
                    temp = taxableIncome - singleFiler[3].maxSalary;
                    totalTax = (singleFiler[3].maxSalary * singleFiler[3].taxRate) + temp * singleFiler[4].taxRate;
                    System.out.println("Your total tax is: $" + totalTax);
                }
            }
        }
        static void TierFive() {
            double totalTax;
            double temp;

            if (taxableIncome >= singleFiler[4].minSalary && taxableIncome <= singleFiler[4].maxSalary) {
                totalTax = taxableIncome * singleFiler[4].taxRate;
                System.out.println("Your total tax is: $" + totalTax);
            }

            else {
                if (taxableIncome > singleFiler[4].maxSalary && taxableIncome <= singleFiler[5].maxSalary) {
                    temp = taxableIncome - singleFiler[4].maxSalary;
                    totalTax = (singleFiler[4].maxSalary * singleFiler[4].taxRate) + temp * singleFiler[5].taxRate;
                    System.out.println("Your total tax is: $" + totalTax);
                }
            }
        }
        static void TierSix() {
            double totalTax;
            double temp;

            if (taxableIncome >= singleFiler[5].minSalary && taxableIncome <= singleFiler[5].maxSalary) {
                totalTax = taxableIncome * singleFiler[5].taxRate;
                System.out.println("Your total tax is: $" + totalTax);
            }

            else {
                if (taxableIncome > singleFiler[5].maxSalary && taxableIncome <= singleFiler[6].maxSalary) {
                    temp = taxableIncome - singleFiler[5].maxSalary;
                    totalTax = (singleFiler[4].maxSalary * singleFiler[5].taxRate) + temp * singleFiler[6].taxRate;
                    System.out.println("Your total tax is: $" + totalTax);
                }
            }
        }
        static void TierSeven() {
            double totalTax;

            if (taxableIncome >= singleFiler[6].minSalary && taxableIncome <= singleFiler[6].maxSalary) {
                totalTax = taxableIncome * singleFiler[6].taxRate;
                System.out.println("Your total tax is: $" + totalTax);
            }
        }
    }

    private static class JointFilers {

        static void TierOne() {
            double totalTax;
            double temp;
            if (taxableIncome >= jointFiler[0].minSalary && taxableIncome <= jointFiler[0].maxSalary) {
                totalTax = taxableIncome * jointFiler[0].taxRate;
                System.out.println("Your total tax is: $" + totalTax);
            }

            else {
                if (taxableIncome > jointFiler[0].maxSalary && taxableIncome <= jointFiler[1].maxSalary) {
                    temp = taxableIncome - jointFiler[0].maxSalary;
                    totalTax = (jointFiler[0].maxSalary * jointFiler[0].taxRate) + temp * jointFiler[1].taxRate;
                    System.out.println("Your total tax is: $" + totalTax);
                }
            }
        }
        static void TierTwo() {
            double totalTax;
            double temp;
            if (taxableIncome >= jointFiler[1].minSalary && taxableIncome <= jointFiler[1].maxSalary) {
                totalTax = taxableIncome * jointFiler[1].taxRate;
                System.out.println("Your total tax is: $" + totalTax);
            }

            else {
                if (taxableIncome > jointFiler[1].maxSalary && taxableIncome <= jointFiler[2].maxSalary) {
                    temp = taxableIncome - jointFiler[1].maxSalary;
                    totalTax = (jointFiler[1].maxSalary * jointFiler[1].taxRate) + temp * jointFiler[2].taxRate;
                    System.out.println("Your total tax is: $" + totalTax);
                }
            }
        }
        static void TierThree() {
            double totalTax;
            double temp;
            if (taxableIncome >= jointFiler[2].minSalary && taxableIncome <= jointFiler[2].maxSalary) {
                totalTax = taxableIncome * jointFiler[2].taxRate;
                System.out.println("Your total tax is: $" + totalTax);
            }

            else {
                if (taxableIncome > jointFiler[2].maxSalary && taxableIncome <= jointFiler[3].maxSalary) {
                    temp = taxableIncome - jointFiler[2].maxSalary;
                    totalTax = (jointFiler[2].maxSalary * jointFiler[2].taxRate) + temp * jointFiler[3].taxRate;
                    System.out.println("Your total tax is: $" + totalTax);
                }
            }
        }
        static void TierFour() {
            double totalTax;
            double temp;
            if (taxableIncome >= jointFiler[3].minSalary && taxableIncome <= jointFiler[3].maxSalary) {
                totalTax = taxableIncome * jointFiler[3].taxRate;
                System.out.println("Your total tax is: $" + totalTax);
            }

            else {
                if (taxableIncome > jointFiler[3].maxSalary && taxableIncome <= jointFiler[4].maxSalary) {
                    temp = taxableIncome - jointFiler[3].maxSalary;
                    totalTax = (jointFiler[3].maxSalary * jointFiler[3].taxRate) + temp * jointFiler[4].taxRate;
                    System.out.println("Your total tax is: $" + totalTax);
                }
            }
        }
        private static void TierFive() {
            double totalTax;
            double temp;
            if (taxableIncome >= jointFiler[4].minSalary && taxableIncome <= jointFiler[4].maxSalary) {
                totalTax = taxableIncome * jointFiler[4].taxRate;
                System.out.println("Your total tax is: $" + totalTax);
            }

            else {
                if (taxableIncome > jointFiler[4].maxSalary && taxableIncome <= jointFiler[5].maxSalary) {
                    temp = taxableIncome - jointFiler[4].maxSalary;
                    totalTax = (jointFiler[4].maxSalary * jointFiler[4].taxRate) + temp * jointFiler[5].taxRate;
                    System.out.println("Your total tax is: $" + totalTax);
                }
            }
        }
        private static void TierSix(){
            double totalTax;
            double temp;
            if (taxableIncome >= jointFiler[5].minSalary && taxableIncome <= jointFiler[5].maxSalary) {
                totalTax = taxableIncome * jointFiler[5].taxRate;
                System.out.println("Your total tax is: $" + totalTax);
            }

            else {
                if (taxableIncome > jointFiler[5].maxSalary && taxableIncome <= jointFiler[6].maxSalary) {
                    temp = taxableIncome - jointFiler[5].maxSalary;
                    totalTax = (jointFiler[5].maxSalary * jointFiler[5].taxRate) + temp * jointFiler[6].taxRate;
                    System.out.println("Your total tax is: $" + totalTax);
                }
            }
        }
        private static void TierSeven(){
            double totalTax;
            if (taxableIncome >= jointFiler[6].minSalary && taxableIncome <= jointFiler[6].maxSalary) {
                totalTax = taxableIncome * jointFiler[6].taxRate;
                System.out.println("Your total tax is: $" + totalTax);
            }
        }
    }
    private static class HeadOfHouseFilers{

        static void TierOne(){
            double totalTax;
            double temp;
            if (taxableIncome >= hohFiler[0].minSalary && taxableIncome <= hohFiler[0].maxSalary) {
                totalTax = taxableIncome * hohFiler[0].taxRate;
                System.out.println("Your total tax is: $" + totalTax);
            }

            else {
                if (taxableIncome > hohFiler[0].maxSalary && taxableIncome <= hohFiler[1].maxSalary) {
                    temp = taxableIncome - hohFiler[0].maxSalary;
                    totalTax = (hohFiler[0].maxSalary * hohFiler[0].taxRate) + temp * hohFiler[1].taxRate;
                    System.out.println("Your total tax is: $" + totalTax);
                }
            }
        }
        static void TierTwo(){
            double totalTax;
            double temp;
            if (taxableIncome >= hohFiler[1].minSalary && taxableIncome <= hohFiler[1].maxSalary) {
                totalTax = taxableIncome * hohFiler[1].taxRate;
                System.out.println("Your total tax is: $" + totalTax);
            }

            else {
                if (taxableIncome > hohFiler[1].maxSalary && taxableIncome <= hohFiler[2].maxSalary) {
                    temp = taxableIncome - hohFiler[1].maxSalary;
                    totalTax = (hohFiler[1].maxSalary * hohFiler[1].taxRate) + temp * hohFiler[2].taxRate;
                    System.out.println("Your total tax is: $" + totalTax);
                }
            }
        }
        static void TierThree(){
            double totalTax;
            double temp;
            if (taxableIncome >= hohFiler[2].minSalary && taxableIncome <= hohFiler[2].maxSalary) {
                totalTax = taxableIncome * hohFiler[2].taxRate;
                System.out.println("Your total tax is: $" + totalTax);
            }

            else {
                if (taxableIncome > hohFiler[2].maxSalary && taxableIncome <= hohFiler[3].maxSalary) {
                    temp = taxableIncome - hohFiler[2].maxSalary;
                    totalTax = (hohFiler[2].maxSalary * hohFiler[2].taxRate) + temp * hohFiler[3].taxRate;
                    System.out.println("Your total tax is: $" + totalTax);
                }
            }
        }
        static void TierFour(){
            double totalTax;
            double temp;
            if (taxableIncome >= hohFiler[3].minSalary && taxableIncome <= hohFiler[3].maxSalary) {
                totalTax = taxableIncome * hohFiler[3].taxRate;
                System.out.println("Your total tax is: $" + totalTax);
            }

            else {
                if (taxableIncome > hohFiler[3].maxSalary && taxableIncome <= hohFiler[4].maxSalary) {
                    temp = taxableIncome - hohFiler[3].maxSalary;
                    totalTax = (hohFiler[3].maxSalary * hohFiler[3].taxRate) + temp * hohFiler[4].taxRate;
                    System.out.println("Your total tax is: $" + totalTax);
                }
            }
        }
        static void TierFive(){
            double totalTax;
            double temp;
            if (taxableIncome >= hohFiler[4].minSalary && taxableIncome <= hohFiler[4].maxSalary) {
                totalTax = taxableIncome * hohFiler[4].taxRate;
                System.out.println("Your total tax is: $" + totalTax);
            }

            else {
                if (taxableIncome > hohFiler[4].maxSalary && taxableIncome <= hohFiler[5].maxSalary) {
                    temp = taxableIncome - hohFiler[4].maxSalary;
                    totalTax = (hohFiler[4].maxSalary * hohFiler[4].taxRate) + temp * hohFiler[5].taxRate;
                    System.out.println("Your total tax is: $" + totalTax);
                }
            }
        }
        static void TierSix(){
            double totalTax;
            double temp;
            if (taxableIncome >= hohFiler[5].minSalary && taxableIncome <= hohFiler[5].maxSalary) {
                totalTax = taxableIncome * hohFiler[5].taxRate;
                System.out.println("Your total tax is: $" + totalTax);
            }

            else {
                if (taxableIncome > hohFiler[5].maxSalary && taxableIncome <= hohFiler[6].maxSalary) {
                    temp = taxableIncome - hohFiler[5].maxSalary;
                    totalTax = (hohFiler[5].maxSalary * hohFiler[5].taxRate) + temp * hohFiler[6].taxRate;
                    System.out.println("Your total tax is: $" + totalTax);
                }
            }
        }
        private static void TierSeven(){
            double totalTax;
            if (taxableIncome >= hohFiler[6].minSalary && taxableIncome <= hohFiler[6].maxSalary) {
                totalTax = taxableIncome * hohFiler[6].taxRate;
                System.out.println("Your total tax is: $" + totalTax);
            }
        }
    }
}
\$\endgroup\$
  • \$\begingroup\$ As stands, this code is quite broken. For a single filer with income $406,751, the tax should be $118,119 and change. I bet you charge $160,000 or so. \$\endgroup\$ – mdfst13 Jan 30 '17 at 21:29
  • \$\begingroup\$ Anybody have any ideas on converting the values in the tax tiers to 'BigDecimal' \$\endgroup\$ – Gabriel_W Jan 30 '17 at 22:51
5
\$\begingroup\$

You are right, you over-complicated the code. My comments on it:

  • Avoid using static state (here's a good explanation on why).
  • Reuse code. If you start seeing that the code looks alike in several places that's a good indication that you should be able to abstract the logic and reuse it.
  • If you are going to use arbitrary numbers to present options to the user it's a good practice to represent that with an enum. That way, after you parse the option, your code will be more readable, switch clauses will exhaust the options, etc.
  • Don't use double (or float) for money, use BigDecimal (here's why)
  • Instead of creating static methods that read static state, create instance methods and pass whatever the method needs as a parameter. That way the method itself declares its dependencies and its product.
  • Users will give you bad input. ALWAYS try to check for all possible inputs.
  • If your method is bigger than 50~ lines, it is likely doing more things than it should be. Abstract logic and pull it into another method. That'll make your code more readable.
  • After finishing your code, TEST. If you are not going to write automated tests, at least test it yourself.

My take on the calculator:

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Scanner;

class TaxCalculator {
    public static void main( String[] args ) {
        new TaxCalculator().start();
    }

    private Scanner scanner = new Scanner( System.in );

    private void start() {
        System.out.println( "*****2016 Annual Tax Calculator*****\n" );
        System.out.println( "0 = Single\n1 = Married\n2 = Head of Household\n" );

        FilingStatus status = getFilingStatus();
        BigDecimal taxableIncome = getTaxableIncome();

        BigDecimal tax = calculateTax( status, taxableIncome );

        NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance( new Locale( "en", "US" ) );
        System.out.printf( "Your total tax is: " + currencyFormatter.format( tax.setScale( 2, BigDecimal.ROUND_HALF_UP ) ) );
        System.out.println();
    }

    private FilingStatus getFilingStatus() {
        System.out.print( "Please enter your filing status: " );

        int status;

        String statusString = scanner.nextLine();
        try {
            status = Integer.parseInt( statusString );
        } catch ( NumberFormatException e ) {
            System.out.println( "ERROR: You must enter either 0, 1 or 2" );
            return getFilingStatus();
        }

        if ( status < 0 || status >= FilingStatus.values().length ) {
            System.out.println( "ERROR: You must enter either 0, 1 or 2" );
            return getFilingStatus();
        }

        return FilingStatus.values()[status];
    }

    private BigDecimal getTaxableIncome() {
        System.out.print( "Please enter your total taxable income: $" );

        String incomeString = scanner.nextLine();

        // Remove commas
        incomeString = incomeString.replace( ",", "" );

        BigDecimal income;
        try {
            income = new BigDecimal( incomeString );
        } catch ( NumberFormatException e ) {
            System.out.println( "ERROR: You must enter a valid number" );
            return getTaxableIncome();
        }

        if ( income.compareTo( new BigDecimal( "0" ) ) < 0 ) {
            System.out.println( "ERROR: You must enter 0 or a positive number" );
            return getTaxableIncome();
        }

        return income;
    }

    private BigDecimal calculateTax( FilingStatus status, BigDecimal taxableIncome ) {
        if ( taxableIncome.compareTo( BigDecimal.ZERO ) == 0 ) return BigDecimal.ZERO;

        TaxBracket[] taxTable = TAX_TABLES.get( status );

        BigDecimal tax = BigDecimal.ZERO;
        for ( TaxBracket taxBracket : taxTable ) {
            if ( taxBracket.maxSalary.signum() != - 1 && taxableIncome.compareTo( taxBracket.maxSalary ) >= 0 )
                tax = tax.add( taxBracket.maxSalary.subtract( taxBracket.minSalary ).multiply( taxBracket.taxRate ) );
            else if ( taxBracket.maxSalary.signum() == - 1 || taxableIncome.compareTo( taxBracket.minSalary ) >= 0 )
                tax = tax.add( taxableIncome.subtract( taxBracket.minSalary ).add( new BigDecimal( 1 ) ).multiply( taxBracket.taxRate ) );
            else
                break;
        }

        return tax;
    }

    private enum FilingStatus {
        SINGLE,
        MARRIED_JOINT,
        HEAD_OF_HOUSEHOLD
    }

    private static class TaxBracket {
        final BigDecimal minSalary;
        final BigDecimal maxSalary;
        final BigDecimal taxRate;

        TaxBracket( String minSalary, String maxSalary, String taxRate ) {
            this.minSalary = new BigDecimal( minSalary );
            this.maxSalary = new BigDecimal( maxSalary );
            this.taxRate = new BigDecimal( taxRate );
        }
    }

    private static final Map<FilingStatus, TaxBracket[]> TAX_TABLES;

    static {
        TAX_TABLES = new HashMap<>();

        TAX_TABLES.put( FilingStatus.SINGLE, new TaxBracket[]{
            new TaxBracket( "0", "9075", "0.10" ),
            new TaxBracket( "9076", "36900", "0.15" ),
            new TaxBracket( "36901", "89350", "0.25" ),
            new TaxBracket( "89351", "186350", "0.28" ),
            new TaxBracket( "186351", "405100", "0.33" ),
            new TaxBracket( "405101", "406750", "0.35" ),
            new TaxBracket( "406751", "-1", "0.396" )
        } );
        TAX_TABLES.put( FilingStatus.MARRIED_JOINT, new TaxBracket[]{
            new TaxBracket( "0", "18150", "0.10" ),
            new TaxBracket( "18151", "73800", "0.15" ),
            new TaxBracket( "73801", "148850", "0.25" ),
            new TaxBracket( "148851", "226850", "0.28" ),
            new TaxBracket( "226851", "405100", "0.33" ),
            new TaxBracket( "405101", "457600", "0.35" ),
            new TaxBracket( "457601", "-1", "0.396" )
        } );
        TAX_TABLES.put( FilingStatus.HEAD_OF_HOUSEHOLD, new TaxBracket[]{
            new TaxBracket( "0", "12950", "0.10" ),
            new TaxBracket( "12951", "49400", "0.15" ),
            new TaxBracket( "49401", "127550", "0.25" ),
            new TaxBracket( "127551", "206600", "0.28" ),
            new TaxBracket( "206601", "405100", "0.33" ),
            new TaxBracket( "405101", "432200", "0.35" ),
            new TaxBracket( "432201", "-1", "0.396" )
        } );
    }
}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Wow great reply. I really appreciate all of tbis great information. I am going to have a good look at this. Thanks again. \$\endgroup\$ – Gabriel_W Jan 31 '17 at 5:23
  • \$\begingroup\$ May I ask what the purpose of the -1 in the tier seven maxSalary? Is that to use the overflow of BigDecimal or something? \$\endgroup\$ – Gabriel_W Jan 31 '17 at 5:27
  • \$\begingroup\$ It's just a way of signaling that it has no limit. Look at the condition inside the method calculateTax. \$\endgroup\$ – MiguelAraCo Jan 31 '17 at 6:01
  • \$\begingroup\$ Since there is always a set of TaxBracket for a FillingStatus you can think to remove the TAX_TABLES and place the TaxBracket[] into the FillingStatus. The same appky for the computaton logic that you can move to the FillingStatus itself. \$\endgroup\$ – gervais.b Jan 31 '17 at 7:58
  • 1
    \$\begingroup\$ @Anonymous Yeah you can change the Map<FilingStatus, TaxBracket[]> for a two-dimensional array and the enum for static final ints, but in my opinion that would reduce readability and the map doesn't bring a significant overhead to justify the change. In a simple example like this I think it's a matter of taste/style. \$\endgroup\$ – MiguelAraCo Jan 31 '17 at 13:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.