javafor-loopif-statementarraylistone-liner

Is there a one-liner for list creation and element addition?


Say we have to iterate over a list of complex object, and "group" them in a map where a key is (for example) a date and the relative value is a list of complex objects that share that same date.

I'm a sucker for elegant and readable code, in my way though.

  1. I love one liners after loops and conditional constructs as they do not require "{" & "}";
  2. I hate declaring variables I will not re-use;
Map<ZonedDateTime, List<ComplexObject >> map = new HashMap<>();
        
for(var complexObject : complexObjectsList)
            
    if (map.containsKey(complexObject.getZonedDateTime()))

        map.get(complexObject.getZonedDateTime()).add(complexObject);

    else

        map.put(complexObject.getZonedDateTime(), new ArrayList<ComplexObject>().add(complexObject));
            

As you can see, for and if/else constructs do not need {} nor additional lines.

The problem here, is:

in the case of a date not present yet in the map, I would love to add it in a one-liner, also creating the list with the first element inside. However, since ArrayList's ".add" method does not return a List (which is what the map value expects) and, instead, returns a boolean, I cannot do so.

I'm forced to declare a new List a few lines higher, add the element in another line, and then pass it. Consequentially, I will have to use "{}", multiple lines and a variable declaration that is not going to be used anymore.

Is there a way to achieve this? Thanks a lot!


Solution

  • However the question is about having a one line where you can create a list, add an element to it, and return the list.

    Depends on the kind of list you want:

    Many other ways also exist, e.g. Stream.of(element).collect(toList()), many other list implementations exist, e.g. ImmutableList.of(element) with Guava.


    Another way of approaching the problem outlined in the question, which is basically creating a new list and adding an element to it would be:

    map.computeIfAbsent(complexObject.getZonedDateTime(), k -> new ArrayList<>()).add(complexObject);
    

    I challenge your preference towards omitting {} and doing things in one-liners: neither of these are good general approaches:

    Ultimately, you should optimize for readable code. Far more time is (or should be) spent reading code than writing code. The poor person who has to read your code next might be you - it's easy to forget what you meant when you return to the code a week, a month, a year later.

    Be kind, take the time to help future you.