2

So I've searched through several websites and others questions on this, and none seem to have the answer that works for me. I have code that works, and my programming mentor suggested I change the chained if/else if to using a lambda table instead. I asked about using something of a hash table, and he said using a hash for only 9 items (the real program has 9 if/else statements) would be a waste.

I will post the working code using both the if/else if and the hash table, keeping it limited to 3 items to keep the code short and sweet.

Here is the code for if/else if...

public class testLambda {
    String[] numArray = {"One", "Two", "Three"};

    testLambda(String num){
        if (num.equals(numArray[0])){
            printStringOne();
        } else if (num.equals(numArray[1])){
            printStringTwo();
        } else if (num.equals(numArray[2])){
            printStringThree();
        }
    }

    private void printStringOne(){
        System.out.println("1");
    }

    private void printStringTwo(){
        System.out.println("2");
    }

    private void printStringThree(){
        System.out.println("3");
    }

    public static void main(String[] args) {
        new testLambda("One");
        new testLambda("Three");
        new testLambda("Two");
    }
}

results in system printing...

1
3
2

Here is the code for a hash table

import java.util.HashMap;
import java.util.Map;

public class testLambda {
    String[] numArray = {"One", "Two", "Three"};

    testLambda(String num){
        Map<String, Runnable> printNumber = new HashMap<>();

        printNumber.put(numArray[0], () -> printStringOne());
        printNumber.put(numArray[1], () -> printStringTwo());
        printNumber.put(numArray[2], () -> printStringThree());

        printNumber.get(num).run();
    }

    private void printStringOne(){
        System.out.println("1");
    }

    private void printStringTwo(){
        System.out.println("2");
    }

    private void printStringThree(){
        System.out.println("3");
    }

    public static void main(String[] args) {
        new testLambda("Three");
        new testLambda("One");
        new testLambda("Two");
    }
}

results in system printing...

3
1
2

and now... the lambda. From what I have read, an interface is required. Keep in mind, I can't use extends, because my application is already extending a different class(java doesn't support multiple inheritance) Here is what I have conjured so far (not working):

public class testLambda {
    String[] numArray = {"One", "Two", "Three"};

    public interface PrintNumber{
        void printNumber();
    }

    testLambda(String num){
        PrintNumber[] printNumbers = new PrintNumber[]{
                new PrintNumber() {public void printNumber(){printStringOne();}},
                new PrintNumber() {public void printNumber(){printStringTwo();}},
                new PrintNumber() {public void printNumber(){printStringThree();}}
        };

        for (int n = 0; n < numArray.length; n++){
            if (num.equals(numArray[n])){
                printNumbers[n];
            }
        }
    }

    private void printStringOne(){
        System.out.println("1");
    }

    private void printStringTwo(){
        System.out.println("2");
    }

    private void printStringThree(){
        System.out.println("3");
    }

    public static void main(String[] args) {
        new testLambda("Three");
        new testLambda("Two");
        new testLambda("One");
    }
}

This results in a compile error. Can anyone tell me what I'm doing wrong? I'm really new to the lambda algorithm.

7
  • 2
    Note that, you can just write new PrintNumber[] { () -> printStringOne(), () -> printStringTwo(), () -> printStringThree()} (same as you did with your Map<.., Runnable>). You do not necessarily need a new interface. Now I don't know why it should get simpler with lambdas (or a lambda table?) and I do not know why it should be a waste to use a Map in this case. I wouldn't place a Runnable in there, but that's another thing. I would rather ask your mentor, what's the point of using a lambda table or why he/she suggested it. Commented May 15, 2017 at 10:47
  • You're right! This is much cleaner. Thanks a bunch :) Also, when I meet with him tomorrow, i'll ask him your question and get his response. Also, it looks like the interface is still required for creating the object array CreateCharacter[] createCharacters = new CreateCharacter[]{...};. Commented May 15, 2017 at 11:02
  • Not necessarily. You could also just use Runnable[]. However using your own interface makes sense to make the purpose (and code) clearer. Commented May 15, 2017 at 11:06
  • Oh yeah, thanks :) but how would I then call the index of the Runnable array? printNumbers[n].printNumber(); as printNumber() is red out. Commented May 15, 2017 at 11:10
  • nevermind, I found it printNumbers[n].run(); Thanks again :) Commented May 15, 2017 at 11:13

1 Answer 1

3

The compilation error is due to this statement:

numArray[n];

which is not a valid statement. What you wanted was this:

    for (int n = 0; n < numArray.length; n++){
        if (num.equals(numArray[n])){
            createCharacters[n].printNumber();
        }
    }

However, this relies on keeping two separate arrays in sync, and is therefore error prone. I suggest using a single HashMap for everything, and getting rid of your original numArray in favour of the HashMap:

public class testLambda {
    Map<String, Runnable> printNumber = new HashMap<>();
    static {
        printNumber.put("One", () -> printStringOne());
        printNumber.put("Two", () -> printStringTwo());
        printNumber.put("Three", () -> printStringThree());
    }

    testLambda(String num){
        printNumber.get(num).run();  // Add some checking here for robustness
    }

By the way, what you call a "lambda table" doesn't necessarily mean it can't be a HashMap. In fact, the above can be called a lambda table. The () -> printStringXXX(); are lambda expressions, and the map is a table of strings to lambdas.

Sign up to request clarification or add additional context in comments.

2 Comments

Sorry, I edited the question and re-wrote the constructor. It's still the statement error, but the intent of use is different. This is my fault.
omg I was so close. I was just missing the .printNumber() in printNumbers[n], making it printNumbers[n].printNumber(); as the correct answer. Thanks :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.