标签: collectors

是否可以在使用 java 8 流的收集阶段过滤/忽略对象?

这个问题与我不久前发布的另一个问题有关。

我已经找到了一种按照我想要的方式对数据进行分组的方法。但是因为我需要对对象进行分组/映射,所以当我需要应用一些过滤时,我已经在收集期间关闭了流。我有以下代码:

final Map<TeamDetails, List<Player>> teamDetailsPlayerListMap  = 
        dbRows.stream().map(row -> mapDbRowToTeamPlayerPair(row))
                .collect(Collectors.groupingBy(TeamPlayerPair::getKey, 
                      Collectors.mapping(TeamPlayerPair::getValue, Collectors.toList())));

final List<Team> teams = teamDetailsPlayerListMap.entrySet().stream()
        .map(teamPlayerList -> mapTeamPlayerListToTeam(teamPlayerList))
        .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是某些 dbRowsStringplayerName. 我不想在收集之前过滤,就好像 aTeam没有播放器一样(例如,只有 1 db 行,播放器名称为空字符串),我仍然希望Team在最后的s列表中包含它。它只会有一个空的玩家列表。

有什么方法可以在收集过程中应用过滤器,以便不会将空字符串或空字符串添加到列表中???

我已经能够使用自定义收集器实现它,如下所示,但我只是想知道是否有办法在没有自定义收集器的情况下做到这一点???

Function<Player, Boolean> emptyPlayerNameFilter = new Function<Player, Boolean>() {
    @Override
    public Boolean apply(Player player) {
         return player != null && player.getName() != null && !"".equals(player.getName());
    }
};

final Map<TeamDetails, List<Player>> teamDetailsPlayerListMap  = 
        dbRows.stream().map(row -> mapDbRowToTeamPlayerPair(row))
        .collect(Collectors.groupingBy(TeamPlayerPair::getKey, 
                Collectors.mapping(TeamPlayerPair::getValue, 
                        MyCollectors.toFilteredLinkedList(emptyPlayerNameFilter))));

final List<Team> …
Run Code Online (Sandbox Code Playgroud)

java-8 java-stream collectors

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

java 8,List&lt;Employee&gt; 部门地图和地址列表

我有一个类似 classe User{ String Department; 的类;字符串地址;我有用户列表,我可以使用 java 8 Stream/map/collect 获得以下输出吗

List<User> userList=getUserList();

Map<String,List<String>> userAddressMap=new HashMap<String,List<String>>();

for(User user : userList){

   List<String> addressList=userAddressMap.get(user.getDepartment());

   if(addressList==null){
        userAddressMap.put(user.getDepartment(),addressList);
   }

   addressList.add(user.getAddress);
}
Run Code Online (Sandbox Code Playgroud)

java collections java-8 java-stream collectors

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

如何将流收集到 CopyOnWriteArrayList 中

我收到“不兼容的类型,必需:CopyOnWriteArrayList,找到:对象”,内容如下。我正在使用 IntelliJ 2016.1.1。

CopyOnWriteArrayList<Foo> l = fields.stream()
                                    .distinct()
                                    .collect(toCollection(CopyOnWriteArrayList::new));
Run Code Online (Sandbox Code Playgroud)

intellij-idea java-8 java-stream collectors

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

Java8 - 使用流映射而不收集性能

呈指数增长的流

我有一个Stream,生长成倍创建排列。所以每次调用都会addWeeks增加Stream.

Stream<SeasonBuilder> sbStream = sbSet.stream();

for (int i = 1; i <= someCutOff; i++) {
    sbStream = sbStream.map(sb -> sb.addWeeks(possibleWeeks))
                       .flatMap(Collection::stream); 
}

// Collect SeasonBuilders into a Set
return sbStream.collect(Collectors.toSet());   // size > 750 000 
Run Code Online (Sandbox Code Playgroud)

问题

  • 每次调用都会addWeeks返回 aSet<SeasonBuilder>并将所有内容收集到 a 中Set需要一段时间。
  • addWeeks不是静态的,需要SeasonBuilder在流中的每一个上调用,每次通过循环

    public Set<SeasonBuilder> addWeeks(
        final Set<Set<ImmutablePair<Integer, Integer>>> possibleWeeks) {
            return possibleWeeks.stream()
                    .filter(containsMatchup())   // Finds the weeks to add
                    .map(this::addWeek)   // Create new …
    Run Code Online (Sandbox Code Playgroud)

java lambda java-8 java-stream collectors

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

使用流收集器从java对象获取键值

我正在尝试使用流和集合从对象列表中获取键和值列表,但我不知道是否可能.

我有这门课:

public class MyObject {

    private int key1;

    private String key2;

    private String key3;

    public int getKey1() { return key1; }

    public void setKey1(int key1) { this.key1 = key1; }

    public String getKey2() { return key2; }

    public void setKey2(String key2) { this.key2 = key2; }

    public String getKey3() { return key3; }

    public void setKey3(String key3) { this.key3 = key3; }
}
Run Code Online (Sandbox Code Playgroud)

我想处理这个对象的列表,并用逗号分隔所有值和所有键.

List<MyObject> objectList = myObjectList;
String keys = objectList.stream().collect(Collectors.joining(", ","(", ")"));
String values = Collections.nCopies(objectList.size(), "?").stream().collect(Collectors.joining(", …
Run Code Online (Sandbox Code Playgroud)

java java-8 java-stream collectors

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

如何在java 8中使用收集器和流自动递增哈希图的键

我是 Java 8 StreamsCollectors类的新手。

我正在读取一个文件,其内容需要保存在一个文件中LinkedHashMap<Integer, String>,其中它<keys>是文件的行号,它<values>是每行的内容。

在这里,我想使用这个Stream概念,但我无法使用Collectors.toMap自动递增<keys>,它需要保存在LinnkedHashMap对象中。相反,我得到了例外。

以下是我正在尝试的代码:

List<String> list = new ArrayList<>();
Integer count = 0;

try (BufferedReader br = Files.newBufferedReader( Paths.get( fileName ) )) {
    // br returns as stream and convert it into a List
    list = br.lines().collect( Collectors.toList() );
}
catch ( IOException e ) {
    e.printStackTrace();
}

list.forEach( System.out::println );

Map<Integer, String> fileNumWithContentMapper = list.stream()
        .collect( Collectors.toMap( n->n+1,s1->s1));
Run Code Online (Sandbox Code Playgroud)

java java-8 java-stream collectors

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

将 Java Stream 映射到以对象为键的对象映射

我有一些课程,并且正在 List<WorkDay> 中做一些工作,其中包含一个 List<LedgerItem>,除了一部分之外,我一切正常。嗯,它有效,但不完全是我想要的。

public Stream<Map<WorkDay, Set<LedgerItem>>> adjustWorkDays(List<WorkDay> workDays) {        
    return workDays.stream()
            .sorted((d1,d2) -> d1.getCreated().compareTo(d2.getCreated()))
            .map(day -> createGroupByWorkDay(day))/*need it to collect here*/;
}
Run Code Online (Sandbox Code Playgroud)

如果您可以看到返回类型是,Stream<Map<WorkDay, Set<LedgerItem>>>但我想将其映射到流之外,就像Map<WorkDay, Set<LedgerItem>>使用收集器一样,但似乎无法获取Collectors.toMap()语法来执行除中断之外的任何操作。

就像我说的,一切都很完美,所以我不需要映射之外的任何东西来工作。

仅供参考:已经createGroupByWorkDay返回Map<WorkDay, Set<LedgerItem>>,但只接受一个,WorkDay因为这是一个要求,所以我无法更改其执行方式......

提前致谢

编辑:所以我所拥有的未在此处列出的方法createGroupByWorkDay可以按预期完美运行,并且永远不会改变。它返回正确的类型,Map<WorkDay, Set<LedgerItem>>但只有一个 WorkDay 的签名,就像createGroupByWorkDay(WorkDay day)原始评论中的问题方法一样,使用该方法来构建按 WorkDay 分组并返回的单个地图,但可能有 N 个这样的地图,因此方法public Stream<Map<WorkDay, Set<LedgerItem>>> adjustWorkDays(List<WorkDay> workDays)应该返回收集到收集器中的一张地图中的所有地图。如果那有意义的话?

java-8 java-stream collectors

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

尝试打印JAVA8收集器的结果时出现模糊错误

我在尝试打印JAVA8收藏家的结果时遇到Ambiguity错误.

我试图打印Product对象中的ID总和的结果,但得到以下错误:

"方法println(double)对于PrintStream类型是不明确的"

这是一小段代码,我收到编译错误:

编辑:添加代码段以获取更多详细信息:

  1. Product.java域类.

package com.sample.reproduce.bugs;

public class Product {

    private double id;

    private String productName;

    public double getId() {
        return id;
    }

    public void setId(double id) {
        this.id = id;
    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

}
Run Code Online (Sandbox Code Playgroud)
  1. 我在编译错误的Main.java类:

以下是我遇到编译错误的代码行:

System.out.println(productList.stream().collect(Collectors.summingDouble(x -> x.getId())));
Run Code Online (Sandbox Code Playgroud)

班级快照:

在此输入图像描述

如果我将在一个单独的行中使用Collector(println方法之外),我不会收到任何错误.

如果我们在println()方法中使用它,为什么编译器无法检测到JAVA 8收集器的确切返回类型?

使用命令提示符添加另一种方法的细节:

我尝试使用相同JDK版本的命令提示符,并且程序已成功编译和执行.所以Holger的答案似乎是正确的.这似乎仅适用于Eclipse编译器:

在此输入图像描述

java java-8 java-stream collectors ecj

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

为什么我不能在收集器中将 Function.identity 引用为方法引用

有人可以建议,为什么我不能在这里应用方法参考?

工作代码。

System.out.println(
                Arrays.stream(str.split(" "))
                        .collect(Collectors.groupingBy(Function.identity(),Collectors.counting())));  
Run Code Online (Sandbox Code Playgroud)

编译错误,无法解析方法

System.out.println(
            Arrays.stream(str.split(" "))
                    .collect(Collectors.groupingBy(Function::identity,Collectors::counting)));
Run Code Online (Sandbox Code Playgroud)

java java-8 java-stream method-reference collectors

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

为什么 Collectors.toUnmodifiableList 使用中间累加器的类型检查?

我看到以下代码(JDK 16、JDK 17):

    public static <T>
    Collector<T, ?, List<T>> toUnmodifiableList() {
        return new CollectorImpl<>(ArrayList::new, List::add,
                                   (left, right) -> { left.addAll(right); return left; },
                                   list -> {
                                       if (list.getClass() == ArrayList.class) { // ensure it's trusted
                                           return SharedSecrets.getJavaUtilCollectionAccess()
                                                               .listFromTrustedArray(list.toArray());
                                       } else {
                                           throw new IllegalArgumentException();
                                       }
                                   },
                                   CH_NOID);
    }
Run Code Online (Sandbox Code Playgroud)

使用if (list.getClass() == ArrayList.class) {检查有什么意义?为什么不简单地使这段代码像这样简单

return new CollectorImpl<>(ArrayList::new, ArrayList::add,                                          
                           (left, right) -> { left.addAll(right); return left; },              
                           list -> SharedSecrets.getJavaUtilCollectionAccess().listFromTrustedArray(list.toArray()),                                                                  
                           CH_NOID);                                                           
Run Code Online (Sandbox Code Playgroud)

通过替换为List::addArrayList::add我们提供了类的最具体的方法句柄,而不是接口。最后一个代码假设累加器实例将作为 …

java java-stream collectors

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