2
\$\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
\$\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\$
  • \$\begingroup\$ Sorry for the late accept and thanks for the improvement! \$\endgroup\$ – Konrad Höffner Oct 1 at 14:11
11
\$\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\$
  • \$\begingroup\$ Agreed. Unlike C strings, where strlen() is O(n), String::length should be fast. \$\endgroup\$ – 200_success Mar 25 '16 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\$ – Konrad Höffner Oct 1 at 14:12

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.