标签: java-stream

从可选<Stream>中提取流

假设我有一个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)

java java-stream option-type

2
推荐指数
1
解决办法
139
查看次数

Java-Stream - Java 11 中基于聚合计数的分组和排序

我有一个Stream自定义对象作为方法的参数。显然我只能使用一次 Stream。

我的对象有一个String名为 的属性category。

public class MyType {
    private String category;
    
    // other properties, getters, etc.
}
Run Code Online (Sandbox Code Playgroud)

我需要一个分类列表List<String>。

首先,我需要根据每个类别出现的次数对数据进行排序。如果出现次数相同,则按字典顺序对这些类别进行排序。

基本上,我需要这样的东西

java8流对聚合和进行分组和排序

但我没有办法多次消费该流。所以我不知道如何解决这个问题。

这是一个例子:

输入:

{
    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)

java sorting java-stream

2
推荐指数
1
解决办法
202
查看次数

流迭代不使用最后一个值

简化示例

我有以下代码,它生成一系列的总和,即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)

java java-stream

2
推荐指数
1
解决办法
325
查看次数

如何使用 Stream Java 8 按元素比较两个列表?

这是某个网站上的一个简单任务。

如果 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)

java compare list java-stream

2
推荐指数
1
解决办法
642
查看次数

实施归约运算来找到数字的最大差异?

我正在寻找合适的基于流的归约操作来查找双列表的最大差异。(请不要使用旧式嵌套 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 reduce reduction java-stream

2
推荐指数
1
解决办法
73
查看次数

在 Stream.map() 中转换为 (char) 不会产生所需的结果

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 不流过流?我缺少什么?我知道这是一个新手问题,但我很乐意接受教育。

java java-stream

2
推荐指数
1
解决办法
148
查看次数

两个对象供应商

我有一个二元函数:

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声明。

java lambda java-stream

2
推荐指数
1
解决办法
89
查看次数

为什么 Collectors.toList() 不能保证可变性

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)

java collections java-8 java-stream collectors

2
推荐指数
1
解决办法
199
查看次数

Java8流:流中的通用记录器方法

我想创建一种在流中打印出信息的方法。请查看我现有的记录器方法。方法参数必须是通用的,例如在我的示例字符串和整数中。在我的情况下,该方法应该返回原始对象。有人可以告诉我当前方法有什么问题吗?

在此先多谢!

看一下记录器方法

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 functional-programming java-8 java-stream

1
推荐指数
1
解决办法
87
查看次数

何时使用map和forEach

我正在学习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 java-stream

1
推荐指数
1
解决办法
63
查看次数