标签: java-stream

将元素从Stream添加到现有List的更好方法是什么?

我必须编写一些代码,将Java 8 Stream的内容多次添加到List中,而且我很难弄清楚最好的方法是什么.基于我在SO上阅读的内容(主要是这个问题:如何将Java8流的元素添加到现有List中)和其他地方,我将其缩小到以下选项:

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

public class Accumulator<S, T> {


    private final Function<S, T> transformation;
    private final List<T> internalList = new ArrayList<T>();

    public Accumulator(Function<S, T> transformation) {
        this.transformation = transformation;
    }

    public void option1(List<S> newBatch) {
        internalList.addAll(newBatch.stream().map(transformation).collect(Collectors.toList()));
    }

    public void option2(List<S> newBatch) {
        newBatch.stream().map(transformation).forEach(internalList::add);
    }
}
Run Code Online (Sandbox Code Playgroud)

我们的想法是,对于同一个实例,将多次调用这些方法Accumulator.选择是在使用中间列表和Collection.addAll()在流外部调用一次还是collection.add()从流中为每个元素调用之间.

我倾向于更喜欢选项2,这更符合函数式编程的精神,并且避免创建中间列表,但是,当n很大时调用addAll()而不是调用add()n次可能有好处.

两种选择中的一种明显优于另一种吗?

编辑:JB Nizet有一个非常酷的答案,延迟转换,直到所有批次都添加.在我的情况下,需要直接执行转换.

PS:在我的示例代码中,我用作transformation占位符,用于需要在流上执行的任何操作

java collections java-8 java-stream

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

Java 8将多个文件平面映射到行

给定一组文件名:

bigList = Arrays.stream(files)
    .flatMap(file - > {
        try {
            return Files.lines(Paths.get(path + SEPARATOR + file));
        } catch (IOException e) {
            LOGGER.log(Level.WARNING, "No se puede encontrar el archivo " + file);
        }
        return null;
    })
    .filter(str - > str.startsWith("ABC"))
    .distinct()
    .map(Mapper::mapToObj)
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

当我使用传统的for循环时(而不是Arrays.stream(..).flatMap(..)),这会返回不同的输出

for (String file: files) {
    bigList.addAll(Files.lines(Paths.get(path + SEPARATOR + file))
        .filter(str - > str.startsWith("ABC"))
        .distinct()
        .map(Mapper::mapToObj)
        .collect(Collectors.toList()));
}
Run Code Online (Sandbox Code Playgroud)

为什么会这样?

提前致谢

干杯

java-8 java-stream

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

java8 stream不会更改类成员

我有这个代码:

Set<String> namesSet = new HashSet<>();

@Override
public boolean isValid(List<String> input) {
    input.stream().map(item -> namesSet.add(item));
    return namesSet.size() == input.size();
}
Run Code Online (Sandbox Code Playgroud)

input 是一个包含一个项目的列表.

为什么这个项目没有被添加到namesSet之后stream::map呢?

这里更新是我的修复:

Set<String> namesSet;

@Override
public boolean isValid(List<String> input) {
    namesSet = new HashSet<>();
    input.stream().forEach(item -> namesSet.add(item));
    return namesSet.size() == input.size();
}
Run Code Online (Sandbox Code Playgroud)

java java-8 java-stream

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

Java流:找到两个流之间不同的第一个项目

假设我有两个具有相似但不一定相同内容的流.如何找到两者之间不同的第一个项目.例如,假设我有:

Stream<String> first = Arrays.asList("a", "b", "c").stream();
Stream<String> second = Arrays.asList("a", "x", "c").stream ();
Run Code Online (Sandbox Code Playgroud)

如何确定"b"和"x"是流不同的第一个项目?如果其中一个流被截断呢?

java java-stream

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

如何使用Java 8转换Map的每个条目集的键和值?

我有一个Map<String, String>我想转换为Map<Type1,Type2>使用Java流的.

这是我尝试过但我认为我的语法错误:

myMap.entrySet()
.stream()
.collect(Collectors.toMap(e -> Type1::new Type1(e.getKey()), e -> Type2::new Type2(e.getValue))));
Run Code Online (Sandbox Code Playgroud)

也试过了

myMap.entrySet()
    .stream()
    .collect(Collectors.toMap(new Type1(Map.Entry::getKey), new Type2(Map.Entry::getValue));
Run Code Online (Sandbox Code Playgroud)

但我只是继续运行编译错误.我该如何改造?

java hashmap java-8 java-stream

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

如何通过值集合流式传输?

如何流式传输Map<String, List<String>>获取:

  1. 甲List<String>所有的String的值s List的第Map它们比5个字符?如何长期计算这些?

  2. 甲Map<String, List<String>>其中密钥保持不变,但List小号仅由String长度大于5号第?

  3. A 在每张地图的密钥中有多于5的Map<String, Long>计数?StringList

我开始做的事情但我被困住了:

long l = map.entrySet().stream()
            .filter(m -> m.getValue().stream().filter(s -> s.length() > 5)
Run Code Online (Sandbox Code Playgroud)

谢谢

java collections java-8 java-stream

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

从一个列表中提取多个字段并将其保存到另一个列表或相同类型的新列表.在java 8中

我有一个用户List<User>"abc" 的列表.

class User {
int id;
String name;
String address;
.....//getters and setters
}
Run Code Online (Sandbox Code Playgroud)

我只需要从中提取名称和地址List<User>并保存到另一个新的列表对象List<User>"xyz".或者一些新的列表,它有两个字符串字段的名称和地址.例如:

class SomeClass {
String name;
String address;
........//getters and setters
}
Run Code Online (Sandbox Code Playgroud)

我知道可以通过迭代原始列表并保存到另一个新列表对象来完成.但我想知道如何Java 8更有效地完成它.通过使用streams(),map()...等使用默认构造函数.

java list java-8 java-stream

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

Java8流式类层次结构

我正在慢慢学习Java 8的新功能,并试图找到一种以流方式处理类层次结构(从子级到父级)的方法。

例如,在类或其父级上找到注释。

在Java 8之前,我会这样完成:

public static <T extends Annotation> T getAnnonationOn(Class<?> type, Class<T> annType) {
    Class<?> t = type;
    T annot = null;
    while (t != null && annot == null) {
        annot = t.getAnnotation(annType);
        t = t.getSuperclass();
    }
    return annot;
}
Run Code Online (Sandbox Code Playgroud)

现在,我希望以一种更加“功能性的编程”方式来做到这一点。我找不到比使用以下递归连接流更好的方法:

import java.lang.annotation.Annotation;
import java.util.stream.Stream;

public static <T extends Annotation> T getAnnonationOn(Class<?> type, Class<T> annType) {
    return ClassIterator.streamSuperclass(type)
        .map(t -> t.getAnnotation(annType))
        .filter(a -> a != null)
        .findFirst()
        .orElse(null);
}

public static class ClassIterator {
    public static Stream<Class<?>> …
Run Code Online (Sandbox Code Playgroud)

reflection java-8 java-stream

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

findFirst()用于Java流,但是对于n个元素?

我想从流中收集前n个元素,而不是遍历整个事物.是否有标准方法可以做到这一点?翼

MyList.stream()
  .filter(x -> predicate(x))
  .findFirstN(100)
Run Code Online (Sandbox Code Playgroud)

会从流中返回最多100个元素的集合吗?我的另一种方法是评估整个流,然后从结果中进行采样,但这并没有利用流固有的惰性评估.

java lazy-evaluation java-8 java-stream

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

Java8流集合中对象属性的平均值

我是Java的新手,所以如果已经在其他地方回答了这个问题,那么我要么不知道搜索正确的内容还是我无法理解答案.

所以问题是:我在列表中有一堆对象:

try(Stream<String> logs = Files.lines(Paths.get(args))) {

        return logs.map(LogLine::parseLine).collect(Collectors.toList());


    }
Run Code Online (Sandbox Code Playgroud)

这就是添加属性的方式:

        LogLine line = new LogLine();
    line.setUri(matcher.group("uri"));
    line.setrequestDuration(matcher.group("requestDuration"));
    ....
Run Code Online (Sandbox Code Playgroud)

如何对日志进行排序,以便最终得到列表,其中具有相同"uri"的对象仅以平均requestDuration显示一次.

例:

         object1.uri = 'uri1', object1.requestDuration = 20;
         object2.uri = 'uri2', object2.requestDuration = 30;
         object3.uri = 'uri1', object3.requestDuration = 50;
Run Code Online (Sandbox Code Playgroud)

结果:

        object1.uri = 'uri1', 35;
        object2.uri = 'uri2', 30;
Run Code Online (Sandbox Code Playgroud)

提前致谢!

sorting collections average java-8 java-stream

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