0

Please, Is there an elegant and efficient way of doing the following in Post Java 8 i.e. 1. Looping through an arraylist 2. Reading the object 3. Calling different methods of potentially different objects using the values contained in the arraylist items

I did look at streams, switch statement, but it was much messy than my if-else.

Any help will be appreciated. Just looking for continuous improvements

List<JAXBElement<? extends Serializable>> bodyElements = eventRequestBodyTypeSrc.getContent();

            for(JAXBElement element: bodyElements){

                if(element.getName().getLocalPart().equalsIgnoreCase("A")){
                    methodA(element.getValue());
                }else if(element.getName().getLocalPart().equalsIgnoreCase("B")){
                     methodB(element.getValue());
                }else if(element.getName().getLocalPart().equalsIgnoreCase("C")){
                     methodC(element.getValue());
                }else if(element.getName().getLocalPart().equalsIgnoreCase("D")){
                     methodD(element.getValue());
                }else if(element.getName().getLocalPart().equalsIgnoreCase("E")){
                     methodE(element.getValue());
                }else{
                 }

            }
Mega
  • 1,304
  • 5
  • 22
  • 37

2 Answers2

0

As a lean solution I would gather all mappings first as follows:

Map<String, Consumer<Serializable>> dispatchers = new HashMap<>();
dispatchers.put("A", this::methodA);
// etc.

...and dispatch the elements like that:

Consumer<Serializable> dispatcher = dispatchers.get(element.getName().getLocalPart().toUpperCase(Locale.US));
if (dispatcher != null) {
    dispatcher.accept(element.getValue());
}
RedXIII
  • 781
  • 7
  • 6
  • `element.getValue()` returns `Serializable`. – shmosel Apr 23 '19 at 23:36
  • Thanks for the timely response. I did quickly rework my code to Enum and Switch statement. However, I will try the Consumer approach you suggested and revert. A little research will be needed, but that is fine. Thanks again. – Mega Apr 29 '19 at 23:38
0

I think you have a bit of an XY Problem going on. I would refactor this at a higher level to encapsulate the strings and their related actions. Here's a rough concept using an enum:

enum Action {
    A("a") {
        @Override
        void doSomething(Serializable value) {
            // ...
        }
    },
    B("b") {
        @Override
        void doSomething(Serializable value) {
            // ...
        }
    };

    private static final Map<String, Action> actionsByName = Arrays.stream(values())
            .collect(Collectors.toMap(a -> a.name, a -> a));

    private final String name;

    Action(String name) {
        this.name = name;
    }

    abstract void doSomething(Serializable value);

    public static void processElement(JAXBElement<? extends Serializable> element) {
        Action action = actionsByName.get(element.getName().getLocalPart().toLowerCase());
        if (action != null) {
            action.doSomething(element.getValue());
        } else {
            // ...
        }
    }
}
shmosel
  • 49,289
  • 6
  • 73
  • 138
  • 1
    Instead of converting every string to lowercase on lookup, I’d just put the same action twice, e.g. under `"a"` and `"A"`. Or use a `TreeMap(String.CASE_INSENSITIVE_ORDER)` for more complex keys. Then, using a functional interface as value, you could use a single `actionsByName.getOrDefault(element.getName() .getLocalPart(), x -> {}).doSomething(element.getValue());` statement… – Holger Apr 24 '19 at 13:32
  • Thanks for the timely response. I did quickly rework my code to Enum and Switch statement. However, I will try the Action pattern and Streams approach you suggested and revert. A little research will be needed, but that is fine. Thanks again. – Mega Apr 29 '19 at 23:36