我有一些字符串,如果任何一个为null,那么我需要返回null。通过Stream实现此目的的方法是什么?还是有更好的方法?
protected String toCombinedString(SomeClass shipment) {
String prefix1 = ofNullable(shipment)
.map(SomeClass::getBill)
.map(Bill::getPrefixString)
.orElse(null);
String prefix2 = ofNullable(shipment)
.map(SomeClass::getBill)
.map(Bill::getPrefixString)
.orElse(null);
String number1 = ofNullable(shipment)
.map(SomeClass::getBill)
.map(Bill::getNumberString)
.orElse(null);
String number2 = ofNullable(shipment)
.map(SomeClass::getBill)
.map(Bill::getNumberString)
.orElse(null);
....
return Stream.of(prefix1, number1, prefix2, number2...)
.filter(Objects::nonNull)
.reduce((a, b) -> a + "-" + b)
.orElseGet(String::new);
}
示例输出组合:
唯一可以通过的情况是,每个String都应该为非空或非null,否则返回null
答案 0 :(得分:2)
您似乎执行了三元运算,例如:
return prefix == null || number == null ? null : prefix + "-" + number;
在问题中进行编辑之后,并且条件为仅将String
实体中的所有此类Bill
类型的属性都考虑在结果中。您可以制定一种从所有属性中提取String
的方法,如下所示:
protected String toCombinedString(SomeClass shipment) {
return Optional.ofNullable(shipment)
.map(SomeClass::getBill)
.map(bill -> extractAttributes(bill, Bill::getNumberString, Bill::getPrefixString)) // use this further
.orElse(null);
}
private String extractAttributes(Bill entity, Function<Bill, String>... mappers) {
List<String> attributes = Arrays.stream(mappers)
.map(function -> function.apply(entity))
.collect(Collectors.toList());
return attributes.stream().anyMatch(s -> s == null || s.isEmpty()) ?
null : String.join("-", attributes);
}
答案 1 :(得分:1)
您可以使用
List<String> list = Arrays.asList(prefix1, number1, prefix2, number2...);
return list.contains(null)? null: String.join("-", list);
使用Stream
不会有任何改善。临时存储的成本是相同的,因为Stream.of(…)
使用临时数组的方式与Arrays.asList(…)
或 varargs 方法通常相同。
但是考虑到每个字符串都是复杂操作的结果,最后一条语句的复杂性或简单性并没有真正的意义。
我宁愿考虑:
String prefix1 = your
long
complicated
operation;
if(prefix1 == null) return null;
String prefix2 = second
long
complicated
operation;
if(prefix2 == null) return null;
String number1 = third
long
complicated
operation;
if(number1 == null) return null;
String number2 = fourth
long
complicated
operation;
if(number2 == null) return null;
…
return String.join("-", prefix1, number1, prefix2, number2 …);
答案 2 :(得分:0)
您可以利用Java 8的Streams的 Count 功能:
Response.render
上面的代码将计算提供的字符串列表中的所有空值。
然后您可以检查计数是否大于0。如果是,则返回null。
long i = list.stream()
.filter(str -> str == null)
.count();
答案 3 :(得分:0)
我认为流会使事情复杂化,在处理数据的集合或聚合时应使用流。
这是一个不使用流的示例:
Enumerating objects: 17, done.
Counting objects: 100% (17/17), done.
Delta compression using up to 4 threads
Compressing objects: 100% (16/16), done.
Writing objects: 100% (17/17), 3.01 KiB | 440.00 KiB/s, done.
Total 17 (delta 3), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Python app detected
remote: -----> Installing python-3.6.9
remote: -----> Installing pip
remote: -----> Installing SQLite3
remote: ! Push rejected, failed to compile Python app.
remote:
remote: ! Push failed
remote: Verifying deploy...
remote:
remote: ! Push rejected to scumbotfin.
remote:
To https://git.heroku.com/scumbotfin.git
! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/scumbotfin.git'
答案 4 :(得分:0)
我确实没有看到您的用例,但是我认为此代码窃听器应该对您有用。这个想法是抛出一个异常,而不是返回一个null的可选orElse。您可以实现如下代码:
protected String toCombinedString(SomeClass shipment) {
try {
String prefix = ofNullable(shipment)
.map(SomeClass::getBill)
.map(Bill::getPrefixString)
.orElseThrow(NullPointerException::new));
String number = ofNullable(shipment)
.map(SomeClass::getBill)
.map(Bill::getNumberString)
.orElseThrow(NullPointerException::new));
.....
return Stream.of(prefix, number, prefix1, number1....)
.reduce((a, b) -> a + "-" + b);
} catch(NullPointerException e) {
return null;
}
}
为了清楚起见,您也可以将try捕获包装在该函数之外,但是这种逻辑应该可以工作,并且可以在执行过程中在遇到的第一个空值处停止执行,从而优化性能。
答案 5 :(得分:0)
如果与问题的第一个版本一样只有两个字符串,则使用三元运算是解决问题的更有效方法:
return prefix == null || number == null ? null : prefix + "-" + number;
如果您有更多项目,请使用流:
boolean hasNull = Stream.of(prefix, num).anyMatch(Objects::isNull);
return hasNull ? null : Stream.of(prefix, num).collect(Collectors.joining("-"));