首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >修改lambda表达式中的变量

修改lambda表达式中的变量
EN

Stack Overflow用户
提问于 2015-10-30 15:33:36
回答 2查看 325关注 0票数 2

我正在尝试将for循环转换为基于java-8 forEach的语句。当循环在数组中遇到'\n‘字符并返回数组中该位置的索引时,循环就会中断。

代码语言:javascript
复制
protected Integer skipLine(byte[] buf,Integer len, Integer i) {
    for(;i<len;i++) {
        if(buf[i] == '\n') {
            newLine();
            return ++i;
        }
    }
    return i;
}

相当于Java-8:

代码语言:javascript
复制
protected Integer skipLine(byte[] buf,Integer len, Integer i) {
    IntStream stream = IntStream.range(i, len).map(j -> buf[j]); // this is necessary because there's no ByteStream
    stream.forEach(??);
    return i;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-10-30 15:39:51

下面的方法将返回所需的结果。

它创建一个从ilen排他(在range的帮助下)的len,然后过滤缓冲区的元素等于\n (借助filter)。当找到一个,newLine()就会被调用。因为我们只对第一个感兴趣,所以我们称之为findFirst()。如果没有找到,那么我们返回len (在orElse的帮助下)。

代码语言:javascript
复制
protected Integer skipLine(byte[] buf,Integer len, Integer i) {
    return IntStream.range(i, len)
                    .filter(n -> buf[n] == '\n')
                    .peek(n -> newLine())
                    .findFirst()
                    .orElse(len-1) + 1;
}

另外,您应该将输入参数更改为int而不是Integer (并且类似地,返回int而不是Integer)。

票数 4
EN

Stack Overflow用户

发布于 2015-11-01 06:26:25

不要把太多东西塞进一条小溪里。无论你在队伍中赢了什么,你都会在清楚的方面输掉。

如果你必须用英语来描述你的方法,你会说:“我想找到第一个行提要,它位于ilen (不包括len )之间。如果我找到了,我想打电话给newLine(),在linefeed之后马上返回索引。如果找不到,我只想返回len。”

考虑下面的实现,它读起来与方法的英文描述完全一样。

代码语言:javascript
复制
protected Integer skipLine(byte[] buf, Integer len, Integer i) {
    OptionalInt linefeed = IntStream.range(i, len)
            .filter(n -> buf[n] == '\n')
            .findFirst();

    if (linefeed.isPresent()) {
        newLine();
        return linefeed.getAsInt() + 1;
    } else {
        return len;
    }
}

通过使用流在linefeed之后搜索位置,然后在.orElse(len)中只有一条返回语句,您可以在不损失太多清晰度的情况下缩短它,但这是一个品味问题。

如另一个答案所建议的,请避免将peekfindFirst一起用于副作用。它依赖于未指定的行为,并可能导致惊喜。考虑以下代码(Arrays.asList的静态导入):

代码语言:javascript
复制
List<List<Integer>> numbers = asList(
        asList(1, 2), 
        asList(3, 4)
);

int one = numbers.stream()
        .flatMap(List::stream)
        .peek(System.out::println)
        .findFirst()
        .get();

这段代码输出了什么?由于您使用的是findFirst,您可能希望peek只打印流的第一个元素,即1。但是,实际上,上面的代码将打印12。peek不受约束,只对满足findFirst的元素进行严格的操作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33439630

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档