【问题标题】:Filter Twice Lambda Java过滤两次 Lambda Java
【发布时间】:2014-09-06 09:10:57
【问题描述】:

我有一个列表如下"1", "2", "3", "4", "5", "6", "7"
和 预期结果必须是

"1 2" "3 4" "5 6" "7"

我知道怎么做到 7 点

我的结果

"1 2" "3 4" "5 6"

我也想知道如何输入 7。

我在过滤器中添加了i -> i == objList.size()-1,但它没有给出我想要的内容

有人知道如何解决这个问题吗? 代码:

List result = IntStream.range(0, objList.size()-1)
            .filter( i -> i % 2 == 0 || i -> i == objList.size()-1)
            .mapToObj(i -> objList.get(i) + "" + objList.get(i + 1))
            .collect(Collectors.toList());      
    result.forEach(i -> System.out.print(" " + i ));

【问题讨论】:

  • 哈哈不,不是。你知道什么样的大学在 Java 中教授 lambda。让我知道,这样我就可以去那里了哈哈
  • 我只是想在这里在 java 中应用 lambda。我已经看到了:) 你知道我们如何在这里用 lambda 修复它吗?

标签: java map filter lambda java-8


【解决方案1】:

您的第一个问题是IntStream.range(x,y)。此方法需要一个范围,该范围在开始时包括在内,在结束时不包括在内。由于您将objList.size()-1(在您的情况下为6)作为范围的结尾,因此输入列表(6)中最后一个字符串的索引被排除在IntStream和位于该索引处的字符串(“7” ) 没有出现在您的输出中。

static IntStream range(int startInclusive,
                       int endExclusive)

Returns a sequential ordered IntStream from startInclusive (inclusive) to endExclusive (exclusive) by an incremental step of 1.

API Note:

    An equivalent sequence of increasing values can be produced sequentially using a for loop as follows:


         for (int i = startInclusive; i < endExclusive ; i++) { ... }

(Source)

将其更改为IntStream.range(0, objList.size())

另一个问题是 .filter( i -&gt; i % 2 == 0 || i -&gt; i == objList.size()-1) 无法编译,因为它需要一个 lambda 表达式,而且您也不需要 || i -&gt; i == objList.size()-1 部分(因为数组的最后一个索引 6 已经是偶数) .

当然,这仍然行不通。如果你解决了这些问题,objList.get(i + 1) 在 i = 6 时会给你一个ArrayIndexOutOfBoundsException 异常。

我对最后一个问题的修复可能不是最优雅的解决方案,但这是我在这么晚的时候编译和工作的第一件事。

修复我们最终得到的(在最后一行添加了一些小格式之后):

import java.util.Arrays;
import java.util.stream.IntStream;
import java.util.stream.Collectors;
import java.util.List;

public class LambdaTest     
{
    public static void main (String[] args)
    {
        List<String> objList = Arrays.asList("1", "2", "3", "4", "5", "6", "7");
        List<String> result = IntStream.range(0, objList.size())
            .filter( i -> (i % 2) == 0)
            .mapToObj(i -> (i<objList.size()-1)?(objList.get(i) + " " + objList.get(i + 1)):objList.get(i))
            .collect(Collectors.toList());      
        result.forEach(i -> System.out.print("\"" + i + "\" "));
    } 
}

我尝试了这段代码here 并得到了预期的输出。

【讨论】:

  • 你值得被鞠躬,所以我在这里为你做 M(--)M,如果我希望我有足够的积分给你 +1
  • 只需一个问题即可更好地理解它。你能解释一下吗? '这个范围在开始时包括在内,在结束时是专有的。这就是为什么 6 被排除在外,而您的输出中没有得到“7”。”
  • @user3674428 你的列表有 7 个字符串,所以它的大小是 7,因为第一个索引是 0,最后一个是 6。 IntStream(0,6) 将返回一个包含数字 0,1 的 Stream ,2,3,4,5。 6 被排除在外,因为范围的末尾是排他的。这就是为什么你必须传递 List 的大小而不是 size-1。
  • @user3674428 这个答案似乎处理 8 个元素和处理 7 个元素一样。我没有看到任何明显的方法来简化它。可能的变化范围从 0 到 objList.size()/2,然后在适当的地方加倍,而不是过滤掉奇数。或者,将? : 条件重构为辅助方法。但这些都是风格要点,而不是基本的简化。
  • 当我将例如 8 添加到列表中时,它表现不佳。你能好心一点并运行它以便你看到吗?谢谢
猜你喜欢
  • 1970-01-01
  • 2015-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多