在Java1.8流中,如何仅当至少有一个元素时在foreach之前执行逻辑 //结果可以是任何内容,错误总是以“ERROR”开头 列出结果={ “成功100-约翰行动成功”, “成功100-它也对哈利有用”, “莎莉的错误是4514。总是莎莉。” } //我希望这个输出类似 //警告:有错误 //警告:Sally出现错误4514。总是莎莉。 // //在没有错误的情况下,我不需要警告: 结果.流() .filter(name->name.startsWith(“错误”)) 。如果不为空,请执行此操作(()->LOG.warn(“有错误”) .forEach(错误->{LOG.warn(“错误:+error}

在Java1.8流中,如何仅当至少有一个元素时在foreach之前执行逻辑 //结果可以是任何内容,错误总是以“ERROR”开头 列出结果={ “成功100-约翰行动成功”, “成功100-它也对哈利有用”, “莎莉的错误是4514。总是莎莉。” } //我希望这个输出类似 //警告:有错误 //警告:Sally出现错误4514。总是莎莉。 // //在没有错误的情况下,我不需要警告: 结果.流() .filter(name->name.startsWith(“错误”)) 。如果不为空,请执行此操作(()->LOG.warn(“有错误”) .forEach(错误->{LOG.warn(“错误:+error},java,java-8,java-stream,Java,Java 8,Java Stream,如果不为空的话就这么做是一厢情愿的。我看不到一个明显的优雅的方法来处理java流。有人能想出一个好的方法吗?过滤列表: // the results can be anything, errors always start with 'ERROR' List<String> results= { "Success 100 - Operation worked John", "Success 100 - It also worked for Harry",

如果不为空的话就这么做是一厢情愿的。我看不到一个明显的优雅的方法来处理java流。有人能想出一个好的方法吗?

过滤列表:

// the results can be anything, errors always start with 'ERROR'
List<String> results= { 
    "Success 100 - Operation worked John", 
    "Success 100 - It also worked for Harry", 
    "ERROR 4514 for Sally. It's always Sally." 
}

// I want this to output something like 
//     warn: There were errors
//     warn: ERROR 4514 for Sally. It's always Sally.
//
// in the case there are no ERROR's I want no warn:'s
results.stream()
    .filter( name->name.startsWith( "ERROR" ) )
    .DO_THIS_IF_NOT_EMPTY( ()-> LOG.warn( "There were errors"; )
    .forEach( error -> { LOG.warn( "ERROR: " + error }

您可以保留一个
最终原子布尔值
,以跟踪这是否是第一个原子布尔值

if (!errors.isEmpty()) {
    LOG.warn("There were errors");
    errors.forEach(error -> LOG.warn("ERROR: " + error));
}
静态字符串[]结果={
“成功100-约翰行动成功”,
“成功100-它也对哈利有用”,
“莎莉的错误是4514。总是莎莉。”
};
公开无效测试(){
列表名称=数组.asList(结果);
final AtomicBoolean first=新的AtomicBoolean(真);
names.stream()
.filter(name->name.startsWith(“错误”))
.forEach(错误->{
if(first.getAndSet(false)){
System.out.println(“有错误”);
}
System.out.println(“错误:+错误”);
});
}

IMHO@abubakkar's是一家更好的餐厅。

你可以试试类似的东西

static String[] results = {
        "Success 100 - Operation worked John",
        "Success 100 - It also worked for Harry",
        "ERROR 4514 for Sally. It's always Sally."
};

public void test() {
    List<String> names = Arrays.asList(results);
    final AtomicBoolean first = new AtomicBoolean(true);
    names.stream()
            .filter(name -> name.startsWith("ERROR"))
            .forEach(error -> {
                if (first.getAndSet(false)) {
                    System.out.println("There were errors ");
                }

                System.out.println("ERROR: " + error);
            });
}

这里是另一个更紧凑的解决方案:

if (names.stream().anyMatch(IS_ERROR)) {
    LOG.warn("There were errors");
    names.stream().filter(IS_ERROR).forEach(LOG::warn);
}
给定:

results.stream().filter(s -> s.startsWith("ERROR")).forEach(s -> System.out.println("Warning found match: "+ s));
List<String> names = Arrays.asList(
        "Success 100 - Operation worked John",
        "Success 100 - It also worked for Harry",
        "ERROR 4514 for Sally. It's always Sally.");

Predicate<String> IS_ERROR = name -> name.startsWith("ERROR");

在这种情况下,没有内在的流操作,因此回过头来使用
迭代器是最简单的解决方案:

if (names.stream().anyMatch(IS_ERROR)) {
    LOG.warn("There were errors");
    names.stream().filter(IS_ERROR).forEach(LOG::warn);
}
Iterator it=results.stream()
.filter(name->name.startsWith(“错误”))
.iterator();
if(it.hasNext()){
LOG.warn(“有错误”);
it.forEachRemaining(error->LOG.warn(“error:+error”);
}

这就是说,记录不提供任何上下文的“there was errors”(有错误)这样的消息是没有意义的。特别是当您稍后要生成一个有意义的日志记录时,它提供了实际的消息并暗示存在错误

显然,这应该是一个标题,换句话说,您试图在日志框架的完全错误的一端进行日志文件格式化

因为没有保证这些消息在日志文件中相邻,只需考虑其他线程或子系统可能有其他日志消息,这是没有意义的。 相反,您应该使用日志分析工具,该工具能够过滤日志文件以查找来自同一来源的记录,可能会查找来自同一线程的紧随其后的记录,这使您独立于它们在日志文件中的实际位置


当工具显示至少一条匹配的记录时,你知道“有错误”…

典型。女人会因为一切而受到责备:-)@efekctive你能找到post plz吗?@Eugene不知道这是不是一个,但我最近在回答中对流与非流进行了基准测试:.TL;DR:streams在处理数万个或更多项目时是有效的。对于较小的数字,命令式循环执行better@efekctive没错,但这也是关于一个不太容易出错的程序ing范式,不鼓励副作用
LOG.warn(“有错误”)
看起来您试图在日志框架的完全错误的一端进行格式化,因为这不是真正的日志消息,而是后续消息的标题。由于无法保证这些消息在日志文件中相邻出现,因此这没有意义。相反,您应该使用日志分析工具,能够来自同一个源的日志消息几乎同时发生,而不管它们出现在日志文件中的什么位置。然后,您看到一个或多个错误日志的事实足以识别“有错误”…而不是
.size()
检查,更惯用的方法是检查
if(!errors.isEmpty())
当然可以,但是先收集然后做,然后继续(这是当前代码附带做的)我觉得有点失去了流的精神,当你有很多流的时候,会失去可读性。流的设计使得任何终端操作都会导致对流的评估。在你的情况下,如果流不是空的,当你想做什么的时候,我觉得这是一个终端操作。或者,如果你不想做什么的话如果要调整集合的大小,可以使用
迭代器()
terminal op,然后遍历迭代器。好吧,但这并不优雅,需要学习了解它是什么does@Timo我认为你编辑了错误的帖子。这是答案部分。这是老古董答案的评论部分,不是吗?这是对老古董答案的评论…这不是任务的重点ion,这是前面的“有错误”行对,我的错,我以为如果元素以Error开头,你想记录一些东西这是一个非常简单的例子,以简化问题描述。移动目标栏的答案是“有错误”"这是一个从语义上来说很有用的日志消息,它完全忽略了***点,这是一个从一个真正更大的问题上缩小的例子,你不会期望人们阅读整个问题。请假设你回复的人在处理他们的问题时有更多的智慧,而我不是处理以字符串形式为Harry、John和Sarah编写的错误代码并将其记录下来-然后,
LOG.warn
是一个选择不当的占位符,因为记录警告消息显然具有与任意代码不同的语义。无论如何,
Iterator<String> it = results.stream()
    .filter(name -> name.startsWith( "ERROR" ))
    .iterator();
if(it.hasNext()) {
    LOG.warn("There were errors");
    it.forEachRemaining(error -> LOG.warn("ERROR: " + error));
}