Nicksxs's Blog

What hurts more, the pain of hard work or the pain of regret?

在目前的房子也差不多租了四五年了,楼下邻居换了两拨了,我们这栋楼装修了不知道多少次,因为是学区的原因,房子交易的频率还是比较高的,不过比较神奇的我们对门的没换过,而且一直也没什么交集(除了后面说的水管爆裂),就进出的时候偶尔看到应该是住着一对老夫妻,感觉年纪也有个七八十了。

对对面这户人家的印象,就是对面的老头子经常是我出门上班去了他回来,看着他颤颤巍巍地走楼梯,我看到了都靠边走,而且有几次还听见好像是他儿子在说他,”年假这么大了,还是少出去吧”,说实话除了这次的事情,之前就有一次水管阀门爆裂了,算是有点交集,那次大概是去年冬天,天气已经很冷了,我们周日下午回来看到楼梯有点湿,但是没什么特别的异常就没怎么注意,到晚上洗完澡,楼下的邻居就来敲门,说我们门外的水表那一直在流水,出门一看真的是懵了,外面水表那在哗哗哗地流水,导致楼梯那就跟水帘洞一样,仔细看看是对面家的水表阀门那在漏水,我只能先用塑料袋包一下,然后大冬天(刚洗完澡)穿着凉拖跑下去找物业保安,走到一楼的时候发现水一直流到一楼了,楼梯上都是水流下来,五楼那是最惨的,感觉门框周边都浸透了,五楼的也是态度比较差的让我一定要把水弄好了,但是前面也说了谁是从对门那户的水表阀那出来的,理论上应该让对面的处理,结果我敲门敲了半天对面都没反应,想着我放着不管也不太好,就去找了物业保安,保安上来看了只能先把总阀关了,我也打电话给维修自来水管的,自来水公司的人过了会也是真的来修了,我那会是挺怕不来修,自来水公司的师傅到了以后拿开一看是对面那户的有个阀门估计是自己换上去的,跟我们这的完全不一样,看上去就比较劣质,师傅也挺气的,大晚上被叫过来,我又尝试着去敲门也还是没人应,也没办法,对面老人家我敲太响到时候出来说我吓到他们啥的,第二天去说也没现场了。

前面的这件事是个重要铺垫,前几天 LD 下班后把厨余垃圾套好袋子放在门口,打算等我下班了因为要去做核酸(hz 48 小时核酸)顺便带下去,结果到了七点多,说对面的老太太在那疯狂砸门了,LD 被吓到了不敢开门,老太太在外面一边砸门一边骂,“你们年轻人怎么素质这么差”(他们家也经常在门口放垃圾,我们刚来住的时候在楼梯转角他们就放这个废弃的洗衣机,每次走楼梯带点东西都要小心翼翼地走,不然都过不去,然后我赶紧赶回去,结果她听到我回家了,还特意开门继续骂,“你们年轻人怎么素质这么差,垃圾放在这里”,我说我们刚才放在这,打算待会做核酸的时候去扔掉,结果他们家老头,都已经没了牙齿,在那瞪大眼睛说,“你们早上就放在这了的,”我说是LD 刚才下班了放的,争论了一会,我说这个事情我们门口放了垃圾,这会我就去扔掉了,但是你们家老太太这么砸门总不太好,像之前门口水管爆掉了,我敲了门没人应,我也没要砸门一定把你们叫醒,结果老头老太说我们的水管从来没换过,不可能破的(其实到这,再往后说就没意思了,跟这么不要脸的人说多了也只是瞎扯),一会又回到这个垃圾的问题,那个老头说“你们昨天就放在这里了的”,睁着眼说瞎话可真是 666,感觉不是老太太拦着点他马上就要冲上来揍我了一样,事后我想想,这种情况我大概只能躺地上装死了,当这个事情发生之前我真的快把前面说的事情(水管阀坏了)给忘了,虽然这是理论上不该我来处理,除非是老头老太太请求我帮忙,这事后面我也从没说起过,本来完全没交集,对他们的是怎么样的人也没概念,总觉得年纪大了可能还比较心宽和蔼点,结果没想到就是一典型的坏人变老了,我说你们这么砸门,我老婆都被吓得不敢开门,结果对面老头老太太的儿子也出来了说,“我们就是敲下门,我母亲是机关单位退休的,所以肯定不会敲门很大声的,你老婆觉得吓到了是你们人生观价值观有问题”,听到这话我差点笑出来,连着两个可笑至极的脑残逻辑,无语他妈给无语开门,无语到家了。对门家我们之前有个印象就是因为我们都是顶楼,这边老小区以前都是把前后阳台包进来的,然后社区就来咨询大家的意见是不是统一把包进来的违建拆掉,还特地上来六楼跟他们说,结果对面的老头就说,“我要去住建局投诉你们”,本来这个事情是违法的,但是社区的意思也是征求各位业主的意见,结果感觉是社区上门强拆了一样,为老不尊,坏人变老了的典范了。

我们日常在代码里处理一些集合逻辑的时候用到 Stream 其实还挺多的,普通的取值过滤集合一般都是结合 ide 的提示就能搞定了,但是有些不太常用的就在这记录下,争取后面都更新记录下来。

自定义 distinctByKey 对结果进行去重

stream 中自带的 distinct 只能对元素进行去重
比如下面代码

1
2
3
4
5
6
7
8
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(1);
list.add(2);
list = list.stream().distinct().collect(Collectors.toList());
System.out.println(list);
}

结果就是去了重的

1
[1, 2]

但是当我的元素是个复杂对象,我想根据对象里的某个元素进行过滤的时候,就需要用到自定义的 distinctByKey 了,比如下面的想对 userId 进行去重

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public static void main(String[] args) {
List<StudentRecord> list = new ArrayList<>();
StudentRecord s1 = new StudentRecord();
s1.setUserId(11L);
s1.setCourseId(100L);
s1.setScore(100);
list.add(s1);
StudentRecord s2 = new StudentRecord();
s2.setUserId(11L);
s2.setCourseId(101L);
s2.setScore(100);
list.add(s2);
StudentRecord s3 = new StudentRecord();
s3.setUserId(12L);
s3.setCourseId(100L);
s3.setScore(100);
list.add(s3);
System.out.println(list.stream().distinct().collect(Collectors.toList()));
}
@Data
static class StudentRecord {
Long id;
Long userId;
Long courseId;
Integer score;
}

结果就是

1
[StudentRecord(id=null, userId=11, courseId=100, score=100), StudentRecord(id=null, userId=11, courseId=101, score=100), StudentRecord(id=null, userId=12, courseId=100, score=100)]

因为对象都不一样,所以就没法去重了,这里就需要用

1
2
3
4
5
6
public static <T> Predicate<T> distinctByKey(
Function<? super T, ?> keyExtractor) {

Map<Object, Boolean> seen = new ConcurrentHashMap<>();
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}

然后就可以用它来去重了

1
System.out.println(list.stream().filter(distinctByKey(StudentRecord::getUserId)).collect(Collectors.toList()));

看下结果

1
[StudentRecord(id=null, userId=11, courseId=100, score=100), StudentRecord(id=null, userId=12, courseId=100, score=100)]

但是说实在的这个功能感觉应该是 stream 默认给实现的

使用 java.util.stream.Collectors#groupingBy 对 list 进行分组

这个使用场景还是蛮多的,上面的场景里比如我要对 userId 进行分组,就一行代码就解决了

1
System.out.println(list.stream().collect(Collectors.groupingBy(StudentRecord::getUserId)));

结果

1
{11=[StudentRecord(id=null, userId=11, courseId=100, score=100), StudentRecord(id=null, userId=11, courseId=101, score=100)], 12=[StudentRecord(id=null, userId=12, courseId=100, score=100)]}

很方便的变成了以 userId 作为 key,以相同 userIdStudentRecordList 作为 valuemap 结构

因某国际大都市的给力表现,昨儿旁边行政区启动应急响应,同事早上就在群里说要去超市买菜了,到了超市人还特别多,由于来的就是我们经常去的那家超市,一方面为了安全,另一方面是怕已经抢不到了,就去了另一家比较远的超市,开车怕没车位就骑了小电驴,还下着小雨,结果到了超市差不多 12 点多,超市里出来的人都是推着一整车一整车的物资,有些比较像我,整箱的泡面,好几提纸巾,还有各种吃的,都是整箱整箱的,进了超市发现结账包括自助结账的都排很长的队,到了蔬菜货架附近,差点哼起那首歌“空空如也~”,新鲜蔬菜基本已被抢空,只剩下一些卖相不太好的土豆番薯之类的,也算是意料之外情理之中了,本来以为这家超市稍微离封控区远一些会空一点,结果就是所谓的某大都市封控了等物资,杭州市是屯了物资等封控,新鲜蔬菜没了我们也只能买点其他的,神奇的是水果基本都在,可能困难时期水果不算必需品了?还是水果基本人人都已经储备了很多,不太能理解,虽然水果还在,但是称重的地方也还有好多人排队,我们采取了并行策略,LD 在那排队,遥控指挥我去拿其他物资,拿了点碱水面,黑米,那黑米的时候还闹了个乌龙,因为前面就是散装鸡蛋的堆货的地方,结果我们以为是在那后面排队,结果称重那个在那散步了,我们还在那排队,看到后面排队,那几个挑的人也该提醒下吧,几个鸡蛋挑了半天,看看人家大妈,直接拿了四盘,看了下牛奶货架也比较空,不过还有致优跟优倍,不过不算很实惠,本来想买,只是后来赶着去结账,就给忘了,称好了黑米去看了下肉,结果肉也没了,都在买猪蹄,我们也不太爱吃猪蹄,就买了点鸡胸肉,整体看起来我们买的东西真的有点格格不入,不买泡面(因为 LD 不让买了),也不屯啥米和鸡蛋,其实鸡蛋已经买了,米也买了,其他的本身冰箱小也放不下太多东西,我是觉得还可能在屯一点这那的,LD 觉得太多了,基本的米面油有了,其他调味品什么也有了。后面就是排队结账,我去排的时候刚好前面一个小伙子跟大妈在争执,大妈说我们差不多时间来的,你要排前面就前面,小伙子有点不高兴,觉得她就是插队,哈哈,平时一般这种剧情都是发生在我身上的,这会看着前面的吵起来还是很开心的,终于有跟我一样较真的人了,有时候总觉得我是个很纠结,很较真的人,但是我现在慢慢认可了这种较真,如果没有人指出来这种是插队行为,是不对的,就会有越来越多的人觉得是可以随意插队的,正确的事应该要坚持,很多情况大家总是觉得多一事不如少一事,鸡毛蒜皮的没什么好计较的,正是这种想法,那么多人才不管任何规则,反而搞得像遵守规则都是傻 X 似的。回到屯物资,后面结账排到队了也没来得及买原来想买的花生牛奶什么的,毕竟那么多人排着队,回家后因为没有蔬菜,结果就只能吃干菜汤和饭了

0%