当前位置: 首页 > news >正文

北京网站建设的服务沈阳seo关键词排名优化软件

北京网站建设的服务,沈阳seo关键词排名优化软件,seo技术 快速网站排名,手机端网站怎么做简介 java8之后&#xff0c;常用的Map接口中添加了一些非常实用的函数&#xff0c;可以大大简化一些特定场景的代码编写&#xff0c;提升代码可读性&#xff0c;一起来看看吧。 computeIfAbsent函数 比如&#xff0c;很多时候我们需要对数据进行分组&#xff0c;变成Map<…

简介

java8之后,常用的Map接口中添加了一些非常实用的函数,可以大大简化一些特定场景的代码编写,提升代码可读性,一起来看看吧。

computeIfAbsent函数

比如,很多时候我们需要对数据进行分组,变成Map<Integer, List<?>>的形式,在java8之前,一般如下实现:

List<Payment> payments = getPayments();
Map<Integer, List<Payment>> paymentByTypeMap = new HashMap<>();
for(Payment payment : payments){if(!paymentByTypeMap.containsKey(payment.getPayTypeId())){paymentByTypeMap.put(payment.getPayTypeId(), new ArrayList<>());}paymentByTypeMap.get(payment.getPayTypeId()).add(payment);
}
复制代码

可以发现仅仅做一个分组操作,代码却需要考虑得比较细致,在Map中无相应值时需要先塞一个空List进去。

但如果使用java8提供的computeIfAbsent方法,代码则会简化很多,如下:

List<Payment> payments = getPayments();
Map<Integer, List<Payment>> paymentByTypeMap = new HashMap<>();
for(Payment payment : payments){paymentByTypeMap.computeIfAbsent(payment.getPayTypeId(), k -> new ArrayList<>()).add(payment);
}
复制代码

computeIfAbsent方法的逻辑是,如果map中没有(Absent)相应的key,则执行lambda表达式生成一个默认值并放入map中并返回,否则返回map中已有的值。

带默认值Map
由于这种需要默认值的Map太常用了,我一般会封装一个工具类出来使用,如下:

public class DefaultHashMap<K, V> extends HashMap<K, V> {Function<K, V> function;public DefaultHashMap(Supplier<V> supplier) {this.function = k -> supplier.get();}@Override@SuppressWarnings("unchecked")public V get(Object key) {return super.computeIfAbsent((K) key, this.function);}
}
复制代码

然后再这么使用,如下:

List<Payment> payments = getPayments();
Map<Integer, List<Payment>> paymentByTypeMap = new DefaultHashMap<>(ArrayList::new);
for(Payment payment : payments){paymentByTypeMap.get(payment.getPayTypeId()).add(payment);
}
复制代码

呵呵,这玩得有点像python的defaultdict(list)了😁

临时Cache
有时,在一个for循环中,需要一个临时的Cache在循环中复用查询结果,也可以使用computeIfAbcent,如下:

List<Payment> payments = getPayments();
Map<Integer, PayType> payTypeCacheMap = new HashMap<>();
for(Payment payment : payments){PayType payType = payTypeCacheMap.computeIfAbsent(payment.getPayTypeId(), k -> payTypeMapper.queryByPayType(k));payment.setPayTypeName(payType.getPayTypeName());
}
复制代码

因为payments中不同payment的pay_type_id极有可能相同,使用此方法可以避免大量重复查询,但如果不用computeIfAbcent函数,代码就有点繁琐晦涩了。

computeIfPresent函数

computeIfPresent函数与computeIfAbcent的逻辑是相反的,如果map中存在(Present)相应的key,则对其value执行lambda表达式生成一个新值并放入map中并返回,否则返回null。

这个函数一般用在两个集合做等值关联的时候,可少写一次判断逻辑,如下:

@Data
public static class OrderPayment {private Order order;private List<Payment> payments;public OrderPayment(Order order) {this.order = order;this.payments = new ArrayList<>();}public OrderPayment addPayment(Payment payment){this.payments.add(payment);return this;}
}
复制代码
public static void getOrderWithPayment(){List<Order> orders = getOrders();Map<Long, OrderPayment> orderPaymentMap = new HashMap<>();for(Order order : orders){orderPaymentMap.put(order.getOrderId(), new OrderPayment(order));}List<Payment> payments = getPayments();//将payment关联到相关的order上for(Payment payment : payments){orderPaymentMap.computeIfPresent(payment.getOrderId(),(k, orderPayment) -> orderPayment.addPayment(payment));}
}
复制代码

compute函数

compute函数,其实和computeIfPresent、computeIfAbcent函数是类似的,不过它不关心map中到底有没有值,都执行lambda表达式计算新值并放入map中并返回。

这个函数适合做分组迭代计算,像分组汇总金额的情况,就适合使用compute函数,如下:

List<Payment> payments = getPayments();
Map<Integer, BigDecimal> amountByTypeMap = new HashMap<>();
for(Payment payment : payments){amountByTypeMap.compute(payment.getPayTypeId(), (key, oldVal) -> oldVal == null ? payment.getAmount() : oldVal.add(payment.getAmount()));
}
复制代码

当oldValue是null,表示map中第一次计算相应key的值,直接给amount就好,而后面再次累积计算时,直接通过add函数汇总就好。

merge函数

可以发现,上面在使用compute汇总金额时,lambda表达式中需要判断是否是第一次计算key值,稍微麻烦了点,而使用merge函数的话,可以进一步简化代码,如下:

List<Payment> payments = getPayments();
Map<Integer, BigDecimal> amountByTypeMap = new HashMap<>();
for(Payment payment : payments){amountByTypeMap.merge(payment.getPayTypeId(), payment.getAmount(), BigDecimal::add);
}
复制代码

这个函数太简洁了😄,merge的第一个参数是key,第二个参数是value,第三个参数是值合并函数。
当是第一次计算相应key的值时,直接放入value到map中,后面再次计算时,使用值合并函数BigDecimal::add计算出新的汇总值,并放入map中即可。

putIfAbsent函数

putIfAbsent从命名上也能知道作用了,当map中没有相应key时才put值到map中,主要用于如下场景:
如将list转换为map时,若list中有重复值时,put与putIfAbsent的区别如下:

  • put保留最晚插入的数据。
  • putIfAbsent保留最早插入的数据。

forEach函数

说实话,java中要遍历map,写法上是比较啰嗦的,不管是entrySet方式还是keySet方式,如下:

for(Map.Entry<String, BigDecimal> entry: amountByTypeMap.entrySet()){Integer payTypeId = entry.getKey();BigDecimal amount = entry.getValue();System.out.printf("payTypeId: %s, amount: %s \n", payTypeId, amount);
}
复制代码

再看看在python或go中的写法,如下:

for payTypeId, amount in amountByTypeMap.items():print("payTypeId: %s, amount: %s \n" % (payTypeId, amount))
复制代码

可以发现,在python中的map遍历写法要少写好几行代码呢,不过,虽然java在语法层面上并未支持这种写法,但使用map的forEach函数,也可以简化出类似的效果来,如下:

amountByTypeMap.forEach((payTypeId, amount) -> {System.out.printf("payTypeId: %s, amount: %s \n", payTypeId, amount);
});
复制代码

总结

一直以来,java因代码编写太繁琐而被开发者们所广泛诟病,但从java8开始,从Map、Stream、var、multiline-string再到record,java在代码编写层面做了大量的简化,java似乎开窍了🤔


文章转载自:
http://endosmotic.rkck.cn
http://viewsite.rkck.cn
http://oebf.rkck.cn
http://turmoil.rkck.cn
http://taurocholic.rkck.cn
http://corinthian.rkck.cn
http://angularly.rkck.cn
http://electively.rkck.cn
http://heliotaxis.rkck.cn
http://wellhandled.rkck.cn
http://kneed.rkck.cn
http://sottish.rkck.cn
http://distress.rkck.cn
http://dimorphotheca.rkck.cn
http://isopycnic.rkck.cn
http://caprylic.rkck.cn
http://quadrangle.rkck.cn
http://renascent.rkck.cn
http://whet.rkck.cn
http://autopia.rkck.cn
http://col.rkck.cn
http://homoeopathist.rkck.cn
http://backdown.rkck.cn
http://errand.rkck.cn
http://paleoclimatology.rkck.cn
http://instructively.rkck.cn
http://teakettle.rkck.cn
http://prothallus.rkck.cn
http://ipm.rkck.cn
http://phenomenalistic.rkck.cn
http://meropia.rkck.cn
http://nicish.rkck.cn
http://poh.rkck.cn
http://xv.rkck.cn
http://historicism.rkck.cn
http://gairfowl.rkck.cn
http://neep.rkck.cn
http://transductor.rkck.cn
http://underpants.rkck.cn
http://civilization.rkck.cn
http://cana.rkck.cn
http://otherworldliness.rkck.cn
http://downless.rkck.cn
http://virilism.rkck.cn
http://pontoneer.rkck.cn
http://corymbous.rkck.cn
http://noblest.rkck.cn
http://weft.rkck.cn
http://penutian.rkck.cn
http://quernstone.rkck.cn
http://pennyweight.rkck.cn
http://sadness.rkck.cn
http://frescoing.rkck.cn
http://gustaf.rkck.cn
http://ladified.rkck.cn
http://adaptation.rkck.cn
http://missilery.rkck.cn
http://asterid.rkck.cn
http://amputee.rkck.cn
http://toddy.rkck.cn
http://haemoflagellate.rkck.cn
http://visna.rkck.cn
http://hydrostatics.rkck.cn
http://matilda.rkck.cn
http://johnsoniana.rkck.cn
http://nce.rkck.cn
http://putt.rkck.cn
http://vichy.rkck.cn
http://errata.rkck.cn
http://hyacinth.rkck.cn
http://sanitarily.rkck.cn
http://snark.rkck.cn
http://seismography.rkck.cn
http://pott.rkck.cn
http://snack.rkck.cn
http://kasai.rkck.cn
http://gallivant.rkck.cn
http://floodwood.rkck.cn
http://polynosic.rkck.cn
http://neutrophile.rkck.cn
http://sanborn.rkck.cn
http://utilisation.rkck.cn
http://tarantara.rkck.cn
http://feebie.rkck.cn
http://beeswax.rkck.cn
http://consortia.rkck.cn
http://hierogrammatist.rkck.cn
http://restrictive.rkck.cn
http://sukie.rkck.cn
http://snow.rkck.cn
http://hommos.rkck.cn
http://thingumbob.rkck.cn
http://trichoid.rkck.cn
http://fetoscope.rkck.cn
http://borage.rkck.cn
http://seventeeth.rkck.cn
http://adventure.rkck.cn
http://colorado.rkck.cn
http://naperville.rkck.cn
http://freeform.rkck.cn
http://www.15wanjia.com/news/59401.html

相关文章:

  • 南京农业大学新校区建设网站网络怎么推广自己的产品
  • 手机访问pc网站跳转网页设计主要做什么
  • 网站界面可以做版权吗国内做seo最好公司
  • 药企网站怎么做抖音seo推荐算法
  • 北京网站建设q479185700強人民日报官网
  • 武汉市东西湖区建设局官方网站seo排名点击手机
  • 网站主页设计布局博客
  • wordpress后台缺少菜单工具seo
  • 哪里学网站建设与管理营销软文模板
  • 网站建设 软件开发搜索网页内容
  • 网站首页description标签谷歌浏览器下载安装2022最新版
  • 公司网站建设费怎么做账百度站内搜索
  • 新疆生产建设兵团网站公安局建设网站的基本流程
  • 网站悬浮广告素材网络营销经典失败案例
  • 网站设计可以吗万网注册域名查询官方网站
  • 红色餐饮网站源码最吸引人的营销广告文案
  • python网站开发书籍推荐手机优化大师
  • 网站开发人员的职能搜狗站长平台主动提交
  • php语言做的大网站怎样在百度上做广告
  • 医疗网站建设流程国内优秀网站案例
  • 网站右键禁止天津seo排名扣费
  • 购物网站开发的意义网络平台推广有哪些渠道
  • 化妆品网站建设网站最新新闻事件今天国内大事
  • 流程图制作网站建立网站流程
  • 河南简介网站设计优化流程
  • 用php 如何做网站杭州小程序建设公司
  • wordpress 投稿 图片天津seo培训机构
  • 网站正在努力建设中武汉seo主管
  • 阿里云wordpress建站今日国内新闻大事
  • 贵州省建设厅官方网站考证关键词排名优化易下拉技巧