标签: collectors

如何在java 8中使用流将一些字段收集到一个列表中?

例如,我有一个名字和姓氏的人.

我想从人员列表中收集一个字符串列表(姓名和姓氏),但似乎我不能每个列表使用两次地图或者每个列表不能使用两次流.我的代码是:

persons.stream()
   .map(Person::getName)
   .collect(Collectors.toSet())
   .stream().map(Person::getSurname) 
   .collect(Collectors.toList())
Run Code Online (Sandbox Code Playgroud)

但它一直告诉我,Person静态方法不能引用非静态方法.

我究竟做错了什么?

java java-8 java-stream collectors

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

如何在Collectors.toMap合并函数中获取密钥?

当在期间找到重复的键条目时Collectors.toMap(),(o1, o2)调用合并功能.

问题:如何获取导致重复的密钥?

String keyvalp = "test=one\ntest2=two\ntest2=three";

Pattern.compile("\n")
    .splitAsStream(keyval)
    .map(entry -> entry.split("="))
    .collect(Collectors.toMap(
        split -> split[0],
        split -> split[1],
        (o1, o2) -> {
            //TODO how to access the key that caused the duplicate? o1 and o2 are the values only
            //split[0]; //which is the key, cannot be accessed here
        },
    HashMap::new));
Run Code Online (Sandbox Code Playgroud)

在合并函数内部,我想根据来决定,如果我取消映射,或继续并接受这些值.

java java-8 collectors

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

Java 9 Collectors.flatMapping在Java 8中重写

我接触到了一个新功能,因为被称为Collectors.flatMapping分组或分区的下游.如(例子来自这里):

List<List<Integer>> list = Arrays.asList(
    Arrays.asList(1, 2, 3, 4, 5, 6), 
    Arrays.asList(7, 8, 9, 10));

Map<Integer, List<Integer>> map =list.stream()
    .collect(Collectors.groupingBy(
         Collection::size,
         Collectors.flatMapping(
             l -> l.stream().filter(i -> i % 2 == 0),
             Collectors.toList())));
Run Code Online (Sandbox Code Playgroud)

{4 = [8,10],6 = [2,4,6]}

这是一个相当优雅的方式,只使用3个收藏家.我需要在中重写收集器,但尚不支持.我尝试使用6种收集器,这种收集器使用起来 非常广泛,我无法找到使用较少的收集器的方法:

Map<Integer, List<Integer>> map = list.stream()
    .collect(Collectors.groupingBy(
        Collection::size,
        Collectors.collectingAndThen(
            Collectors.mapping(
                l -> l.stream().filter(i -> i % 2 == 0).collect(Collectors.toList()),
                Collectors.toList()),
            i -> i.stream().flatMap(j -> j.stream()).collect(Collectors.toList()))));
Run Code Online (Sandbox Code Playgroud)

是否有一个更短的仅使用更好的方法

java java-8 java-stream collectors java-9

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

如何从地图中生成具有不同值的地图(并使用 BinaryOperator 使用正确的键)?

我有一张地图Map<K, V>,我的目标是删除重复的值并Map<K, V>再次输出相同的结构。如果重复的值被发现,必须有一个选择键(k从两个键()k1k1)持有这些值,因为这个原因,假设BinaryOperator<K>kk1k2可用。

示例输入和输出:

// Input
Map<Integer, String> map = new HashMap<>();
map.put(1, "apple");
map.put(5, "apple");
map.put(4, "orange");
map.put(3, "apple");
map.put(2, "orange");

// Output: {5=apple, 4=orange} // the key is the largest possible
Run Code Online (Sandbox Code Playgroud)

用我的尝试Stream::collect(Supplier, BiConsumer, BiConsumer)非常笨拙,包含可变操作,比如Map::putMap::remove我想避免:

// // the key is the largest integer possible (following the example above)
final BinaryOperator<K> reducingKeysBinaryOperator = (k1, …
Run Code Online (Sandbox Code Playgroud)

java dictionary java-8 java-stream collectors

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

使用自定义收集器进行Java 8分组?

我有以下课程.

class Person {

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        return birthday.until(IsoChronology.INSTANCE.dateNow()).getYears();
    }

    public String getName() {
        return name;
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望能够按年龄分组,然后收集人名列表而不是Person对象本身; 所有这些都在一个很好的lamba表达式中.

为了简化所有这些,我将链接我当前的解决方案,该解决方案按年龄存储分组结果,然后迭代它以收集名称.

ArrayList<OtherPerson> members = new ArrayList<>();

members.add(new OtherPerson("Fred", IsoChronology.INSTANCE.date(1980, 6, 20), OtherPerson.Sex.MALE, "fred@example.com"));
members.add(new OtherPerson("Jane", IsoChronology.INSTANCE.date(1990, 7, 15), OtherPerson.Sex.FEMALE, "jane@example.com"));
members.add(new OtherPerson("Mark", IsoChronology.INSTANCE.date(1990, 7, 15), OtherPerson.Sex.MALE, "mark@example.com"));
members.add(new OtherPerson("George", IsoChronology.INSTANCE.date(1991, 8, 13), OtherPerson.Sex.MALE, "george@example.com"));
members.add(new OtherPerson("Bob", IsoChronology.INSTANCE.date(2000, 9, 12), OtherPerson.Sex.MALE, "bob@example.com"));

Map<Integer, List<Person>> collect = members.stream().collect(groupingBy(Person::getAge));

Map<Integer, List<String>> result = new …
Run Code Online (Sandbox Code Playgroud)

java lambda java-8 java-stream collectors

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

如何理解此Java 8 Stream collect()方法?

我试图将一个int数组转换为List,并且采取了使用Java 8 Stream的陌生路线,并提出了这个建议。

Arrays.stream(arr).boxed().collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

我仍然很难完全理解这条线,

  1. 为什么Collectors.toList()在这种情况下返回一个ArrayList<Integer>实现List接口?为什么不LinkedList<Integer>符合List接口的通用类呢?我找不到这事,除了简短提的ArrayList 这里,在API说明部分。

  2. 的左面板是什么 在此处输入图片说明 Stream.collect()意思?显然R是通用返回类型(ArrayList<Integer>在我的代码中)。而且我认为<R, A>是该方法的泛型类型参数,但是如何指定它们呢?我查看了Collector界面文档,但无法吸收它。

java list java-8 java-stream collectors

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

如果toList返回空列表,则收集器返回singletonList

我有一个很大的流管道,因此希望保持清洁.我有以下部分更大的管道

Integer defaultInt;
//...
Stream<Integer> ints;
ints.filter(/* predicate_goes_here */).collect(toSingletonIfEmptyCollector);
Run Code Online (Sandbox Code Playgroud)

toSingletonIfEmptyCollector被认为是作用于同一Collectors.toList()的确,如果它返回非emtpy列表,Collections.singletonList(defaultInt)如果Collectors.toList()返回空.

是否有更短的方法来实现它(例如,通过组合JDK中提供的标准收集器)而不是Collector从头开始实现所有方法?

java java-8 java-stream collectors

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

如何从方法Collectors.groupingBy获取有序类型的Map

我需要按类型将数据列表分成不同的列表,为此我使用构造

Map<String,List<Dish>> dishMap = menu.stream()  
         .collect(Collectors.groupingBy(Dish::getType));
Run Code Online (Sandbox Code Playgroud)

但是如何从方法"Collectors.groupingBy"获取LinkedHashMap而不是HashMap.我在javadoc中找到了一些数据但是我不能得到我必须用这个方法做的事情:

Map<String,List<Dish>> dishMap = menu.stream().collect(Collectors.groupingBy(
                Dish::getType,
                LinkedHashMap::new, ????));
Run Code Online (Sandbox Code Playgroud)

我应该在方法"groupingBy"的第三个参数中放置什么才能得到我需要的东西?

java grouping linkedhashmap java-8 collectors

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

将选项列表收集到包含当前选项的列表

我正在尝试重构一些代码以返回可选列表而不是可选。

我的班级有以下清单

private final List<Mapper<? extends Message>> mappers;
Run Code Online (Sandbox Code Playgroud)

有一个私有方法可以为这些映射器创建特征并返回消息列表

private List<Message> mapToFeature() {
        mappers.stream()
                .map(mapper -> mapper.createFeature())
                .collect(Optionals.toList());
}
Run Code Online (Sandbox Code Playgroud)

Mapper 的界面如下所示:

public interface Mapper<T extends Message> {
    Optional<T> createFeature();
}
Run Code Online (Sandbox Code Playgroud)

Optionals.toList()方法返回一个收集器以将当前选项过滤到列表中。

我想更改接口(以及所有相应的类)以返回可选列表

public interface Mapper<T extends Message> {
    List<Optional<T>> createFeature();
}
Run Code Online (Sandbox Code Playgroud)

我在Options util 中没有方法从多个列表中过滤当前选项。我如何能够在不对 util 类进行任何更改的情况下执行相同的操作?

java java-8 java-stream collectors

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

Java 16 的 Stream.toList() 和 Stream.collect(Collectors.toList()) 的区别?

JDK 16 现在toList()直接在Stream实例上包含一个方法。在以前的 Java 版本中,您总是必须使用该collect方法并提供一个Collector实例。

新方法显然需要输入更少的字符。这两种方法是否可以互换,或者是否存在应该注意的细微差别?

var newList = someCollection.stream()
    .map(x -> mapX(x))
    .filter(x -> filterX(x))
    .toList();

// vs.

var oldList = someCollection.stream()
    .map(x -> mapX(x))
    .filter(x -> filterX(x))
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

(这个问题类似于会不会 Stream.toList() 比 Collectors.toList() 表现更好,但关注行为而不是(仅)关注性能。)

java java-stream collectors java-16

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