java stream distinct_任意键上的Java Lambda Stream Distinct()?

参见英文答案 > Java 8 Distinct by property????????????????????????????????????22个

我经常遇到Java lambda表达式的问题,当我想在对象的任意属性或方法上使用distinct()一个流时,但想要保留对象而不是将其映射到该属性或方法.我开始创建容器,如here所讨论,但我开始做足够的事情,它变得烦人,并制作了很多样板类.

我将这个Pairing类放在一起,该类包含两个类型的两个对象,并允许您指定左,右或两个对象的键控.我的问题是……对于某些类型的关键供应商,distinct()是否真的没有内置的lambda流功能?那真让我感到惊讶.如果没有,该课程能否可靠地完成该功能?

以下是它的调用方式

BigDecimal totalShare = orders.stream().map(c -> Pairing.keyLeft(c.getCompany().getId(), c.getShare())).distinct().map(Pairing::getRightItem).reduce(BigDecimal.ZERO, (x,y) -> x.add(y));

这是配对课程

public final class Pairing {

private final X item1;

private final Y item2;

private final KeySetup keySetup;

private static enum KeySetup {LEFT,RIGHT,BOTH};

private Pairing(X item1, Y item2, KeySetup keySetup) {

this.item1 = item1;

this.item2 = item2;

this.keySetup = keySetup;

}

public X getLeftItem() {

return item1;

}

public Y getRightItem() {

return item2;

}

public static Pairing keyLeft(X item1, Y item2) {

return new Pairing(item1, item2, KeySetup.LEFT);

}

public static Pairing keyRight(X item1, Y item2) {

return new Pairing(item1, item2, KeySetup.RIGHT);

}

public static Pairing keyBoth(X item1, Y item2) {

return new Pairing(item1, item2, KeySetup.BOTH);

}

public static Pairing forItems(X item1, Y item2) {

return keyBoth(item1, item2);

}

@Override

public int hashCode() {

final int prime = 31;

int result = 1;

if (keySetup.equals(KeySetup.LEFT) || keySetup.equals(KeySetup.BOTH)) {

result = prime * result + ((item1 == null) ? 0 : item1.hashCode());

}

if (keySetup.equals(KeySetup.RIGHT) || keySetup.equals(KeySetup.BOTH)) {

result = prime * result + ((item2 == null) ? 0 : item2.hashCode());

}

return result;

}

@Override

public boolean equals(Object obj) {

if (this == obj)

return true;

if (obj == null)

return false;

if (getClass() != obj.getClass())

return false;

Pairing,?> other = (Pairing,?>) obj;

if (keySetup.equals(KeySetup.LEFT) || keySetup.equals(KeySetup.BOTH)) {

if (item1 == null) {

if (other.item1 != null)

return false;

} else if (!item1.equals(other.item1))

return false;

}

if (keySetup.equals(KeySetup.RIGHT) || keySetup.equals(KeySetup.BOTH)) {

if (item2 == null) {

if (other.item2 != null)

return false;

} else if (!item2.equals(other.item2))

return false;

}

return true;

}

}

更新:

测试斯图尔特的功能如下,它似乎工作得很好.下面的操作区分每个字符串的第一个字母.我想弄清楚的唯一部分是ConcurrentHashMap如何只维护整个流的一个实例

public class DistinctByKey {

public static Predicate distinctByKey(Function super T,Object> keyExtractor) {

Map seen = new ConcurrentHashMap<>();

return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;

}

public static void main(String[] args) {

final ImmutableList arpts = ImmutableList.of("ABQ","ALB","CHI","CUN","PHX","PUJ","BWI");

arpts.stream().filter(distinctByKey(f -> f.substring(0,1))).forEach(s -> System.out.println(s));

}

输出是……

ABQ

CHI

PHX

BWI

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值