如何使用Java流在字符串列表中查找最大长度?

4

我有一个如下的类:

public class A
{
    String name;
    String getName(){return name;}
}

我也有一个类似下面的列表:

List<A> list_a = new ArrayList<>();
//add n objects into list_a

我想使用Java中的流查找列表list_a中对象的最大长度。我已经编写了以下代码:

final int max_len = list_a.stream().max(Comparator.comparingInt(A::getName::length));

但是它不能工作,我的意思是语法有问题。你能帮我吗?谢谢。
3个回答

7
你正在使用的不是 lambda。Lambda 的格式如下: (arguments) -> action。在A::getName中,你所拥有的是方法引用,但是额外的::length并不是它语法的一部分。
相反,你可以使用如下的lambda表达式:a -> a.getName().length()代替A::getName::length
但是,你的代码还存在另一个问题。
list_a.stream()
      .max(Comparator.comparingInt(A::getName::length));

处理流的 Amax 方法被调用于 Stream<A> 上将导致结果为 Optional<A> 而不是 int。这是因为存在 list_a 可能为空的情况,这意味着可能没有有效的结果。
如果您想获得 OptionalInt,则需要将 Stream<A> 映射到 Stream<String>,然后首先将其映射到 Stream of ints。 然后您可以调用其 max() 方法并获得:
OptionalInt maxOpt  = list_a.stream()
                            .map(A::getName)
                            .mapToInt(String::length)
                            .max();

当您已经拥有OptionalInt时,您可以使用它来检查值是否存在isPresent()并通过getAsInt()获取它。您还可以使用orElse(defaultValueIfEmpty)
int max = maxOpt.orElse(-1); //will return value held by maxOpt, or -1 if there is no value

5
您可以使用 IntStream,因为您只需要查找最大长度:
OptionalInt oi = list_a.stream()
                 .map(A::getName)
                 .mapToInt(String::length)
                 .max()

final int max_len = oi.orElse(0); //defaulting to 0

如果需要使用自定义比较器,您需要使用lambda表达式:

final int max_len = list_a.stream()
                .max(Comparator.comparingInt(a -> 
                     a.getName().length())) //need a lambda
                .map(A::getName)
                .map(String::length)
                .orElse(0); //defaulting to 0

2

使用Collections.max的另一种解决方案:

A a = Collections.max(list_a, Comparator.comparing(obj -> obj.getName().length()));
int maxLen = a.getName().length();

请注意,如果集合为空,则Collections.max将抛出NoSuchElementException。如果您不想这样,请使用像@Pshemo答案中的OptionalInt方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接