简体   繁体   中英

Java console menu using lambdas

I'm learning how to create a basic console menu in Java. I've been told that it would be more efficient for me to do this with lambda's instead. The code here works quite alright without lambda's but I would like to know how to modify it so that I can add the methods to the menu class by using lambda's?

Also why would the use of lambda's make this better/more efficient? Or would it just make the code easier to read?

Here are the classes below:

Runnable Interface

@FunctionalInterface
public interface Runnable {
    public void run();
}

ChoicePair class

public class ChoicePair<String, Runnable> {
    private String text;
    private Runnable funcint;

    public ChoicePair(String t, Runnable fi) {
        this.text = t;
        this.funcint = fi;
    }

    public void setText(String t) {this.text = t;}
    public void setFI(Runnable fi) {this.funcint = fi;}
    public String getText() {return this.text;}
    public Runnable getFI() {return this.funcint;}

}

Menu Class

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

public class Menu implements Runnable {

    private String title;
    private ArrayList<ChoicePair> choices;
    public Scanner scan = new Scanner(System.in);
    public Menu(String title) {
        this.title = title;
        choices = new ArrayList<ChoicePair>();
    }

    @Override
    public void run() {
        int choiceInt = -1;
        while(choiceInt != 0) {
            System.out.println(title + ":");
            int x = 1;
            for (ChoicePair cur : choices) {
                System.out.println("[" + x + "]: " + cur.getText());
                x++;
            }
            if (title == "Main Menu")
                System.out.println("[0]: EXIT");
            else
                System.out.println("[0]: Back");
            System.out.println(">\t");
            choiceInt = getInt();
            act(choiceInt);
        }
    }
    public void addPair(ChoicePair addition) {
        choices.add(addition);
    }

    public int getInt() {
        return scan.nextInt();
    }

    public void act(int choiceInt) {
        if(choiceInt == 0)
            return;
        if(choiceInt < 0 || choiceInt > choices.size()) {
            System.out.println("Incorrect input.");
            return;
        }
        int choicePos = choiceInt - 1;
        ((Runnable)choices.get(choicePos).getFI()).run();
    }

}

Mean Calculator class (contains methods used)

public class meanCalculator {
    private static double[] values;
    private static int type;

    public meanCalculator() {
    }

    public static void setValues(double[] input) {
        values = input.clone();
    }

    public static void addValues(double[] addition) {
        if (values == null) {
            values = addition.clone();
            return;
        }
        double[] temp = new double[values.length + addition.length];

        int y;
        for(y = 0; y < values.length; ++y) {
            temp[y] = values[y];
        }

        for(y = values.length; y < addition.length + values.length; ++y) {
            temp[y] = addition[y - values.length];
        }

        values = temp;
    }

    public static void clearSet() {
        values = null;
        return;
    }

    public static void removeN(int n) {
        double[] newSet = new double[values.length - n];
        for (int x = 0; x < values.length - n; x++) {
            newSet[x] = values[x];
        }
        values = newSet.clone();
    }

    public static void display() {
        System.out.println("Displaying values currently in meanCalculator array: [" + values.length + "] values.");
        for(double d: values) {
            System.out.println(d);
        }
    }

    public static void setType(int typeIndex) {
        type = typeIndex;
    }

    private static double Arithmetic(double[] input) {
        double total = 0.0D;

        for(int i = 0; i < input.length; ++i) {
            total += input[i];
        }

        return total / (double)input.length;
    }

    private static double Geometric(double[] input) {
        double total = 1.0D;

        for(int x = 0; x < input.length; ++x) {
            total *= input[x];
        }

        total = Math.pow(total, 1.0D / (double)input.length);
        return total;
    }

    private static double Harmonic(double[] input) {
        double total = 0.0D;

        for(int x = 0; x < input.length; ++x) {
            total += 1.0D / input[x];
        }

        total = 1.0D / total;
        total *= (double)input.length;
        return total;
    }

    public static String getType() {
        switch(type) {
            case 1:
                return "Arithmetic";
            case 2:
                return "Geometric";
            case 3:
                return "Harmonic";
            default:
                return "Not yet defined!";
        }
    }

    public static double calcMean() {
        switch(type) {
            case 1:
                return Arithmetic(values);
            case 2:
                return Geometric(values);
            case 3:
                return Harmonic(values);
            default:
                return 999.0D;
        }
    }
}

Application (Main class)

import java.util.*;

public class Application {
    public static Scanner scan = new Scanner(System.in);
    public static void main(String[] args) {
        Menu mainMenu = new Menu("Main Menu");

        //Create runnables for setting mean types...
        Runnable setMean1 = new Runnable() {
            @Override
            public void run() {
                meanCalculator.setType(1);
                System.out.println("Mean type set to Arithmetic.");
            }
        };
        Runnable setMean2 = new Runnable() {
            @Override
            public void run() {
                meanCalculator.setType(2);
                System.out.println("Mean type set to Geometric...");
            }
        };
        Runnable setMean3 = new Runnable() {
            @Override
            public void run() {
                meanCalculator.setType(3);
                System.out.println("Mean type set to Harmonic...");
            }
        };
        //Create mean-setting menu and choicepairs and populate.
        Menu setMean = new Menu("Set Mean Type");
        ChoicePair mean1 = new ChoicePair("Arithmetic", setMean1);
        ChoicePair mean2 = new ChoicePair("Geometric", setMean2);
        ChoicePair mean3 = new ChoicePair("Harmonic", setMean3);
        setMean.addPair(mean1);
        setMean.addPair(mean2);
        setMean.addPair(mean3);
        mainMenu.addPair(new ChoicePair("Set Mean Type", setMean));

        //Create runnables for array setting...
        Runnable addValues = new Runnable() {
            @Override
            public void run() {
                ArrayList<Double> additionArrayList = new ArrayList<Double>();
                String input = null;
                int x = 0;
                System.out.print("Enter values to add to set, or '-1' to complete entry.\n> ");
                while (input != "-1") {
                    input = scan.nextLine();
                    if (Double.parseDouble(input) == -1.0D)
                        break;
                    additionArrayList.add(Double.parseDouble(input));
                }
                System.out.println("Break detected.");
                double[] additions = new double[additionArrayList.size()];
                for(double d: additionArrayList) {
                    additions[x] = d;
                    x++;
                }
                meanCalculator.addValues(additions);
            }
        };
        Runnable clearSet = new Runnable() {
            @Override
            public void run() {
                meanCalculator.clearSet();
            }
        };
        Runnable removeN = new Runnable() {
            @Override
            public void run() {
                System.out.print("Enter number of elements to remove from end\n> ");
                int toRemove = scan.nextInt();
                meanCalculator.removeN(toRemove);
            }
        };
        Runnable displaySet = new Runnable() {
            @Override
            public void run() {
                meanCalculator.display();
            }
        };
        ChoicePair add = new ChoicePair("Add values to Array", addValues);
        ChoicePair clear = new ChoicePair("Clear Array", clearSet);
        ChoicePair remove = new ChoicePair("Remove N elements", removeN);
        ChoicePair display = new ChoicePair("Display Array", displaySet);
        Menu arrayOptions = new Menu("Array Options");
        arrayOptions.addPair(add);
        arrayOptions.addPair(clear);
        arrayOptions.addPair(remove);
        arrayOptions.addPair(display);
        mainMenu.addPair(new ChoicePair("Array Options", arrayOptions));

        //Create runnable for calculate-mean function...
        Runnable calcMean = new Runnable() {
            @Override
            public void run() {
                double mean = meanCalculator.calcMean();
                String type = meanCalculator.getType();
                System.out.println(type + " mean for current array = " + mean);
            }
        };
        ChoicePair calculate = new ChoicePair("Calculate Mean", calcMean);
        mainMenu.addPair(calculate);



        //Run the main menu
        mainMenu.run();
    }
}

You can use lambdas instead of anonymous classes in your main method. Like this:

Runnable setMean1 = () -> {
    meanCalculator.setType(1);
    System.out.println("Mean type set to Arithmetic.");
};

It will be more readable and less boilerplate code, but you will not get any performance benefit from it.

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