标签: java-stream

合并两个流

我试图实现一个方法来合并两个Streams中的值基于a Comparator的值.

我有办法做到这一点,我迭代流并将值插入到一个Stream.Builder,但我还没有弄清楚如何制作一个懒惰评估版本(许多流操作的方式),所以它可以处理无限流.

我想要它做的就是对输入数据执行单个合并传递,而不是对流进行排序(实际上,流很可能是无序的;需要保留这种混乱).

static Stream<E> merge(Stream<E> first, Stream<E> second, Comparator<E> c)
Run Code Online (Sandbox Code Playgroud)

我如何懒惰地合并这样的两个流?

如果我用两个Queues作为输入,一些Consumer作为输出,这将是相当简单的:

void merge(Queue<E> first, Queue<E> second, Consumer<E> out, Comparator<E> c){
    while(!first.isEmpty() && !second.isEmpty()
        if(c.compare(first.peek(), second.peek()) <= 0)
            out.accept(first.remove());
        else
            out.accept(second.remove());
    for(E e:first)
        out.accept(e);
    for(E e:second)
        out.accept(e);
}
Run Code Online (Sandbox Code Playgroud)

但我需要使用惰性评估和流来完成这项工作.

为了解决这些评论,这里有一些示例输入和结果:

例1:

merge(
    Stream.of(1, 2, 3, 1, 2, 3),
    Stream.of(2, 2, 3, 2, 2, 2),
    Comparator.naturalOrder()
);
Run Code Online (Sandbox Code Playgroud)

将返回一个将产生此序列的流:

1, 2, 2, 2, 3, 3, 1, 2, …
Run Code Online (Sandbox Code Playgroud)

java merge java-8 java-stream

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

字符串数组上的Java 8流

我有一个格式的字符串:

row1col1 row1col2
row2col1 row2col2
row3col1 row3col2
Run Code Online (Sandbox Code Playgroud)

等等...

我想提取每个项目并构建一个具有以下属性的对象数组:

new MyObject(row1col1, row1col2); 
Run Code Online (Sandbox Code Playgroud)

我是Java 8和Streams的新手,我想知道如何在没有循环的情况下实现这一点.

通常我会使用a String.split('\n')将行累积到String数组中

然后是一个循环,我将在空格分隔符上再次分割每一行,并使用两个元素的结果数组(row1col1 row1col2)构建我的对象,直到没有更多行要处理.

像这样:

String sausage = "row1col1 row1col2\nrow2col1 row2col2\nrow3col1 row3col2";
String[] rows = sausage.split("\n");

for (String row : rows) {
    String[] objectData = u.split("\\s+");
    MyObject myObject = new MyObject(objectData[0], objectData[1]);
    myObjectList.add(myObject);
}
Run Code Online (Sandbox Code Playgroud)

谁能解释我如何用流来实现同样的目标,那背后的机制是什么让我这样做呢?

在增加元素数量时,这甚至是一种有效的思维方式,因为从我看到的所有示例中,流程都集中在过滤,收集或通常给出一组元素检索应用一些标准的次要集合.

java arrays collections java-8 java-stream

10
推荐指数
2
解决办法
2万
查看次数

如何在Stream链中调用setter

如何在不使用forEach()的情况下调用Stream链中的setter?

List<Foo> newFoos = foos.stream()
        .filter(foo -> Foo::isBlue)
        .map(foo -> foo.setTitle("Some value")) //I am unable to use this because also changing the data type into Object
        .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

java java-8 java-stream

10
推荐指数
3
解决办法
6668
查看次数

Java 8获取列表中的所有元素

我有一个对象列表,其中每个对象返回List<String>.如何使用Java 8流只获取一个List<String>?

Contact class有以下方法;

public List<String> getSharedFriendsIds() {
    return sharedFriendsIds;
}
Run Code Online (Sandbox Code Playgroud)

我有

List<Contact> contactsList;
Run Code Online (Sandbox Code Playgroud)

我在想的是

List<String> sharedContacts = contactsList.stream()
    .map(Contact::getSharedFriendsIds)
    .sequential()
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

但上面的线不是返回 List<String>,而是 List<List<String>>我不想要的.

java java-8 java-stream

10
推荐指数
2
解决办法
2万
查看次数

在处理Java 8流管道时,对顺序()和并行()的调用顺序是否重要?

调用sequential()和parallel()更改Java 8流管道的执行方式是否放置?

例如,假设我有这样的代码:

new ArrayList().stream().parallel().filter(...).count();
Run Code Online (Sandbox Code Playgroud)

在这个例子中,很明显filter()将并行运行.但是,如果我有这个代码怎么办:

new ArrayList().stream().filter(...).parallel().count();
Run Code Online (Sandbox Code Playgroud)

是否filter()在并行运行仍然还是它按顺序运行?之所以不清楚是因为中间操作filter()是懒惰的,即它们不会在调用终端操作之前运行count().因此,在count()调用时,我们有一个并行流管道但是filter()顺序执行,因为它在调用之前到来了parallel()?

java parallel-processing java-stream

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

Java 8使用2个字段排序

根据一些条件,我从MongoDB读取数据并创建一个List<Document>带结果集.

List<Document> documentList = new ArrayList<Document>();
Run Code Online (Sandbox Code Playgroud)

样本记录看起来像:

documentList: [
    Document{
        { _id=5975ff00a213745b5e1a8ed9,
            u_id=,
            visblty = 1,
            c_id=5975ff00a213745b5e1a8ed8,                
            batchid=null,
            pdate=Tue Jul 11 17:52:25 IST 2017, 
            locale=en_US,
            subject = "Document2"
        }     },
    Document{
        { _id=597608aba213742554f537a6,
            u_id=,
            visblty = 1,
            c_id=597608aba213742554f537a3, 
            batchid=null,
            pdate=Fri Jul 28 01:26:22 IST 2017,
            locale=en_US,
            subject = "Document2"
        }    } 
]
Run Code Online (Sandbox Code Playgroud)

使用此documentList,我再次使用某些条件进行过滤,然后我需要根据某些条件(我将在请求中获取)对过滤器记录进行排序.

List<Document> outList = documentList.stream()
                .filter(d -> d.getInteger("visblty") == 1
                && (!StringUtils.isEmpty(req.pdate())? (d.getDate(CommonConstants.PDATE).after(afterDate)): true) 
                && (!StringUtils.isEmpty(req.pdate())? (d.getDate(CommonConstants.PDATE).before(beforeDate)): true)
                .sorted().skip(4).limit()
                .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

不确定如何排序(动态需要根据输入更改排序顺序,它看起来像" pdate by DESC"或" subject …

java sorting java-8 java-stream

10
推荐指数
3
解决办法
1万
查看次数

Java 8 - 如何声明对返回void的未绑定非静态方法的方法引用

这是一个简单的类,说明了我的问题:

package com.example;

import java.util.function.*;

public class App {

    public static void main(String[] args) {
        App a1 = new App();

        BiFunction<App, Long, Long> f1 = App::m1;
        BiFunction<App, Long, Void> f2 = App::m2;

        f1.apply(a1, 6L);
        f2.apply(a1, 6L);
    }

    private long m1(long x) {
        return x;
    }

    private void m2(long x) {
    }
}
Run Code Online (Sandbox Code Playgroud)

f1,指的是App::m1,和被绑定到a1中f1的来电apply,工作完全正常-编译器是幸福的呼叫可以通过f1.apply就好制成.

f2,指App::m2,不起作用.

我希望能够定义一个没有返回类型的未绑定非静态方法的方法引用,但我似乎无法使其工作.

java void java-8 java-stream method-reference

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

Java Collectors.toMap的内存优化

我有一个将列表转换为地图的功能.调用此函数后,映射的大小不会更改.我正在尝试在以下两个实现之间做出决定:

Map<Long, Object> listToMap(List<Object> objs) {
        /* Implementation One: */

        Map<Long, Object> map = new HashMap<>(objs.size(), 1);
        for (Object obj : objs) {
            map.put(obj.getKey(), obj);
        }
        return map;

        /* Implementation Two: */

        return objs.stream().collect(Collectors.toMap(Object::getKey, obj -> obj));

    }
Run Code Online (Sandbox Code Playgroud)

在第一个实现中,我通过使用1的加载因子和列表的大小为所有元素分配了足够的内存.这确保不会执行调整大小操作.然后,我遍历列表并逐个添加元素.

在第二个实现中,我使用Java 8流来提高可读性.

我的问题是:第二个实现是否会涉及HashMap的多个调整大小,还是已经过优化以分配足够的内存?

java java-8 java-stream

10
推荐指数
2
解决办法
580
查看次数

Java Stream Grouping可以收集自定义对象

我有温度等级

class Temperature {
    double minTemp;
    double maxTemp;
    String city;
    String country;
}
Run Code Online (Sandbox Code Playgroud)

我有另一个维护温度集合的类

class Temperatures {
    List<Temperature> temperatures;
}
Run Code Online (Sandbox Code Playgroud)

我想使用streams对countryName进行分组.

我想要的是

public Map<String, Temperatures> temperaturesByCountry()
Run Code Online (Sandbox Code Playgroud)

但我无法使用流将温度作为地图值,我得到的是温度列表.

我的分组实现如下

Map<String, List<Temperature>> result = this.getTemperatures()
                .stream()
                .collect(Collectors.groupingBy(Temperature::getCountry));
Run Code Online (Sandbox Code Playgroud)

我想要Map<String, Temperatures>而不是Map<String, List<Temperature>>

我怎样才能做到这一点.

java grouping hashmap java-8 java-stream

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

在带有流的List中找到与目标相距n步的值

假设我有一个简单的列表:

List<String> listOne = Arrays.asList("str1", "result1", "test", "str4", "result2", "test", "str7", "str8");
Run Code Online (Sandbox Code Playgroud)

目标是"测试",我想将目标之前的值添加到新列表中,因此输出将是[result1, result2].

使用类似的东西添加"测试"值很容易,listTwo = listOne.stream().filter(i -> i.equals("test")).collect(Collectors.toList());但是如何根据目标的位置获取其他值(在我的示例中,它只是目标之前的元素)

我试着只是改变了i到i - 1但没有采取任何行动.

我知道我可以用一个简单的for循环来做,但只是想知道如何在流中应用相同的逻辑.

for (int i = 1; i < listOne.size(); i++) {
    if (listOne.get(i).equals("test")) {
        listTwo.add(listOne.get(i - 1));
    }
}
Run Code Online (Sandbox Code Playgroud)

java java-stream

10
推荐指数
2
解决办法
99
查看次数