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

时间:2018-09-21 12:15:34

标签: java list lambda functional-programming java-stream

我有一个像下面这样的课程:

JSONParser parser = new JSONParser();
     try
        {
            Object object = parser
                    .parse(new FileReader("output_nlu_sentiment.json"));

            //convert Object to JSONObject
            JSONObject jsonObject = (JSONObject) object;

            JSONObject sentimentobject = (JSONObject) jsonObject.get("sentiment");
            JSONObject documentobject= (JSONObject) sentimentobject.get("document");

            String label = (String) documentobject.get("label");               
            System.out.println(label);   

            float score = (float) documentobject.get("score");
            System.out.println(score );
        }catch(FileNotFoundException fe)
        {
            fe.printStackTrace();
        }
     catch(Exception e)
        {
            e.printStackTrace();
        }

我还有一个如下列表:

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

现在,我想使用Java中的流在list_a中找到对象的最大长度。我创建了如下代码:

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

但是它不起作用,我的意思是语法不好。你能帮我吗?谢谢。

3 个答案:

答案 0 :(得分:2)

您使用的不是lambda。 Lambda看起来像(arguments) -> actionA::getName中的内容是method reference,但是附加的::length不是其语法的一部分。

您可以使用A::getName::length之类的lambda来代替a -> a.getName().length()

但是您的代码还有另一个问题。代码

list_a.stream()
      .max(Comparator.comparingInt(A::getName::length));

正在处理A上调用的maxStream<A>方法流,将导致Optional<A>而不是int。之所以是Optional,是因为list_a可能为空,这意味着将没有有效的结果。

如果要获取OptionalInt,则需要先map Stream<A>Stream<String>,然后mapStream of int。然后,您可以调用其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

答案 1 :(得分:2)

您可以使用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 :(得分: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使用该方法。