例如,我有一个名字和姓氏的人.
我想从人员列表中收集一个字符串列表(姓名和姓氏),但似乎我不能每个列表使用两次地图或者每个列表不能使用两次流.我的代码是:
persons.stream()
.map(Person::getName)
.collect(Collectors.toSet())
.stream().map(Person::getSurname)
.collect(Collectors.toList())
Run Code Online (Sandbox Code Playgroud)
但它一直告诉我,Person静态方法不能引用非静态方法.
我究竟做错了什么?
当在期间找到重复的键条目时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-9被称为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个收藏家.我需要在java-8中重写收集器,但尚不支持.我尝试使用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-8 ?
我有一张地图Map<K, V>,我的目标是删除重复的值并Map<K, V>再次输出相同的结构。如果重复的值被发现,必须有一个选择键(k从两个键()k1和k1)持有这些值,因为这个原因,假设BinaryOperator<K>给k从k1和k2可用。
示例输入和输出:
// 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::put和Map::remove我想避免:
// // the key is the largest integer possible (following the example above)
final BinaryOperator<K> reducingKeysBinaryOperator = (k1, …Run Code Online (Sandbox Code Playgroud) 我有以下课程.
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) 我试图将一个int数组转换为List,并且采取了使用Java 8 Stream的陌生路线,并提出了这个建议。
Arrays.stream(arr).boxed().collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
我仍然很难完全理解这条线,
我有一个很大的流管道,因此希望保持清洁.我有以下部分更大的管道
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从头开始实现所有方法?
我需要按类型将数据列表分成不同的列表,为此我使用构造
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"的第三个参数中放置什么才能得到我需要的东西?
我正在尝试重构一些代码以返回可选列表而不是可选。
我的班级有以下清单
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 类进行任何更改的情况下执行相同的操作?
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() 表现更好,但关注行为而不是(仅)关注性能。)
collectors ×10
java ×10
java-8 ×9
java-stream ×8
dictionary ×1
grouping ×1
java-16 ×1
java-9 ×1
lambda ×1
list ×1