在Java 8中,如何Stream通过检查每个对象的属性的清晰度来使用API 过滤集合?
例如,我有一个Person对象列表,我想删除具有相同名称的人,
persons.stream().distinct();
Run Code Online (Sandbox Code Playgroud)
将使用Person对象的默认相等检查,所以我需要像,
persons.stream().distinct(p -> p.getName());
Run Code Online (Sandbox Code Playgroud)
不幸的是,该distinct()方法没有这种过载.如果不修改类中的相等性检查,Person是否可以简洁地执行此操作?
我的确切方案是批量插入数据库,所以我想累积DOM对象然后每1000个,刷新它们.
我通过将代码放入累加器来检测丰满度然后刷新来实现它,但这似乎是错误的 - 刷新控件应该来自调用者.
我可以将流转换为List然后以迭代方式使用subList,但这似乎也很笨拙.
有一个简洁的方法来处理每n个元素然后继续流,而只处理流一次?
是否可以将纯Jdk8中的List分区为相等的块(子列表).
我知道可以使用Guava Lists类,但是我们可以使用纯Jdk吗?我不想在我的项目中添加新的jar,仅用于一个用例.
解决方案:
tagir-valeev提出了迄今为止最好的解决方案:
我还发现了其他三种可能性,但它们只适用于少数情况:
1.Collectors.partitioningBy()将列表拆分为2个子列表 - 如下所示:
intList.stream().collect(Collectors.partitioningBy(s -> s > 6));
List<List<Integer>> subSets = new ArrayList<List<Integer>>(groups.values());
Run Code Online (Sandbox Code Playgroud)
2.Collectors.groupingBy()将我们的列表拆分为多个分区:
Map<Integer, List<Integer>> groups =
intList.stream().collect(Collectors.groupingBy(s -> (s - 1) / 3));
List<List<Integer>> subSets = new ArrayList<List<Integer>>(groups.values());
Run Code Online (Sandbox Code Playgroud)
3.分离器分离:
List<Integer> intList = Lists.newArrayList(1, 2, 3, 0, 4, 5, 6, 0, 7, 8);
int[] indexes =
Stream.of(IntStream.of(-1), IntStream.range(0, intList.size())
.filter(i -> intList.get(i) == 0), IntStream.of(intList.size()))
.flatMapToInt(s -> s).toArray();
List<List<Integer>> subSets =
IntStream.range(0, indexes.length - 1)
.mapToObj(i …Run Code Online (Sandbox Code Playgroud) 给定下面的类和数据结构,我想计算每个连续 3 个元素的计数总和,类似于以下结果:
public class SaleTxn {
private int id;
private String txnDate;
private int amount;
}
Run Code Online (Sandbox Code Playgroud)
数据如下
id txnDate amount
1 2018-10-10 100
2 2018-10-11 200
3 2018-10-12 100
4 2018-10-13 100
5 2018-10-14 200
6 2018-10-15 200
... ...
Run Code Online (Sandbox Code Playgroud)
并且窗口大小为 3,表示只是过去 3 个元素的总和,预期结果如下
2018-10-10 ~ 2018-10-12 Total: 100+200+100 = 400
2018-10-13 ~ 2018-10-14 Total: 100+200+200 = 500
...
Run Code Online (Sandbox Code Playgroud)
我在下面有一个列表代码:
List<SaleTxn> myList; //
myList.stream().filter(x -> ??????)
.mapToInt(SouthboundShareholding::getAmount)
.sum();
Run Code Online (Sandbox Code Playgroud)
我该如何实施?
我知道我可以使用Math.java函数来获取double或float的floor,ceil或round值,但我的问题是 - 如果小数点出现在我的值中,是否可以始终获得更高的整数值
例如
int chunkSize = 91 / 8 ;
Run Code Online (Sandbox Code Playgroud)
这将等于11.375
如果我将地板,天花板或圆形应用于此数字,它将返回11我想要12.
简单如果我有11.xxx我需要12,如果我有50.xxx我想要51
抱歉,chunkSize应为int
我怎样才能做到这一点?
我有哈希图: Map<String, Set<String>> myMap
我想将其拆分为包含Map以下内容的列表:
List<Map<String,Set<String>>> listofMaps;
Run Code Online (Sandbox Code Playgroud)
,每张地图最多可包含100个键。我知道如何以常规方式执行此操作。(在entryset上进行foreach,每100个项目会创建一个新地图)。有什么选择可以用Java 8 lambda或其他东西吗?(有点像Lists.partitions()..)?
我正在尝试编写一个 java 8 流收集器,它反映了rxjava 缓冲区运算符的功能
我有一个工作代码:
// This will gather numbers 1 to 13 and combine them in groups of
// three while preserving the order even if its a parallel stream.
final List<List<String>> triads = IntStream.range(1, 14)
.parallel()
.boxed()
.map(Object::toString)
.collect(ArrayList::new, accumulator, combiner);
System.out.println(triads.toString())
Run Code Online (Sandbox Code Playgroud)
这里的累加器是这样的:
final BiConsumer<List<List<String>>, String> accumulator = (acc, a) -> {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Accumulator|");
stringBuilder.append("Before: ").append(acc.toString());
int accumulatorSize = acc.size();
if (accumulatorSize == 0) {
List<String> newList = new ArrayList<>();
newList.add(a);
acc.add(newList); …Run Code Online (Sandbox Code Playgroud) java ×7
java-8 ×5
java-stream ×4
collections ×2
chunking ×1
hashmap ×1
math ×1
numbers ×1
partitioning ×1
rx-java ×1