例如,有两个列表:
List<Double> list1 = Arrays.asList(1.0, 2.0);
List<String> list2 = Arrays.asList("one_point_zero", "two_point_zero");
Run Code Online (Sandbox Code Playgroud)
使用Stream,我想创建一个由这些列表组成的映射,其中list1用于键,list2用于值.为此,我需要创建一个辅助列表:
List<Integer> list0 = Arrays.asList(0, 1);
Run Code Online (Sandbox Code Playgroud)
这是地图:
Map<Double, String> map2 = list0.stream()
.collect(Collectors.toMap(list1::get, list2::get));
Run Code Online (Sandbox Code Playgroud)
list0用于list1 :: get和list2 ::开始工作.没有创建list0有没有更简单的方法?我尝试了以下代码,但它不起作用:
Map<Double, String> map2 = IntStream
.iterate(0, e -> e + 1)
.limit(list1.size())
.collect(Collectors.toMap(list1::get, list2::get));
Run Code Online (Sandbox Code Playgroud) (这可能与/sf/answers/2121852421/有关,但我恐怕还是没有得到它.所以我这样问我的问题,希望它能够得出一个我可以更容易理解的答案.)
通常,当我有一个Stream时,我可以使用Collectors类中的一个静态方法将其转换为集合:
List<String> strings = Stream.of("this", "is", "a", "list", "of", "strings")
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
然而,类似的过程不适用于原始流,正如其他人注意到的那样:
IntStream.of(3, 1, 4, 1, 5, 9)
.collect(Collectors.toList()); // doesn't compile
Run Code Online (Sandbox Code Playgroud)
我可以这样做:
IntStream.of(3, 1, 4, 1, 5, 9)
.boxed()
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
或者我可以这样做:
IntStream.of(3, 1, 4, 1, 5, 9)
.collect(ArrayList<Integer>::new, ArrayList::add, ArrayList::addAll);
Run Code Online (Sandbox Code Playgroud)
问题是,为什么Collectors.toList()只为原始流做这个?难道没有办法指定包装类型吗?如果是这样,为什么这不起作用:
IntStream.of(3, 1, 4, 1, 5, 9)
.collect(Collectors.toCollection(ArrayList<Integer>::new)); // nope
Run Code Online (Sandbox Code Playgroud)
任何见解将不胜感激.
有一个Student类,它们有name, surname, age字段和getter.
给定一个Student对象流.
如何调用一个collect方法,使得它将返回Map键所在的位置age,Student并且值TreeSet包含surname具有此类的学生age.
我想用Collectors.toMap(),但卡住了.
我以为我可以这样做并将第三个参数传递给toMap方法:
stream().collect(Collectors.toMap(Student::getAge, Student::getSurname, new TreeSet<String>()))`.
Run Code Online (Sandbox Code Playgroud) 有一个Person对象列表.
List<Person> persons = generatePersons();
使用它创建一个unmodifiableList.
List<Person> unmodifiableList = Collections.unmodifiableList(persons);
据我所知,unmodifiableList这不支持添加/删除/设置操作.同时它不是不可变的,因为它引用了现有的可修改列表,persons并且每当对persons列表进行更改时,更改也会反映出来unmodifiableList.
以这种方式创建不可变列表.
List<Person> immutableList = Collections.unmodifiableList(new ArrayList<>(persons));
这会创建一个不可变列表,因为正在使用转换构造函数.不能执行添加/删除/设置操作,immutableList也不能persons反映原始列表中的任何更改immutableList.让我们假设Person对象也是不可变的.
现在,我想使用流创建这两个列表.
第一个,我创建使用:
List<Person> unmodifiablePersons = persons.stream()
.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
我迷失了通过流创建等效的immutableList.
我怎样才能做到这一点?
编辑:
我Person在原始列表中添加了一个新对象persons并打印了persons列表的大小和unmodifiablePersons.两者都给我相同的大小.因此,变化正在反映unmodifiablePersons,因此它不是一成不变的.我在这里错过了什么吗?
编辑2
愚蠢.本应该通过文档.unmodifiablePersons确实是一个不可改变的清单.此外,新Person对象在unmodifiablePersons创建之前添加,因此上述观察.超级傻.
你能帮帮我Java Streams吗?
正如你从标题中看到的,我需要合并List<Map<String, Map<String, Genuineness>>>到Map<String, Map<String, Genuineness>>.
该列表表示为List<Map<String, Map<String, Genuineness>>>:
[
{
"USER_1":{
"APP_1":{
"total":1,
"totalGenuine":1,
"totalDevelopment":1
}
},
"USER_2":{
"APP_1":{
"total":1,
"totalGenuine":1,
"totalDevelopment":1
},
"APP_2":{
"total":2,
"totalGenuine":2,
"totalDevelopment":2
}
}
},
{
"USER_1":{
"APP_1":{
"total":1,
"totalGenuine":1,
"totalDevelopment":1
}
},
"USER_2":{
"APP_1":{
"total":1,
"totalGenuine":1,
"totalDevelopment":1
},
"APP_2":{
"total":2,
"totalGenuine":2,
"totalDevelopment":2
}
}
}
]
Run Code Online (Sandbox Code Playgroud)
因此,正如您所看到的,重复的键可能无处不在.我的目标是Map<String, Map<String, Genuineness>>通过合并将它们组合在一起Genuineness.合并Genuineness只是意味着返回一个新的对象与总结了值total,totalGenuine和totalDevelopment.
这是我的实现失败:
final Map<String, …Run Code Online (Sandbox Code Playgroud) I have some code that I need help with ... I'm trying to build a map using two maps as a source and at the same time using java lambdas
Map<String, List<String>> motorsMapping = new HashMap<>();
motorsMapping.put("CAR", Collections.singletonList("AUDI"));
motorsMapping.put("CAR_AND_BIKE", Arrays.asList("AUDI", "BMW"));
motorsMapping.put("BIKE", Collections.singletonList("BMW"));
Map<String, List<String>> models = new HashMap<>();
models.put("AUDI", Arrays.asList("A1", "Q2"));
models.put("BMW", Arrays.asList("X1", "X5"));
motorsMapping.keySet().forEach(key -> {
Map<String, List<String>> result = new HashMap<>();
result.put(key, new ArrayList<>());
motorsMapping.get(key).forEach(value -> models.getOrDefault(value, Collections.emptyList()).forEach(property -> result.get(key).add(property)));
});
Run Code Online (Sandbox Code Playgroud)
I can do that with the …
SELECT Count(1) AS total,
'hello' AS filter,
field1 AS field1,
Count(DISTINCT field2) AS total_field2
FROM table
WHERE field = true
AND status = 'ok'
GROUP BY field1
Run Code Online (Sandbox Code Playgroud)
怀疑如何使用java8制作地图来存储以下结果。映射键必须是字段field1,映射值必须是total_field2字段。
也就是说,我需要使用字段 field1 和计数字段 field2 对列表进行分组
对于我的总字段
myList.stream().collect(Collectors.groupingBy(MyObject::getField1, Collectors.counting()))
// this is just counting the records grouped by field1
Run Code Online (Sandbox Code Playgroud)
我的结果是正确的total_field1:{4=55, 6=31}
对于 field2,我需要这样的东西,但它只是给我一个记录
myList.stream().filter(distinctByKey(MyObject::getField2))
.collect(Collectors.groupingBy(MyObject::getField1, Collectors.counting()));
public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Set<Object> seen = ConcurrentHashMap.newKeySet();
return t -> seen.add(keyExtractor.apply(t));
}
Run Code Online (Sandbox Code Playgroud)
结果total_Field2:{4=31}
应该返回 …
我有一个类CarPart定义为:
class CarPart {
String name;
BigDecimal price;
Supplier supplier;
}
Run Code Online (Sandbox Code Playgroud)
一个类Report:
class Report {
List<Part> parts;
BigDecimal total;
}
Run Code Online (Sandbox Code Playgroud)
和一个班级Part:
class Part {
String name;
String supplierName;
}
Run Code Online (Sandbox Code Playgroud)
给定 a Stream<CarPart> carParts,我需要创建一个Report对象。
我处理这个问题的想法是创建一个Map<List<Part>, BigDecimal>,其中List<Part>是转换CarPart对象的列表,BigDecimal是给定流中所有汽车零件的价格总和。之后,我可以访问Map<>包含单个条目的 ,并且可以创建一个新的Report.
我开始这样做,但我不知道如何收集它。在.map我在下面做之后,我实际上有一个,Map<Part, BigDecimal>但我需要总结Part一个列表中的所有对象,并将所有对象相BigDecimal加以创建Report.
carParts.stream()
.map(x -> {
return new AbstractMap.SimpleEntry<>(new Part(x.getName(), x.supplier.getName()), x.getPrice());
}) …Run Code Online (Sandbox Code Playgroud) 我正在尝试实现一个简单的收集器,它采用收集器列表,并同时以略有不同的方式从流中收集值。
它与 非常相似Collectors.teeing,但不同之处在于
我想要的类型签名是
public static <T, R> Collector<T, ?, List<R>> list(
final List<Collector<T, ?, R>> downstreamCollectors);
Run Code Online (Sandbox Code Playgroud)
创建此类收集器的一种方法是递归地配对发球收集器,如下所示:
public static <T, R> Collector<T, ?, List<R>> list(
final List<Collector<T, ?, R>> downstreamCollectors) {
return listrec(
Collectors.collectingAndThen(downstreamCollectors.get(0), List::of),
downstreamCollectors.stream().skip(1).toList());
}
private static <T, R> Collector<T, ?, List<R>> listrec(
final Collector<T, ?, List<R>> teedCollectors,
final List<Collector<T, ?, R>> downstreamCollectors) {
if (downstreamCollectors.size() == 0) {
return teedCollectors;
} else {
return listrec(
teeing(
teedCollectors,
downstreamCollectors.get(0),
(l, s) -> Stream.concat(l.stream(), …Run Code Online (Sandbox Code Playgroud) java functional-programming type-inference java-stream collectors
如何使用 Java Stream API 编写以下方法?
public Map<String, String> getMap() {
Map<String, String> mapB = new HashMap<>();
for (String parameterKey : listOfKeys) {
String parameterValue = mapA.get(parameterKey);
mapB.put(parameterKey, Objects.requireNonNullElse(parameterValue, ""));
}
return ImmutableMap.copyOf(mapB);
}
Run Code Online (Sandbox Code Playgroud)
我尝试过这样的事情:
return listOfKeys.stream()
.map(firstMap::get)
.collect( ? )
Run Code Online (Sandbox Code Playgroud)
但我不知道如何从这里继续。
collectors ×10
java ×9
java-stream ×9
java-8 ×7
collections ×1
grouping ×1
guava ×1
hashmap ×1
lambda ×1