4
\$\begingroup\$

Java 8 streams are my new golden hammer that I try to use as often as possible with often enormous gains in brevity and readability. Getting multiple return values, such as a maximum value and its associated element, is a bit cumbersome though (and requires an additional "pair" class).

Should I go back to "normal Java" for this task or is this syntax preferable? Is there a more concise way?

List<String> names = Arrays.asList("John","Paul","Ringo"); 
Pair<String,Integer> longestName = names.stream()
 .map(n->new Pair<>(n,n.length())) // pretend n.length() to be a lengthy operation
 .max(Comparator.comparing(Pair::getB)).get();
System.out.println(longestName.getA()+" "+longestName.getB());

P.S.: With "lengthy operation" I mean long running, as in I don't want to calculate it twice.

\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

Your concept is fine. My only criticism is in code style, and perhaps you should have a specific/custom container instead of the Pair. getA() and getB() should be getName() and getLength(). This also allows you to use primitive values and not Integer, and removes the confusing generic types.

Also:

  • don't get from Optionals at the stream end.
  • use white-space, it's your friend.
  • use meaningful names for lambda parameters (name is better than n )

The code I would write would look like:

Optional<Operation> maxOp = names.stream()
                  .map (name -> new Operation(name, name.length()))
                  .max (Comparator.comparingInt(Operation::getLength()));
Operation longest = maxOp.get();

System.out.println(longest.getName() + " " + longest.getLength());
\$\endgroup\$
1
  • \$\begingroup\$ Sorry for the late accept and thanks for the improvement! \$\endgroup\$ Oct 1, 2019 at 14:11
18
\$\begingroup\$

You don't need the Pair. You can get the String with the maximum length by doing

names.stream().max(Comparator.comparingInt(String::length))
\$\endgroup\$
4
  • \$\begingroup\$ Agreed. Unlike C strings, where strlen() is O(n), String::length should be fast. \$\endgroup\$ Mar 25, 2016 at 17:44
  • \$\begingroup\$ Maybe I didn't explain the problem correctly. I want to return both the length and the string itself, so I want to have two return values. In this example, String::length is fast but this is just a stand in for a long running function. \$\endgroup\$ Oct 1, 2019 at 14:12
  • 1
    \$\begingroup\$ @KonradHöffner this simple syntax gives you the longest string. Just get its length. \$\endgroup\$
    – Sxilderik
    Oct 15, 2020 at 8:43
  • 1
    \$\begingroup\$ This should be the selected answer. \$\endgroup\$
    – Sxilderik
    Oct 15, 2020 at 8:43

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.