我试图使用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中.
有人可以帮助我吗?谢谢!
假设我有一组碰碰车,它们两侧有尺寸,颜色和标识符("汽车代码").
class BumperCar {
int size;
String color;
String carCode;
}
Run Code Online (Sandbox Code Playgroud)
现在我需要的碰碰车映射到List的DistGroup对象,每个包含属性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),我认为,也可以在做一次(可能使用mapping或collectingAndThen或reducing或东西),导致更优雅的代码.
List<BumperCar> bumperCars = ...
Map<SizeColorCombination, List<BumperCar>> map …Run Code Online (Sandbox Code Playgroud) 我有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给人Stream的Map.Entry<B, C>collect(Collectors.groupingBy(...))获取应用于Map.Entry<B, C>和返回的函数B,从而收集C到的值List<C>.但它没有编译,字面意思:
无法从静态上下文引用非静态方法
在Map.Entry::getKey最后一行.
有人可以解释什么是错的或什么是实现我想要的正确方法?
我正在使用早期版本的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)
当水库的结果集我是从数据库中获取,不知道什么是错的任何想法?
通常需要为以下查询转换结果:
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方法签名等中)来说,这有点难以理解. …
看看这段代码.
// 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()是一个更受欢迎的选项.
我有一个字符串:
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)
但不要列出整数.
有任何想法吗?
示例中使用的对象来自包 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>>
我已经检查了一些收藏家,但没有解决我的问题.
如何合并与相同属性键相关的所有集合?
这真的是一个关于细微问题的问题,但我的印象是在这里弄错了.如果使用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) 我目前正在创建一个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>>?