标签: collectors

使用Java 8流收集到Guava的ListMultiMap中

我试图使用java 8收集到ListMultiMap而不使用forEach操作.

如果我在Java 7中编写代码,它将是这样的:

ListMultimap<String, String> result = ArrayListMultimap.create();
     for(State state: states) {
      for(City city: state.getCities()) {
        result.put(state.getName(), city.getName());
      }
    }
Run Code Online (Sandbox Code Playgroud)

我在网上找到了一个网站,讨论如何创建自己的收藏家,以便在这样的场景中使用.我将此实现用于收集器.然后我写了下面的代码:

     ListMultimap<String, String> result = states
        .stream()
        .flatMap(state -> state.getCities().stream()
            .map(city -> {
              return new Pair(state, city);
            }))
        .map(pair -> {
          return new Pair(pair.first().getName(), pair.second().getName()));
        })
        .collect(MultiMapCollectors.listMultimap(
                    Pair::first,
                    Pair::second
                )
        );
Run Code Online (Sandbox Code Playgroud)

但在收集级别,我只能传递一个参数,我似乎找到了传递两个参数的方法.按照网站上的例子,我明白要使用两者,我需要在多图中存储一对"对",如下所示:

ArrayListMultimap<String, Pair> testMap = testObjectList.stream().collect(MultiMapCollectors.listMultimap((Pair p) -> p.first().getName()));
Run Code Online (Sandbox Code Playgroud)

然而,这不是我想要的,我想使用状态的名称和使用java 8的收集器(并且没有forEach)的城市名称收集到ListMultimap中.

有人可以帮助我吗?谢谢!

java guava java-8 java-stream collectors

15
推荐指数
1
解决办法
6382
查看次数

如何使用Java 8 Streams将对象属性分组并映射到另一个对象?

假设我有一组碰碰车,它们两侧有尺寸,颜色和标识符("汽车代码").

class BumperCar {
    int size;
    String color;
    String carCode;
}
Run Code Online (Sandbox Code Playgroud)

现在我需要的碰碰车映射到ListDistGroup对象,每个包含属性size,color以及List汽车代码.

class DistGroup {
    int size;
    Color color;
    List<String> carCodes;

    void addCarCodes(List<String> carCodes) {
        this.carCodes.addAll(carCodes);
    }
}
Run Code Online (Sandbox Code Playgroud)

例如,

[
    BumperCar(size=3, color=yellow, carCode=Q4M),
    BumperCar(size=3, color=yellow, carCode=T5A),
    BumperCar(size=3, color=red, carCode=6NR)
]
Run Code Online (Sandbox Code Playgroud)

应该导致:

[
    DistGroup(size=3, color=yellow, carCodes=[ Q4M, T5A ]),
    DistGroup(size=3, color=red, carCodes=[ 6NR ])
]
Run Code Online (Sandbox Code Playgroud)

我尝试了以下,实际上做了我想要它做的事情.但问题是,它物化的直接结果(成Map),我认为,也可以在做一次(可能使用mappingcollectingAndThenreducing或东西),导致更优雅的代码.

List<BumperCar> bumperCars = ...
Map<SizeColorCombination, List<BumperCar>> map …
Run Code Online (Sandbox Code Playgroud)

java grouping java-8 java-stream collectors

15
推荐指数
1
解决办法
464
查看次数

Java Streams:获取按内部映射键分组的值

我有Map<A, Map<B, C>>,我想Map<B, List<C>>使用Java Streams 从中获取.

我尝试按如下方式进行:

public <A, B, C> Map<B, List<C>> groupsByInnerKey(Map<A, Map<B, C>> input) {
    return input.values()
            .stream()
            .flatMap(it -> it.entrySet().stream())
            .collect(Collectors.groupingBy(Map.Entry::getKey));
}
Run Code Online (Sandbox Code Playgroud)

我期待的是:

  • flatMap给人StreamMap.Entry<B, C>
  • collect(Collectors.groupingBy(...))获取应用于Map.Entry<B, C>和返回的函数B,从而收集C到的值List<C>.

但它没有编译,字面意思:

无法从静态上下文引用非静态方法

Map.Entry::getKey最后一行.

有人可以解释什么是错的或什么是实现我想要的正确方法?

java grouping java-8 java-stream collectors

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

java 8 collectors的问题类型不匹配:无法从List <Object>转换为List <String>

我正在使用早期版本的java 8工作代码,我用它从列表中获取唯一值但是因为我升级到JDK 66它给了我一个错误

类型不匹配:无法转换List<Object>List<String>

List<String> instList = new ArrayList<String>();

while (res.next()) {
    instList.add(res.getString("INST").toString());
}           

List<String> instListF = instList.stream().distinct().collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

水库的结果集我是从数据库中获取,不知道什么是错的任何想法?

java java-8 collectors

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

列出<Object []>到java 8中的Map <K,V>

通常需要为以下查询转换结果:

select category, count(*)
from table
group by category
Run Code Online (Sandbox Code Playgroud)

到一个映射,其中键是类别,值是属于同一类别的记录的数量.

许多持久性框架返回此类查询的结果List<Object[]>,其中对象数组包含两个元素(类别和每个返回结果集行的计数).

我试图找到最可读的方式将此列表转换为相应的地图.

当然,传统方法包括创建地图并手动输入条目:

Map<String, Integer> map = new HashMap<>();
list.stream().forEach(e -> map.put((String) e[0], (Integer) e[1]));
Run Code Online (Sandbox Code Playgroud)

我想到的第一个单线程是利用开箱即用的Collectors.toMap收集器:

Map<String, Integer> map = list.stream().collect(toMap(e -> (String) e[0], e -> (Integer) e[1]));
Run Code Online (Sandbox Code Playgroud)

但是,我发现这种e -> (T) e[i]语法比传统方法的可读性差一点.为了解决这个问题,我可以创建一个util方法,我可以在所有这些情况下重用它:

public static <K, V> Collector<Object[], ?, Map<K, V>> toMap() {
  return Collectors.toMap(e -> (K) e[0], e -> (V) e[1]);
}
Run Code Online (Sandbox Code Playgroud)

然后我有一个完美的单行:

Map<String, Integer> map = list.stream().collect(Utils.toMap());
Run Code Online (Sandbox Code Playgroud)

由于类型推断,甚至不需要转换键和值.但是,对于代码的其他读者(Collector<Object[], ?, Map<K, V>>在util方法签名等中)来说,这有点难以理解. …

java lambda java-8 java-stream collectors

14
推荐指数
1
解决办法
2627
查看次数

收集器(Java)中的groupingby和mapping之间有什么区别?

看看这段代码.

// group by price, uses 'mapping' to convert List<Item> to Set<String>
    Map<BigDecimal, Set<String>> result =
            items.stream().collect(
                    Collectors.groupingBy(Item::getPrice,
                            Collectors.mapping(Item::getName, Collectors.toSet())
                    )
            );
Run Code Online (Sandbox Code Playgroud)

groupingBy和Mapping是否可以互换?他们的区别是什么?

对于collect()中的第三个参数,如果我使用Collectors.toList()而不是Collectors.toSet(),我会得到相同的输出类型Map吗?我听说toList()是一个更受欢迎的选项.

java java-8 java-stream collectors

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

Java 8将int的int转换为List <Integer>

我有一个字符串:

String ints = "1, 2, 3";
Run Code Online (Sandbox Code Playgroud)

我想将其转换为整数列表:

List<Integer> intList
Run Code Online (Sandbox Code Playgroud)

我可以通过这种方式将其转换为字符串列表:

List<String> list = Stream.of("1, 2, 3").collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

但不要列出整数.

有任何想法吗?

java java-8 java-stream collectors

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

Java 8 Collectors.groupingBy with map value将收集结果设置为同一个集合

示例中使用的对象来自包 org.jsoup.nodes

import org.jsoup.nodes.Attribute;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
Run Code Online (Sandbox Code Playgroud)

我需要按键的组属性和结果值Set.

Optional<Element> buttonOpt = ...;
Map<String, Set<String>> stringStringMap =
    buttonOpt.map(button -> button.attributes().asList().stream()
            .collect(groupingBy(Attribute::getKey, 
                  mapping(attribute -> attribute.getValue(), toSet()))))
            .orElse(new HashMap<>());
Run Code Online (Sandbox Code Playgroud)

它似乎正确收集,但值始终是单个字符串(因为库实现)包含按空格分割的不同值.试图改善解决方案:

Map<String, Set<HashSet<String>>> stringSetMap = buttonOpt.map(
        button -> button.attributes()
            .asList()
            .stream()
            .collect(groupingBy(Attribute::getKey, 
                        mapping(attribute -> 
                          new HashSet<String>(Arrays.asList(attribute.getValue()
                                                                .split(" "))),
                   toSet()))))
  .orElse(new HashMap<>());
Run Code Online (Sandbox Code Playgroud)

结果我有不同的结构,Map<String, Set<HashSet<String>>>但我需要Map<String, Set<String>>

我已经检查了一些收藏家,但没有解决我的问题.

问题是:

如何合并与相同属性键相关的所有集合?

java lambda java-8 java-stream collectors

14
推荐指数
3
解决办法
1152
查看次数

为什么Collectors.toMap在重复键错误上报告值而不是键?

这真的是一个关于细微问题的问题,但我的印象是在这里弄错了.如果使用Collectors.toMap-method添加重复键,则会抛出带有"重复键"消息的异常.为什么报告的价值而不是关键?甚至两个?这真的是误导,不是吗?

这是一个证明行为的小测试:

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class TestToMap {

    public static void main(String[] args) {

        List<Something> list = Arrays.asList(
            new Something("key1", "value1"),
            new Something("key2", "value2"),
            new Something("key3", "value3a"),
            new Something("key3", "value3b"));

        Map<String, String> map = list.stream().collect(Collectors.toMap(o -> o.key, o -> o.value));
        System.out.println(map);
    }

    private static class Something {
        final String key, value;

        Something(final String key, final String value){
            this.key = key;
            this.value = value;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

java java-8 java-stream collectors

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

使用Collectors.summingInt时如何获取自定义类型而不是Integer?

我目前正在创建一个Map<String, Map<LocalDate, Integer>>这样的Integer代表秒:

Map<String, Map<LocalDate, Integer>> map = stream.collect(Collectors.groupingBy(
            x -> x.getProject(),
            Collectors.groupingBy(
                x -> x.getDate(),
                Collectors.summingInt(t -> t.getDuration().toSecondOfDay())
            )
        ));
Run Code Online (Sandbox Code Playgroud)

我怎么能创建一个Map<String, Map<LocalDate, Duration>>

java grouping java-8 java-stream collectors

13
推荐指数
1
解决办法
240
查看次数

标签 统计

collectors ×10

java ×10

java-8 ×10

java-stream ×9

grouping ×3

lambda ×2

guava ×1