假设我有一个Optional包含Stream:
Optional<Stream<Integer>> optionalStream = Optional.of(Stream.of(1, 2, 3));
Run Code Online (Sandbox Code Playgroud)
现在我需要提取它Stream本身。如果Optional为空,您想要获得一个空的 Stream。
我正在寻找类似的东西,flatStream()可以一步执行转换。我怎样才能做到这一点?
我目前的尝试:
Stream<Integer> stream = optionalStream.stream().flatMap(Function.identity());
Run Code Online (Sandbox Code Playgroud)
在我的真实场景中,我有这样的东西,它给了我一个Stream<Optional<Foo>>:
stream.findFirst().map(e -> e.getChildren())
Run Code Online (Sandbox Code Playgroud) 我有一个Stream自定义对象作为方法的参数。显然我只能使用一次 Stream。
我的对象有一个String名为 的属性category。
public class MyType {
private String category;
// other properties, getters, etc.
}
Run Code Online (Sandbox Code Playgroud)
我需要一个分类列表List<String>。
首先,我需要根据每个类别出现的次数对数据进行排序。如果出现次数相同,则按字典顺序对这些类别进行排序。
基本上,我需要这样的东西
但我没有办法多次消费该流。所以我不知道如何解决这个问题。
这是一个例子:
输入:
{
object1 :{category:"category1"},
object2 :{category:"categoryB"},
object3 :{category:"categoryA"},
object4 :{category:"category1"},
object5 :{category:"categoryB"},
object6 :{category:"category1"},
object7 :{category:"categoryA"}
}
Run Code Online (Sandbox Code Playgroud)
输出:
List = {category1, categoryA, categoryB}
Run Code Online (Sandbox Code Playgroud) 我有以下代码,它生成一系列的总和,即1, 1+2, 1+2+3, 1+2+3+4
public static void main(String[] args) {
Stream<Integer> inputStream = Stream.of(1,2,3,4);
Iterator<Integer> iterator = inputStream.iterator();
Stream<Integer> outputStream = Stream.iterate(
iterator.next(),
i -> iterator.hasNext(),
next -> {
return iterator.next() + next;
}
);
List<Integer> outputList = outputStream.collect(Collectors.toList());
System.out.println(outputList);
}
Run Code Online (Sandbox Code Playgroud)
但这会打印:[1, 3, 6],缺少最后一个元素。
请注意,这似乎得到了我想要的正确检查,但是有更好的解决方案吗?看起来很糟糕:
public static void main(String[] args) {
Stream<Integer> inputStream = Stream.of(1,2,3,4);
Iterator<Integer> iterator = inputStream.iterator();
AtomicBoolean check = new AtomicBoolean(true);
Stream<Integer> outputStream = Stream.iterate(
iterator.next(),
i -> check.get(),
next -> { …Run Code Online (Sandbox Code Playgroud) 这是某个网站上的一个简单任务。
如果 a[i] > b[i],则 Alice 获得 1 分。如果 a[i] < b[i],则 Bob 获得 1 分。如果 a[i] = b[i],则任何人都不会得分。返回:Alice 的分数位于第一位置,Bob 的分数位于第二位置。
我可以使用流来编写这段代码吗?
public static List<Integer> compareTriplets(List<Integer> a, List<Integer> b) {
int alice = 0;
int bob = 0;
for (int i = 0; i < a.size(); i++) {
if (a.get(i) > b.get(i))
alice++;
else if (a.get(i) < b.get(i))
bob++;
}
return Arrays.asList(alice, bob);
}
Run Code Online (Sandbox Code Playgroud)
...
经过一番思考,我写了这段代码:
public static List<Integer> compareTriplets(List<Integer> a, List<Integer> b) {
Integer[] result = {0, 0};
IntStream.range(0, …Run Code Online (Sandbox Code Playgroud) 我正在寻找合适的基于流的归约操作来查找双列表的最大差异。(请不要使用旧式嵌套 for 循环的解决方案......)
假设我的双重列表是
List<Double> list = List.of(1.1, 0.3, 7.8, 1.0, 9.1, 2.3);
最大差异将导致的值
9.1 - 0.3 = 8.8
我使用 java-streams 的第一个工作方法是:
List<Double> list = List.of(1.1, 0.3, 7.8, 1.0, 9.1, 2.3);
double maxDiff = list.stream().max(Double::compareTo).get()
- list.stream().min(Double::compareTo).get();
Run Code Online (Sandbox Code Playgroud)
如何实现自定义累加器和组合器来进行归约操作Stream.reduce()以实现相同的效果?
java.util.stream 正在挑战我的字符概念。我正在尝试执行字符串的简单字符旋转,其中我只需将每个字符的 int 值加 1。我从“abcd”.chars()(一个流)开始,然后进行映射。但我似乎无法在地图期间投射 ints -> char 。为什么我没有得到想要的结果?
这是普通的 JDK17(temurin)。
jshell> "abdc".chars().map(c -> c + 1).collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
$43 ==> 9899101100
Run Code Online (Sandbox Code Playgroud)
等待; 那不是我想要的。这些是 int 值!让我们尝试一下强制转换为 char:
jshell> "abdc".chars().map(c -> (char)c + 1).collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
$44 ==> 9899101100
Run Code Online (Sandbox Code Playgroud)
好的,效果为零。让我们使用显式映射步骤:
jshell> "abdc".chars().map(c -> c + 1).map(c1 -> (char)c1).collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
$45 ==> 9899101100
Run Code Online (Sandbox Code Playgroud)
啊?哇?好的,让我们在减少步骤中强制转换:
jshell> "abcd".chars().map(c -> c + 1).collect(()->new StringBuilder(), (c,d)->c.append((char)d), (c1, c2)->c1.append(c2))
$46 ==> bcde
Run Code Online (Sandbox Code Playgroud)
最后!但为什么?为什么映射到 char 不流过流?我缺少什么?我知道这是一个新手问题,但我很乐意接受教育。
我有一个二元函数:
public Integer binaryFunction(Integer a, Integer b){
//some stuff
}
Run Code Online (Sandbox Code Playgroud)
我有这个流:
Integer fixedValue = ...
List<Integer> otherValues = ...
otherValues.map(value -> binaryFunction(value, fixedValue)).collect(...);
Run Code Online (Sandbox Code Playgroud)
我想知道如何map(this::binaryFunction)在我的流中使用。我尝试过类似的方法,但它不起作用:
values.map(value -> (value, fixedValue)).map(this::binaryFunction).collect(...);
Run Code Online (Sandbox Code Playgroud)
但这不起作用。我正在寻找可以接受两个值的供应商。
注意:我不想更改binaryFunction声明。
toList() 的实现明确返回一个 ArrayList,它确实保证了可变性:
public static <T>
Collector<T, ?, List<T>> toList() {
return new CollectorImpl<>(ArrayList::new, List::add,
(left, right) -> { left.addAll(right); return left; },
CH_ID);
}
Run Code Online (Sandbox Code Playgroud)
但是 toList 的 JavaDoc 是这样的:
/**
* Returns a {@code Collector} that accumulates the input elements into a
* new {@code List}. There are no guarantees on the type, mutability,
* serializability, or thread-safety of the {@code List} returned; if more
* control over the returned {@code List} is required, use {@link #toCollection(Supplier)}.
*
* …Run Code Online (Sandbox Code Playgroud) 我想创建一种在流中打印出信息的方法。请查看我现有的记录器方法。方法参数必须是通用的,例如在我的示例字符串和整数中。在我的情况下,该方法应该返回原始对象。有人可以告诉我当前方法有什么问题吗?
在此先多谢!
看一下记录器方法
Stream<String> stream = Stream.of("A", "BC", "XYZ");
stream.map(t -> logger(t.length()))
.map(t-> logger(t.substring(0, 2)))
.collection(Collectors.toList());
public static <T> T logger(T t) {
System.out.println(t);
return t;
}
Run Code Online (Sandbox Code Playgroud)
错误:无法推断地图的类型参数(函数)
我正在学习Java 8,遇到了一种情况。我必须在哪里遍历字符串列表,然后将它们转换为upperCase。可能的解决方案是流式处理列表。在Intellij的许多建议中,以下两项似乎很有用。
list.stream()
.map(String::toUpperCase)
Run Code Online (Sandbox Code Playgroud)
要么
list.stream().
forEach(p -> p.toUpperCase())
Run Code Online (Sandbox Code Playgroud)
我对使用哪个建议以及所有建议的用例感到困惑。我可以就所有建议使用哪种方法以及如何理解获得帮助吗?
java ×10
java-stream ×10
java-8 ×2
collections ×1
collectors ×1
compare ×1
lambda ×1
list ×1
option-type ×1
reduce ×1
reduction ×1
sorting ×1