标签: java-stream

Java 8按一对多分组

我想学习如何使用Java 8语法与流,并有点卡住.

当你为每个值都有一个键时,很容易分组.但是如果我为每个值都有一个键列表并且仍然想用groupingBy对它们进行分类呢?我是否必须将其分解为多个语句,或者可能有一些流魔术可以使其更简单.

这是基本代码:

List<Album> albums = new ArrayList<>();
Map<Artist, List<Album>> map = albums.stream().collect(Collectors.groupingBy(this::getArtist));
Run Code Online (Sandbox Code Playgroud)

如果每个专辑只有一个艺术家,那么效果很好.但我必须返回一个列表,因为专辑可以有很多艺术家.专辑和艺术家当然用于说明,我有真实世界的类型..

可能有一个简单的解决方案,但我有一段时间没有找到它,所以我呼吁这个网站代表的集体大脑来解决它.:)如果不存在简单的解决方案,也欢迎使用复杂的解决方案.

在Album类中或作为以Album作为参数的实用程序方法:

Artist getArtist(); // ok

List<Artist> getArtist(); // Not ok, since we now have many "keys" for every Album
Run Code Online (Sandbox Code Playgroud)

干杯,Mikael Grev

java grouping mapreduce java-8 java-stream

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

Java 8 Stream排序字符串列表

我在流上调用已排序的方法.而且java doc说:

"Sorted方法返回一个由该流的元素组成的流,按照自然顺序排序."

但是当我运行下面的代码时:

List<String> list = new ArrayList<String>();
list.add("b");
list.add("a");
list.add("z");
list.add("p");
list.stream().sorted();
System.out.println(list);
Run Code Online (Sandbox Code Playgroud)

我得到输出为

[b, a, z, p]
Run Code Online (Sandbox Code Playgroud)

为什么我没有获得自然排序的输出?

java sorting java-8 java-stream

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

从FileChannel读取所有行到字符串流

对于我的具体任务,我需要将数据读取FileChannel到Stream(或Collection)String的.

在常规NIO中Path我们可以使用方便的方法Files.lines(...)返回一个Stream<String>.我需要得到相同的结果,但是从而FileChannel不是Path:

public static Stream<String> lines(final FileChannel channel) {
//...
}
Run Code Online (Sandbox Code Playgroud)

任何想法如何做到这一点?

java nio java-8 java-stream

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

Java Streams:预先排序的流上的distinct()?

正如在这个问题中所讨论的那样,distinct()当运行它的流被运行时知道时,实现能够使用更有效的算法.如果我们知道流是排序的(例如,因为它来自外部预先排序的数据源,例如带有order by子句的SQL查询)但是没有标记为这样,我们如何才能获得类似的结果?有一个unordered()操作可以删除排序标志,但据我所知,没有办法告诉系统数据是在外部排序的.

java performance java-stream

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

可以使用stream.mapToObj执行多个语句

是否可以在mapToObj方法中执行多个语句?.假设我想使用以下代码将字符串转换为二进制字符串:

 String str = "hello";
 String bin = str.chars()
                  .mapToObj(x-> Integer.toBinaryString(x))
                  .collect(Collectors.joining(" "));
Run Code Online (Sandbox Code Playgroud)

但是,我想使用类似的东西处理前导零

String.format("%8s", x).replaceAll(" ", "0")
Run Code Online (Sandbox Code Playgroud)

那么,如何在mapToObj方法中添加它.我是Java 8新功能的新手.任何帮助,将不胜感激

java-8 java-stream

9
推荐指数
2
解决办法
973
查看次数

并行化REST调用的最佳方法是什么?

我正在研究一些处理多个REST调用的java代码

call1()
call2()
call3()
...
Run Code Online (Sandbox Code Playgroud)

我希望并行化这些调用,但同步执行我的主代码.我用lamba和并行流做了一个POC:

List<Runnable> list = new ArrayList();
list.add(() -> {call1()});
list.add(() -> {call2()});
list.add(() -> {call3()});
list.add(...);

list.parallelStream()
            .forEach(Runnable::run);
Run Code Online (Sandbox Code Playgroud)

你有其他解决方案吗?我还检查过使用来自Jersey客户端的异步调用,但这需要更多的代码更改.

java rest multithreading java-stream

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

迭代和复制HashMap值的有效方法

我想转换:

Map<String, Map<String, List<Map<String, String>>>> inputMap 
Run Code Online (Sandbox Code Playgroud)

到:

Map<String, Map<String, CustomObject>> customMap
Run Code Online (Sandbox Code Playgroud)

inputMap在配置中提供并准备就绪,但我需要customMap格式化。CustomObject 将通过List<Map<String, String>>在函数中使用几行代码来派生。

我已经尝试了迭代输入映射和复制 customMap 中的键值的正常方法。有没有使用 Java 8 或其他一些快捷方式来做到这一点的有效方法?

Map<String, Map<String, List<Map<String, String>>>> configuredMap = new HashMap<>();
Map<String, Map<String, CustomObj>> finalMap = new HashMap<>();


for (Map.Entry<String, Map<String, List<Map<String, String>>>> attributeEntry : configuredMap.entrySet()) {
    Map<String, CustomObj> innerMap = new HashMap<>();
    for (Map.Entry<String, List<Map<String, String>>> valueEntry : attributeEntry.getValue().entrySet()) {
        innerMap.put(valueEntry.getKey(), getCustomeObj(valueEntry.getValue()));
    }
    finalMap.put(attributeEntry.getKey(), innerMap);
}

private CustomObj getCustomeObj(List<Map<String, String>> list) {
    return new CustomObj();
}
Run Code Online (Sandbox Code Playgroud)

java collections java-8 java-stream

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

如何使用 Java Streams 仅收集最大长度的元素?

我正在尝试使用 Java StreamsString从我的列表中收集最大长度的所有s:

List<String> strings = Arrays.asList("long word", "short", "long wwww", "llll wwww", "shr");

List<String> longest = strings.stream()
            .sorted(Comparator.comparingInt(String::length).reversed())
            .takeWhile(???)
            .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

我希望 mylongest包含{"long word", "long wwww", "llll wwww"},因为那些是String具有最大长度的s。如果只有String最大长度的s之一,我显然希望结果List只包含该元素。

我试图首先对它们进行排序,以便在第一个元素中出现最大长度,但我无法检索流中第一个元素的长度。我可以尝试类似的东西peek():

static class IntWrapper {
    int value;
}

public static void main(String[] args) throws IOException {
    List<String> strings = Arrays.asList("long word", "short", "long wwww", "llll wwww", "shr");

    IntWrapper wrapper = new IntWrapper();

    List<String> longest = strings.stream()
            .sorted(Comparator.comparingInt(String::length).reversed())
            .peek(s …
Run Code Online (Sandbox Code Playgroud)

java java-stream

9
推荐指数
3
解决办法
374
查看次数

并行流是否以线程安全的方式处理上游迭代器?

parallel()然而,今天我使用的是在地图之后执行操作的流;底层源是一个非线程安全的迭代器,类似于BufferedReader.lines实现。

我原本以为 trySplit 会在创建的线程上调用,但是;我观察到对迭代器的访问来自多个线程。

例如,以下愚蠢的迭代器实现只是设置了足够的元素来导致分裂,并且还跟踪访问该hasNext方法的唯一线程。

class SillyIterator implements Iterator<String> {

    private final ArrayDeque<String> src =
        IntStream.range(1, 10000)
            .mapToObj(Integer::toString)
            .collect(toCollection(ArrayDeque::new));
    private Map<String, String> ts = new ConcurrentHashMap<>();
    public Set<String> threads() { return ts.keySet(); }
    private String nextRecord = null;

    @Override
    public boolean hasNext() {
        var n = Thread.currentThread().getName();
        ts.put(n, n);
        if (nextRecord != null) {
            return true;
        } else {
            nextRecord = src.poll();
            return nextRecord != null;
        }
    }
    @Override
    public String next() {
        if (nextRecord …
Run Code Online (Sandbox Code Playgroud)

java multithreading java-stream

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

单元测试:使用 for 循环处理集合,但不使用流处理

单元测试的问题是同一集合在流和 for 循环中的处理方式不同。两种情况下的集合都是空的(data.size() = 0),但在情况 1 中,该集合以某种方式进行了处理,换句话说,它将进入 for 循环。在情况 2 中,该集合只是被跳过(这是预期的,因为它是空的)。

测试使用 Mockito,并将Result<Record>用于 JOOQ。

测试是旧的并且没有变化,唯一的变化是从 for 循环到流。

情况1

private SearchResult iterateData(
      Result<Record> data, ...) {

      for (Record record : data) {
           doSomething(record);
    }
Run Code Online (Sandbox Code Playgroud)

案例2

private SearchResult iterateData(
      Result<Record> data, ...) {
      data.stream().forEach(record -> doSomething(record)); 
Run Code Online (Sandbox Code Playgroud)

案例 1 for 循环示例的屏幕截图

模拟结果对象

private DefaultSearchRequestModel rowSpecificValuesTestSetup(
      parameters...) {
    

    DefaultSearchRequestModel searchRequest = new DefaultSearchRequestModel(
        Arrays.asList(....),
        Collections.singletonList(
            new SearchFilter(
                "test",
                Collections.singletonList(...)));

    List<Column> columns =
        this.searchService.filterUserAllowedColumns(...);

    Condition searchCondition =
        this.searchRepositoryMock.getSearchConditions(...);

    List<TableJoinMapping> joinMappings = …
Run Code Online (Sandbox Code Playgroud)

java mockito jooq java-stream

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