我正在尝试返回由字符串中的空格分隔的数字的最大值和最小值。这是我到目前为止的内容:
public static String HighAndLow(String numbers) {
List<Integer> nums = Arrays.asList(numbers.split(" ")).stream()
.map(s -> Integer.parseInt(s))
.collect(Collectors.toList());
int max = nums.stream().reduce((a, b) -> a > b ? a : b);
int min = nums.stream().reduce((a, b) -> a < b ? a : b);
return max + " " + min;
}
但是该代码不会编译,而是返回“
error: incompatible types: Optional<Integer> cannot be converted to int
我不明白...我的代码将整数/字符串转换为可选内容是什么? map会默认执行此操作吗?或者它是我编码方式所独有的?我尝试做另一个映射以在Optional上调用get方法,但这似乎也不起作用。
答案 0 :(得分:3)
您不需要两次使用reduce
操作来获取最小值和最大值。只需在IntSummaryStatistics
上使用List<Integer>
并从此统计信息中获取Max
和Min
并摆脱处理Optional
public static String HighAndLow(String numbers) {
IntSummaryStatistics stats = Arrays.stream(numbers.split(" "))
.mapToInt(Integer::parseInt)
.summaryStatistics();
return stats.getMax() + " " + stats.getMin();
}
IntSummaryStatistics
除了max
和min
IntSummaryStatistics{count=10, sum=129, min=2, average=12.900000, max=29}
答案 1 :(得分:2)
reduce
返回一个Optional
,以便在没有任何值的情况下可以指定任何默认值。因此,要根据您的情况获取int
,您需要定义.orElse()
值,例如:
public static String highAndLow(String numbers) {
List<Integer> nums = Arrays.asList(numbers.split(" ")).stream()
.map(s -> Integer.parseInt(s))
.collect(Collectors.toList());
int max = nums.stream().reduce((a, b) -> a > b ? a : b).orElse(0);
int min = nums.stream().reduce((a, b) -> a < b ? a : b).orElse(0);
return max + " " + min;
}
答案 2 :(得分:1)
您将获得Optional<Integer>
,因为这是reduce(...)
的返回类型。它返回Optional
,因为空列表中没有减小的值。
当然,在您的情况下,不会出现空列表,因为如果numbers
为空,则numbers.split(" ")
将返回一个包含一个空字符串的数组,而Integer.parseInt(s)
将抛出{{ 1}}。
添加filter(...)
可以忽略该空值。如果输入为空,则需要确定要让方法返回的内容,例如一个空字符串。
现在您知道列表不为空,只需调用get()
即可解开NumberFormatException: For input string: ""
。
您应该使用max(...)
和min(...)
而不是调用Optional
:
reduce(...)
更好的是,不要将所有数字都装在public static String highAndLow(String numbers) {
List<Integer> nums = Arrays.asList(numbers.split(" ")).stream()
.filter(s -> ! s.isEmpty())
.map(Integer::valueOf)
.collect(Collectors.toList());
if (nums.isEmpty())
return "";
int max = nums.stream().max(Comparator.naturalOrder()).get();
int min = nums.stream().min(Comparator.naturalOrder()).get();
return max + " " + min;
}
对象中。您应该使用Integer
代替Stream<Integer>
:
IntStream
答案 3 :(得分:0)
当对流的元素执行归约运算时,它返回一个Optional描述归约值。因此, reduce操作将包装到Optional 。 这是减少操作内部实现的示例
public final Optional<P_OUT> reduce(){
boolean foundAny = false;
T result = null;
for (T element : this stream) {
if (!foundAny) {
foundAny = true;
result = element;
}else
result = accumulator.apply(result, element);
}
return foundAny ? Optional.of(result) : Optional.empty();
}
您可以直接使用reduce操作
int max1 = nums.stream().reduce(Integer::max).get();
int min1 = nums.stream().reduce(Integer::min).get();
如果您想通过其他方式获取最小值和最大值,可以在how to find maximum value from a Integer using stream in java 8?问题上看到@Tagir Valeev的答案
答案 4 :(得分:0)
public static String HighAndLow(String numbers) {
List<Integer> nums = Arrays.asList(numbers.split(" ")).stream().map(s -> Integer.parseInt(s))
.collect(Collectors.toList());
int max = nums.stream().reduce((a, b) -> a > b ? a : b).orElse(0);
int min = nums.stream().reduce((a, b) -> a < b ? a : b).orElse(0);
return max + " " + min;
}
带有一个参数的reduce()方法返回一个Optional,这是一个用于null安全的Java类,您可以使用orElse并为max和min定义想要的任何值,例如0和0,
希望有帮助