开发工具分享
  • 首页
  • 计算科学
  • 文化旅游
  • 项目和网站
    • OSSEZ 计算技术
    • USRealEstate 社区
    • 地区文化
    • CWIKI.US
    • BUG.OSSEZ.COM
    • RSS.OSSEZ.COM
CWIKIUS.CN
一个有独立思考和温度的清新站
Computer Science

JDK 15 以上版本的字符串块

考察下下面的代码: public String textBlocks() { // THIS ONLY FOR JDK 15 return """ Get busy living or get busy dying. --Stephen King"""; } 我们可以看到上面的代码使用了 2 个引号 " 来表示一个字符串的块。 结论 上面的代码只能在 JDK 15 以上的版本才可以使用。 如果你使用的是 JDK 13 或者 14 的版本,你可以开启使用预览模式来让编译器通过。 因为我们的本地使用的是 JDK 11 编译器,上面的字符串表示方式在你的编译器上面会提示错误。   https://www.ossez.com/t/jdk-15/13979

2022年08月03日 0Comments 417Browse 0Like Read more
Computer Science

Java 8 中的设计模式策略

概述 在本篇文章中我们对可以在 Java 8 中的设计模式策略(strategy design pattern)进行一些简单的说明。 如果你对 Java 的设计模式不是非常清楚的话,可以先自行脑补下。 我们简单的总结就是将以前 Java 使用的接口和实现的设计模式,在 Java 8 中可以使用 lambda 函数来进行简化。 在下面内容中,我们首先提供了一个简单的设计模式样例,以及在传统的环境下我们是怎么实现这个设计模式的。     随后,我们将会使用 Java 8 中的 lambda 函数来进行实现,然后介绍一些有什么不同的地方。 模式策略 所谓的模式策略(strategy pattern)的定义就是能够让我们的程序在运行时(runtime)改变算法的表现。 在通常的情况下,我们会首先设计一个接口,然后在这个接口中定义我们需要使用的方法,然后使用不同的类来实现我们的接口定义的方法。 这种设计模式为我们在 Java 面向对象设计时候经常用到的。 让我们来考察下面的一个使用案例,针对不同的节日,我们针对某一个销售使用不同的定价策略,比如说圣诞节(Christmas),复活节(Easter)或者新年(New Year),我们使用的价格策略是不一样的。 首先我们需要在接口中定义一个 Discounter 方法,然后针对不同的节日来实现 Discounter 这个方法。 public interface Discounter { BigDecimal applyDiscount(BigDecimal amount); } 然后我们的目标是在复活节的时候打 5 折(50%),另外一个目标是在圣诞节的时候打 9 折(10%)。 随后我们就可以在下面的 2 个类中实现我们在接口中定义的方法。 public static class EasterDiscounter implements Discounter { @Override public BigDecimal applyDiscount(final BigDecimal amount) { return amount.multiply(BigDecimal.valueOf(0.5)); } } public static class ChristmasDiscounter implements Discounter { @Override public BigDecimal applyDiscount(final BigDecimal amount) { return amount.multiply(BigDecimal.valueOf(0.9)); } } 然后,我们在实现中使用这个策略: Discounter easterDiscounter = new EasterDiscounter(); BigDecimal discountedValue = easterDiscounter .applyDiscount(BigDecimal.valueOf(100)); assertThat(discountedValue) .isEqualByComparingTo(BigDecimal.valueOf(50)); 上面这个设计模式是我们在通常情况下使用的,但是比较头痛的是针对每一个方法,你需要在实现中都实现你需要的方法。 另外一个解决方案就是使用内部类型,但是这个内部类型并没有有太多的提高,你还是有不少的工作需要做。 例如下面使用内部类型的实现: Discounter easterDiscounter = new Discounter() { @Override public BigDecimal applyDiscount(final BigDecimal amount) { return amount.multiply(BigDecimal.valueOf(0.5)); } }; 使用 Java 8 如果你开始使用 Java 8 的话,我们知道 lambda 函数表达式可以做内部类型来使用,这样能够明显的降低多余的代码。 同时会让我们的代码看起来更加整洁和可读。 不管怎么样,使用 lambda 表达式提供了另外一种模式的实现,针对最开始的实现来说,Java 8 的实现提供了更多的一种选择。 降低代码的冗余 现在我们针对 EasterDiscounter 的实现,我们现在只是用 lambda 表达式来实现: Discounter easterDiscounter = amount -> amount.multiply(BigDecimal.valueOf(0.5)); 通过上面的代码,我们可以看到使用 lambda 表达式的实现看起来更加整洁,代码更加可读和便于维护,针对开始使用多行才能实现的内容,现在只需要使用一行就可以完成了。 更主要的是: ** 一个 lambda 表达式可以被用来替换匿名的内部类型**。 如果我们需要对多个折扣力度进行实现的话,使用 lambda 表达式就看起来更加漂亮了: List<Discounter> discounters = newArrayList( amount -> amount.multiply(BigDecimal.valueOf(0.9)), amount -> amount.multiply(BigDecimal.valueOf(0.8)), amount -> amount.multiply(BigDecimal.valueOf(0.5)) ); 如果我们需要对很多折扣力度进行定义的话,我们可以在 Java 8 中使用静态方法,然后这个定义将会在一个类中完成。 如果你愿意的话,Java 8 甚至可以让你在接口中定义静态方法。 对比在实体类和匿名内部类型之间进行选择,让我们在一个单独类中创建多个静态 lambda 表达式: public interface Discounter { BigDecimal applyDiscount(BigDecimal amount); static Discounter christmasDiscounter() { return amount -> amount.multiply(BigDecimal.valueOf(0.9)); } static Discounter newYearDiscounter() { return amount -> amount.multiply(BigDecimal.valueOf(0.8)); } static Discounter easterDiscounter() { return amount -> amount.multiply(BigDecimal.valueOf(0.5)); } } 通过上面的代码,我们可以看到使用了较少的代码,我们实现了很多的功能。 改进方法的创建 让我们来对 Discounter 接口再次进行修改,这次我们让 Discounter 接口继承 UnaryOperator 接口,然后添加一 combine() 方法: public interface Discounter extends UnaryOperator<BigDecimal> { default Discounter combine(Discounter after) { return value -> after.apply(this.apply(value)); } } 最开始的设计就是通过对 Discounter 接口的调整,能够让 Discounter 接口能够对折扣进行处理。 随着 UnaryOperator 接口被继承,我们可以使用 UnaryOperator 接口提供的 apply() 方法,我们只需要对 applyDiscount 进行替换就可以了。 combine() 方法为在 Discounter 接口中应用的一个抽象,使用一个内建的 apply() 函数来实现。…

2022年08月03日 0Comments 449Browse 0Like Read more
Computer Science

美国房地产经纪人更要注意和我经历的 “杀猪盘” 诈骗

通常房地产经纪人的信息都比较公开,因此不少骗子可能会利用你的信息对你进行诈骗。 作为地产经纪,已经遇到了多起这种诈骗方式。     本篇文章主要对遇到的杀猪盘诈骗进行一些解读,希望大家都能提高警惕,保护自己的资产。 骗子的套路不断升级,最新的手法就是在北美超级流行的“杀猪盘”骗局,在美华人惨被瞄准,可恨的不只是骗钱,同时还诛心! 杀猪盘 “杀猪盘(killing pig plate)”原本是流传在东南亚地区的诈骗方式,如今已席卷全球,诈骗分子将受害者称为“猪”,把交友工具成为“猪槽”、把聊天剧本称为“猪饲料”、把恋爱聊天过程称为“养猪”、把最后诈骗钱财称为“杀猪”。 本来这个诈骗多是针对未婚人士,通常房地产经纪人的警惕性比较高,并且大部分是按照规矩出牌,因此通常不那么容易上钩。 但是,诈骗罪者会伪装为客户,先和你套近乎,然后再一步一步的引导你上钩。 诈骗套路 作为房地产经纪的你肯定会收到不少陌生人的短信,咨询投资买房的事。 正直的你可能会表示,没有适合投资赚钱的房产,而且劝说对方不要和“自住人”抢房产。说到这里,对方便不再和你聊房地产的事,开始吹嘘自己投资有多么厉害,话里话外都是劝说或者诱导你和他一起做投资。 获得你的信任 对方套路的第一步就是,告诉你他/她将会要在某个地方投资一个房地产,为了将诈骗份子包装成成功人士,投资的房产项目通常都在百万上下。 如果你你是资深地产经纪的话,通常你不会在意对方投资多少钱。 虽然对方投资的钱越多,你成交后的收益越多,但是你需要知道,假设你所在地方的成交中位数在 50 万的话,希望投资百万的客户,对自己的需求是非常明确的,同时美国的金融监管机构对购房资金的来源是有要求的,不是说随便什么资金都可以买的。 点评: 为了获得你的信任,通常骗子都会将自己包装成成功人士。 为了对应上面的称呼,骗子通常都会用比较成功人士的照片,照片看起来会让你感觉气质非常不错,有点意思的感觉。 获得你的信息 通常因为房地产经纪人都是为客户服务的。 第一步大部分人都会被攻陷。在被杀猪之前,我们还有多重方法识破的,别着急,只要不到最后一步都没有问题。 骗子在完成第一步以后,将会进行下一步,在这一步中,通常会要求你提供更多的信息。 针对 Agent 来说,骗子会要求你提供一些房源给他们,因为他们要伪装成购房者,如果连房子都不看的话他们就太假了。 作为 Agent 的你,现在应该马上去给对方找房源去了,通常你会按照对方要求找到一些房源,但是对方可能没有办法回复太多信息给。或者对方不会马上回复你。 通常在过了 1 天或者一段时间后,对方会告诉你他对这个房子感觉非常好,然后让你进行一些介绍。 这个时候 Agent 会非常热情的进行介绍,然后对方就会说他感觉也不错。但是有问题就是资金。 骗子会说他的资金大量在虚拟货币中,骗子就问你有没有什么办法。 骗子也会说,我有一些资金在虚拟货币中,并且都是我投资虚拟货币赚钱的,有可能会暗示的问 Agent ,你有没有进行投资呀,有没有进行虚拟货币投资呀。 点评: 不管骗子使用什么手段,最终的目的就是将被骗者往虚拟货币上转。 通过一些问题,骗子可以摸清的底细,对投资的敏感程度,有多少贪念。 因为有前面的铺垫,这个时候你大脑的反应可能没有那么快的与诈骗联系在一起。 暗示或者提示你开户 到这一步的时候,骗子通常会非常诱惑的提示你进行虚拟货币交易所的开户了。 这个时候使用的交易所都是相对正规的,你的开户需要完成身份验证等操作。 如果不是高级骗子,他们会使用自己的网站,这种网站只要有基本的计算机技术知识都能识别。因为这类交易所的网站地址通常都很奇怪,并且成立时间很短。 如果骗子比较高级,这一步他们会诱导你到正规的虚拟货币交易所进行注册。 点评: 只要不是你自愿想了解虚拟货币的开户都有可能是诈骗。 在对虚拟货币不是非常了解的情况下,不要进入虚拟货币领域,控制住自己的欲望,比特币的钱不是那么好赚的。 暗示或者提示你转账 骗子在这个时候将会暗示或者提示你进行转账。 骗子通常会提示你使用电汇的方式,而不是使用其他的方式。 在美国,通常的转账方式是支票,电汇,ACH 扣款,Paypal 等。电汇方式是所有转账方式中转账资金没有上限的转账方式。 Paypal 和支票通常都会有限制。在美国金融系统中,如果你使用支票进行转账,在超过一定金额后,支票的清账时间很长。 例如 Chase 银行,如果你存入个人支票,如果是新用户,清账时间长达 30 天。 Paypal 通常也只用于小额,通常也在 1 千以内。 为了刺激你,骗子会告诉你,因为你没有及时转账,你损失了多少多少。 如果一次不行,骗子会多次刺激你,2 次,3 次,甚至 10 次都不奇怪。但是所有的目的就只有一个就是然后尽快进行电汇。 点评: 如果你对美国的金融和交易系统有所了解的话,你就不会轻易使用电汇的转账方式。 美国的转账方式有很多种,使用电汇方式是比较麻烦的一种方式。 骗子可能会提示你去银行直接电汇。当然你也可以使用手机方式转账,如果使用手机电汇,通常银行自身会有监管,电汇金额过大的话,账号会被冻结直到解除冻结。 这就是为什么骗子一直催你去银行直接电汇。 一个原则,不管在任何时候,任何地方,任何人,如果你对对方不熟悉,不要转账,不要转账,不要转账。 重要的事情说三次。 杀猪 如果你转账成功了,很不幸你就进入了对方的杀猪盘中了。 在这个时候,对方会一步一步诱导你投入更多资金,甚至让你不惜借贷的投入资金。 如果你还保有一点点理智的话,你还是能够及时或者全部止损的。 点评: 人性的特点已经被骗子利用到了极致。 对你不确定的时候,你可以选择和家人和朋友多沟通下,问下他们的看法。 上网搜索下有没有这种类似的诈骗案例,都会有很多办法止损的。 总结 电信诈骗非常可恶,而且损失的资金绝大部分没有办法追回。 其实也不是没有破解的办法,只是非常明确的一点不要被别人带着走,不要怕得罪人,不要怕损失钱。 骗子通常就利用上面几个人性的弱点了一步一步占领你的。 只要提高警惕相信,相信骗子绝对是无从下手的。 除了“杀猪盘”之外,其他的电信诈骗我们也要小心。电信网络诈骗手法千变万化,但万变不离其宗,最后都会要你转账。 最后的防线就是对不熟悉的人:不要转账,不要转账,不要转账。 不管是对方让你转出,还是转入。 对不明确的转账需求,找朋友,家人多核实,总有一个人能想明白的。 下面的一些办法也许能够帮助到你: 来路不明的链接不点。在点链接之前看看链接的地址,短连接,不熟悉的网站直接删除,不管里面的内容多诱人。 没有一夜暴富的神话,所有的钱都不好赚,虚拟货币更是如此。所有诱导进行虚拟货币投资收益的信息都不可信,更不要尝试进行交易。 陌生电话和短信,一定担心。如果不确定一定要多和家人朋友沟通,知道的人越多出问题的情况越少。 控制住自己的欲望,保护好自己的隐私。 多了解一些常见的诈骗手段,对骗子可能会用到的诈骗方式有所了解。电信诈骗其实离我们很近很近。 骗子一般不太敢接电话和视频要求。如果你尝试和对方进行视频或者语音的话,对方大概率会拒绝。当然骗子会语音,视频要求接受的可能性不大。当然这个并不是非常保险,回到最后的底线就是不转账就行。   https://www.usreio.com/t/topic/224

2022年08月03日 0Comments 477Browse 0Like Read more
Computer Science

Java Optional 初始为空

如果你想对 Optional 进行初始化的话,你可能会考虑使用下面的代码: Optional<QualificationStateLabelInfo> stateSpecificLabel = null; 上面的代码编译和运行都没有问题。 如何初始化 正确的初始化代码是: Optional<QualificationStateLabelInfo> stateSpecificLabel = Optional.empty(); 上面将会把你定义的 Optional 初始化为空。     但是我们会避免使用 null。 https://www.ossez.com/t/java-optional/13975

2022年08月03日 0Comments 409Browse 0Like Read more
Computer Science

Java 8 开始新增的 Optional 类 - Optional 对象中的返回

使用 get() 来返回一个值 在对 Optional 对象完成一些检查和校验后,我们可以使用 get() 方法来返回对象中的值。 // returning Value With get() @Test public void givenOptional_whenGetsValue_thenCorrect() { Optional<String> opt = Optional.of("HoneyMoose"); String name = opt.get(); assertEquals("HoneyMoose", name); } 与 orElse() 或者 orElseGet() 方法不一样的地方是 get() 只会在 Optional 包装的对象不为 null 的时候返回值,否则这个方法将会抛出一个没有这个元素(no such element exception)的异常 。 @Test(expected = NoSuchElementException.class) public void givenOptionalWithNull_whenGetThrowsException_thenCorrect() { Optional<String> opt = Optional.ofNullable(null); String name = opt.get(); } 上面的方法显示了如何使用 get() 方法来获得 Optional 中元素的典型操作。 我们使用 Optional 的主要原因就是为了避免在程序中出现 Null 对象异常的这种情况,但是 get() 方法的这种操作还是会给你带来空对象异常的。 因此需要注意下这种代码编写方式,也有可能在 JDK 的后续版本中,这个 get() 方法有可能被取消掉,但是目前还不会。   正是因为这种情况,get() 这个方法也有可能出现空对象异常,在编码的时候还是需要注意下的。 使用 filter() 来进行条件返回 我们可以使用 filter() 方法在输出之前进行测试,然后过滤出满足我们条件的返回对象。 这个方法将会使用 Java 提供的谓语(predicate )作为参数来返回 Optional 对象。 如果通过了 Java 提供的谓语(predicate )测试的话,Optional 对象将会被原样返回。 如果,测试的 谓语(predicate )为 False 的话,那么一个空的 Optional 对象将会被返回。 @Test public void whenOptionalFilterWorks_thenCorrect() { Integer year = 2016; Optional<Integer> yearOptional = Optional.of(year); boolean is2016 = yearOptional.filter(y -> y == 2016).isPresent(); assertTrue(is2016); boolean is2017 = yearOptional.filter(y -> y == 2017).isPresent(); assertFalse(is2017); } filter() 方法通常用来处理你不需要的返回,或者处理满足你条件的返回。 例如在对用户电子邮件进行检查,或者用户密码进行检查的时候,我们可以设置这样一个 filter() 过滤器,当不满足我们设置条件的时候,我们让程序返回一个空的对象,以此来设置条件。 让我们看另外一个使用场景,我们希望购买一个调制解调器(modem),但是我们只关注的是价格,我们对信号灯并不敏感 我们希望对调制解调器在满足价格区间的时候获得一个通知: public class Modem { private Double price; public Modem(Double price) { this.price = price; } // standard getters and setters } 让我们让这个对象通过一些代码来检查这个对象是不是满足我们设定的价格区间. 下面的代码是我们不使用 Optional 的时候的代码。 从上面的代码来看,我们需要进行 Null 检查,然后获得价格,然后判断价格,更要命的更极端的情况价格也有可能为 null。 public boolean priceIsInRange1(Modem modem) { boolean isInRange = false; if (modem != null && modem.getPrice() != null && (modem.getPrice() >= 10 && modem.getPrice() <= 15)) { isInRange = true; } return isInRange; } 为了满足 Null 检查的所有条件,我们需要不停的 if 进行判断。我们需要通过这些 if 条件检查来确定是否满足我们的条件,并且这个代码看起来有点郁闷,但是实际上也确实就是这样写的。 @Test public void whenFiltersWithoutOptional_thenCorrect() { assertTrue(priceIsInRange1(new Modem(10.0))); assertFalse(priceIsInRange1(new Modem(9.9))); assertFalse(priceIsInRange1(new Modem(null))); assertFalse(priceIsInRange1(new Modem(15.5))); assertFalse(priceIsInRange1(null)); } 同时,你也有可能忘记某一个检查,比如说价格为 NULL 的时候怎么办。 这个检查在编译的时候是不会提示你的,只有程序真正上线运行了,出现了异常了,你才知道,我又忘记检查空了。 现在我们看看 Optional 中的 filter() 是怎么做的。 public boolean priceIsInRange2(Modem modem2) { return Optional.ofNullable(modem2).map(Modem::getPrice).filter(p -> p >= 10).filter(p -> p <= 15).isPresent(); } 你的程序精简到只需要一行就可以了。 map 这个方法只是简单的从对象中获得值,后面的过滤器才是对获得值进过滤的。 需要注意的是,使用 filter() 不会对输入的参数进行修改。 在我们的用例中,我们非常容易的就从我们的 Model 对象中获得了价格的属性。至于 map() 的使用我们在后面的内容中进行介绍。 针对上面的代码,首先如果对象出现 null 的时候是不会对你程序有任何影响的,还是能一直跑下去的。 其次就是逻辑非常简单,整个逻辑就是对价格进行判断,至于其他的 null 判断都是由 Optional 完成的。 @Test public void whenFiltersWithOptional_thenCorrect() { assertTrue(priceIsInRange2(new Modem(10.0))); assertFalse(priceIsInRange2(new Modem(9.9))); assertFalse(priceIsInRange2(new Modem(null))); assertFalse(priceIsInRange2(new Modem(15.5))); assertFalse(priceIsInRange2(null)); } 最开始的 If 代码也是可以完成价格的判断的,但是这个方法有着自身的缺陷,因此我们使用了…

2022年08月03日 0Comments 529Browse 0Like Read more
Computer Science

Java 8 开始新增的 Optional 类 - Optional 对象中的异常

使用 orElseThrow() 处理异常 在 orElse() 和 orElseGet() 方法之外,JDK 还添加了一个 orElseThrow() 方法,JDK 使用这个方法来处理对象为空的情况。 如果 Optional 的对象为 null 的话,orElse() 和 orElseGet() 是返回一个默认值,我们可以使用 orElseThrow() 来抛出一个异常。 考察下面的代码,在 Optional 为空的时候,异常是如何抛出的。 @Test(expected = IllegalArgumentException.class) public void whenOrElseThrowWorks_thenCorrect() { String nullName = null; String name = Optional.ofNullable(nullName).orElseThrow( IllegalArgumentException::new); } 这个异常处理方法是从 Java 8 开始提供的,可以通过在构造来传入异常。 Java 10 以后,还推出了一个更加简单的没有参数的 orElseThrow() 版本的方法。 这样的话,如果 Optional 对象为空的话,我们可以抛出一个 NoSuchElementException 异常: @Test(expected = NoSuchElementException.class) public void whenNoArgOrElseThrowWorks_thenCorrect() { String nullName = null; String name = Optional.ofNullable(nullName).orElseThrow(); } https://www.ossez.com/t/java-8-optional-optional/13968

2022年08月03日 0Comments 450Browse 0Like Read more
Computer Science

Java 8 开始新增的 Optional 类 - Optional 中的方法

fPresent() 的使用条件 ifPresent() 方法能够让我们在对对象进行下一步操作之前判断我们需要操作的对象是否为 Null,在没有 Optional 对象之前,我们通常使用下面的方法先进行判断: if(name != null) { System.out.println(name.length()); } 上面的程序逻辑是,首先判断 name 这个变量是不是为空,如果不为空的话,允许程序继续执行下一步。 这种判断方法不是很美观,代码也比较难看,更重要的是这种判断方法也是容易出错的。 有谁又能够保证我们在检查空,并且打印出变量后,这个变量不被再次使用呢,在这个变量再次使用的时候又有谁能够保证我们不会忘记空检查呢? 同时,有可能在程序的运行时导致空对象异常,NullPointerException。尤其是在程序因为输入的问题导致失败,无法启动的情况下,通常这种情况是因为程序本身没有被很好的设计和编码。 Optional 能够非常明确的处理可能为空的变量,这个是一种比较好的编码习惯。 让我们看看上面的代码在 Java 8 的环境下是如何进行实现的。 在常用的函数编程的情况下,我们在对象不进行空检查后使用函数式进行编程: @Test public void givenOptional_whenIfPresentWorks_thenCorrect() { Optional<String> opt = Optional.of("HoneyMoose"); opt.ifPresent(name -> LOG.debug("{}", name.length())); } 在上面的示例中,我们仅仅使用了 2 行代码就实现了第一种方法需要使用的 5 行代码。 第一行代码使用 Optional 对象来对我们的变量进行包装,第二行代码就对已经包装好的 Optional 对象进行相应的操作。 orElse() 方法来定义默认值 orElse() 这个方法被用来获取 Optional 实例中内部的值。 这个方法只需要 1 个参数,如果 Optional 对象中的值不为空的话,程序将会返回 Optional 对象中的值,否则将会使用 orElse 这个方法中输入参数的值来替代输出。 当然,你也可以在 orElse() 调用一个方法,至于和 orElseGet() 有什么不同,我们将会在后面进行说明。 考察下面的代码: @Test public void whenOrElseWorks_thenCorrect() { String nullName = null; String name = Optional.ofNullable(nullName).orElse("john"); assertEquals("john", name); } orElseGet() 方法来定义默认值 orElseGet() 和 orElse() 方法类似。 我们都知道,如果 Optional 为空的时候,如果使用 orElse() 方法,将会使用这个方法中输入的参数来替代返回,orElseGet() 就更近一步了。 orElseGet 提供的是一个函数式的接口,你可以在 orElseGet() 中使用函数编程,返回的结果就是这个函数进行运算后的结果。 @Test public void whenOrElseGetWorks_thenCorrect() { String nullName = null; String name = Optional.ofNullable(nullName).orElseGet(() -> "john"); assertEquals("john", name); } orElse() 和 orElseGet() 方法的对比 和很多程序员一样,如果你是开始接触 Java 8 的话,你可能对 orElse() 和 orElseGet() 2 个方法之间的执行不同有所不了解,觉得这 2 个方法在功能上都是重复的。     事实上看起来就是这样的,但是在实际上还是有一些微妙的不同的。 如果你对这些细微的不同不够了解的话,有可能会严重影响你程序的执行效率。 简单来说就是其中定义的函数是否被执行的区别,不管前面对 Optional 的判断是否为 null, orElse() 中调用的方法都会被执行,orElseGet() 却不会。 首先,让我们在测试类中定义一个 getMyDefault() 方法,这个方法不使用任何参数,只是打印并且返回一个字符串: public String getMyDefault() { System.out.println("Getting Default Value"); return "Default Value"; } 然后我们分别使用 orElse() 和 orElseGet() 来进行调用这个方法,我们来看看有什么不同。 Optional 对象为空的情况 @Test public void whenOrElseGetAndOrElseOverlap_thenCorrect() { String text = null; String defaultText = Optional.ofNullable(text).orElseGet(this::getMyDefault); assertEquals("Default Value", defaultText); defaultText = Optional.ofNullable(text).orElse(getMyDefault()); assertEquals("Default Value", defaultText); } 正如我们所看到的,因为 Optional 对象为空,我们定义的函数都被调用了。 程序的输出如下,从程序的输出可以看出来,这 2 个方法的执行是相同的。 The side effect is: Getting default value... Getting default value... Optional 对象不(NOT)为空的情况 使用上面相同的代码,但是这次不同的是,我们定义的 Optional 对象是不为空的 @Test public void whenOrElseGetAndOrElseDiffer_thenCorrect() { String text = "Text present"; LOG.debug("Using orElseGet:"); String defaultText = Optional.ofNullable(text).orElseGet(this::getMyDefault); assertEquals("Text present", defaultText); LOG.debug("Using orElse:"); defaultText = Optional.ofNullable(text).orElse(getMyDefault()); assertEquals("Text present", defaultText); } 如上面的代码所展示的,我们需要判断的 Optional 对象已经不为空了,程序的输出如下所示: Using orElseGet: Using orElse: Getting default value... 注意到 orElseGet() 方法在我们检查 Optional 对象不为空的时候,就不再调用 getMyDefault 这个方法。 然后我们再来看看 orElse() 这个方法,尽管…

2022年08月03日 0Comments 481Browse 0Like Read more
Computer Science

Java 8 开始新增的 Optional 类 - 检查 Optional 的值

检查值是否存在的 isPresent() 和 isEmpty() 方法 当我们使用 Optional 对象的时候,我们可以使用 isPresent() 方法来检查返回的 Optional 对象中是否有值。 Optional 对象可以是你自己创建的,或者是从其他方法中返回的。 @Test public void givenOptional_whenIsPresentWorks_thenCorrect() { Optional<String> opt = Optional.of("HoneyMoose"); assertTrue(opt.isPresent()); opt = Optional.ofNullable(null); assertFalse(opt.isPresent()); } 如果 Optional 对象中的值不为 null 的话,这个方法将会返回 True。 同样的,如果使用 Java 11 的话,你可以使用与 isPresent 相反的方法 isEmpty。 如果你的对象中的值为 null 的话,isEmpty 将会返回 True。 @Test public void givenAnEmptyOptional_thenIsEmptyBehavesAsExpected_JDK11() { Optional<String> opt = Optional.of("Baeldung"); assertFalse(opt.isEmpty()); opt = Optional.ofNullable(null); assertTrue(opt.isEmpty()); } 如果你查看 API 的话,你会看到 JDK 的源代码只是用了简单的判断是否等于 null。   这 2 个方法的使用正好是相反的。   https://www.ossez.com/t/java-8-optional-optional/13966

2022年08月03日 0Comments 452Browse 0Like Read more
Computer Science

Java 8 开始新增的 Optional 类 - 创建 Optional 对象

创建一个 Optional 对象 有下面的一些方法可以被用来创建 Optional 对象。     empty 静态方法 如果你想创建一个空的 Optional 的对象,我们简单的使用 Optional 类提供的 empty() 静态方法: @Test public void whenCreatesEmptyOptional_thenCorrect() { Optional<String> empty = Optional.empty(); assertFalse(empty.isPresent()); } 需要注意的是,我们使用 isPresent() 方法来检查 Optional 对象中值的情况。 如果我们创建的 Optional 对象有值的话,isPresent() 方法将会返回 True,否则 isPresent() 这个方法将会返回 False。 我们将会在本页面的后续部分继续讨论有关 isPresent() 方法的使用。 of 静态方法 下面的方法将会创建一个 Optional 对象,在创建这个对象的时候,我们使用了另外的一个静态方法 of() 来进行创建: @Test public void givenNonNull_whenCreatesNonNullable_thenCorrect() { String name = "HoneyMoose"; Optional<String> opt = Optional.of(name); assertTrue(opt.isPresent()); } 需要注意的是,如果你使用 of 静态方法创建一个 Optional 对象的时候,你还是有机会面临空对象(NullPointerException)异常。 考察下面的代码,如果运行的话,你还是会命令到空对象异常,如果你初始化 Optional 为空的话。 @Test(expected = NullPointerException.class) public void givenNull_whenThrowsErrorOnCreate_thenCorrect() { String name = null; Optional.of(name); } ofNullable 静态方法 有时候,我们希望在我们的代码中使用 Null 值。 这个时候,你可以使用静态方法 ofNullable() ,这个静态方法将会告诉 Optional 对象是可能为 Null 的。 @Test public void givenNonNull_whenCreatesNullable_thenCorrect() { String name = "HoneyMoose"; Optional<String> opt = Optional.ofNullable(name); assertTrue(opt.isPresent()); } 通过上面的操作,我们可以在 Optional 使用 null,这样的话,如果你对 Optional 进行初始化的时候,不会因为null 的使用而导致异常。 @Test public void givenNull_whenCreatesNullable_thenCorrect() { String name = null; Optional<String> opt = Optional.ofNullable(name); assertFalse(opt.isPresent()); } https://www.ossez.com/t/java-8-optional-optional/13965

2022年08月03日 0Comments 486Browse 0Like Read more
Computer Science

Java 8 开始新增的 Optional 类

如果你写过一些 Java 代码的话,你应该知道 Java 中最常见的就是空指针异常错误。 这个错误的原因就是你对一个为空的对象进行操作了。 比如说,你有一个 List,但是这个 List 是空对象,如果你要向这个 List 中添加元素或者删除元素的话,你铁定会遇到空对象的异常。 Optional 类是一个可以为 NULL 的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。 Optional 是个容器:它可以保存类型T的值,或者仅仅保存 NULL。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。     Optional 类的引入很好的解决空指针异常。 概述 在本指南中,我们针对 Optional 来进行一些探讨。 Optional 这个类最新是从 Java 8 中引入的,其主要目的如上面我们介绍的,就是为了解决 Java 中广受诟病的空异常。 Java 从 类型级别(type-level) 给出了一个解决方案,用来替代 null。 In this tutorial, we’re going to show the Optional class that was introduced in Java 8. 如果你还想对 Java 的 Optional 了解更多的话,你可以直接访问 Oracle 提供的官方 API,访问地址为: Tired of Null Pointer Exceptions? Consider Using Java SE 8's Optional!   文章列表 因 Optional 有关的内容比较多,请通过下面的链接访问具体的小主题: Java 8 开始新增的 Optional 类 - 创建 Optional 对象 Java 8 开始新增的 Optional 类 - 检查 Optional 的值 Java 8 开始新增的 Optional 类 - Optional 中的方法 Java 8 开始新增的 Optional 类 - Optional 对象中的异常 Java 8 开始新增的 Optional 类 - Optional 对象中的返回 Java 8 开始新增的 Optional 类 - Optional 在 Java 8 中的 Chaining 特性 Java 8 开始新增的 Optional 类 - Optional 在 Java 9 中的 API Java 8 开始新增的 Optional 类 - Optional 可能存在的滥用 Java 8 开始新增的 Optional 类 - Optional 对象序列化 结论 如果你按照上面的顺序阅读完成相关文章的话,你应该对在 Java 8 中开始使用的 Optional 类有了一些基本的了解。 同时在这边文章中也对为什么要使用 Optional 对象来替代 null 检查进行了一些说明。 同时我们也对如何从 Optional 中获得值进行了一些说明,同时对如果值是 null ,我应该如何设置默认值使用的 orElse() 和 orElseGet() 方法进行了一些阐述。 最后,我们对 Optional 返回的值如何进行转换进行了描述,在对返回值进行转换的话,我们可能会使用到 map(), flatMap() 和 filter() 方法。 同时我们还对 Optional 的一些特性,方法进行了阐述和说明。 在最后,我们对为什么使用 Optional 为方法的参数是不好的选项的原因进行了说明,并且举例如何避免这个问题。 https://www.ossez.com/t/java-8-optional/13964  

2022年08月03日 0Comments 438Browse 0Like Read more
1…678910
Archives
  • June 2026
  • May 2026
  • April 2026
  • March 2026
  • February 2026
  • January 2026
  • December 2025
  • November 2025
  • October 2025
  • September 2025
  • August 2025
  • July 2025
  • June 2025
  • May 2025
  • April 2025
  • March 2025
  • February 2025
  • January 2025
  • December 2024
  • November 2024
  • October 2024
  • September 2024
  • August 2024
  • July 2024
  • June 2024
  • May 2024
  • April 2024
  • March 2024
  • February 2024
  • January 2024
  • December 2023
  • November 2023
  • October 2023
  • September 2023
  • August 2023
  • July 2023
  • June 2023
  • May 2023
  • April 2023
  • December 2022
  • November 2022
  • October 2022
  • September 2022
  • August 2022
  • May 2022
  • April 2022
  • March 2022
  • February 2022
  • January 2022
  • December 2021
  • November 2021
  • October 2021
  • September 2021
  • August 2021
  • July 2021
  • June 2021
  • May 2021
  • April 2021
  • March 2021
  • February 2021
  • January 2021
  • December 2020
  • November 2020
  • October 2020
  • September 2020
  • August 2020
  • July 2020
  • June 2020
  • May 2020
  • April 2020
  • March 2020
  • February 2020
  • January 2020
  • December 2019
  • November 2019
  • October 2019
  • September 2019
  • August 2019
  • July 2019
  • June 2019
  • May 2019
  • April 2019
  • March 2019
  • February 2019
  • January 2019
  • December 2018
  • November 2018
  • October 2018
  • September 2018
  • August 2018
  • July 2018
  • June 2018
  • May 2018
  • April 2018
  • March 2018
Categories
  • Computer Science (2,367)
    • Confluence (663)
    • Gradle (12)
  • U.S. (511)
  • 文化旅游 (146)

COPYRIGHT © 2020 CWIKIUS. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

湘ICP备2020018253号-1