zoukankan      html  css  js  c++  java
  • guava – Optional

    过多的使用null可能会导致大量的bugs,Google code 底层代码中,95%的集合类默认不接受null值。对null值,使用快速失败拒绝null比默认接受更好。

    另外,null本身的含义很模糊。例如,对于null返回值,如Map.get(key)返回null,可能因为和key对应的值为null,也可能map中根本没有该key。null也可以用以表示失败或成功,可能代表任何事物。使用其他值而不是null可以使代码含义表达的更清楚。

    尽管如此,有些地方还是应该使用null。在内存和速度方面,null是廉价的,并且在对象数组中是不可避免的。

    基于以上原因,Guava大部分工具对null都设计为快速失败。另外,Guava提供了一些方便使用null的工具。

    实际案例

    不要在Set中使用null,也不要将null作为Map的key值,使用特殊值代替null可以让查找的语义更清晰。

    如果你想把null作为Map的value,更好的办法不是将该条目放入Map中,而是应该以一个单独的Set维护“值为null”的键集合。因为Map中某个键对应的值为null和Map中没有某个键值很容易混淆。

    如果需要在List中使用null,并且这个List是稀疏的,则使用Map<Integer, E>可能更好。

    如果确实需要null,但null值不能和Guava的集合一起工作,则只能选择其他方式,如JDK中的Collections.unmodifiableList代替Guava中的ImmutableList。

    Optional

    Guava设计Optional来解决null问题,Optional<T>表示可能为null的T类型的引用。Optional实例要么包含一个非null的引用,要么什么都不包含(absent),从不会包含null值引用。在需要使用null的时候,可以用Optional代替。

    Optional除了赋予null意义外,增加可读性,还在于它是一种傻瓜式的防护。Optional 迫使你积极思考引用确实的情况,因为你必须显式地从Optional 获取引用。

    Optional 的可能应用方面:

    • 作为方法返回值,用于取代使用null作为返回值的情况。
    • 用于区分“unknow”(如Map不包含)和“known to have no value”(如Map包含该键,值为Optional.absent())。
    • 用于包装null引用,从而在不支持null的集合中使用。

    创建Optional(均为静态方法)

    Optional.of(T) 创建指定引用的Optional实例,对null值抛出NullPointException。建议直接传递常量参数。
    Optional.absent() 创建引用缺失的Optional实例
    Optional.fromNullable(T) 创建指定引用的Optional实例,若引用为null则表示缺失
    assertEquals("training", Optional.of("training").get());
    
    Optional<String> optionalName = Optional.absent();
    assertFalse(optionalName.isPresent());
    
    // Non-null instance
    Optional<String> optionalName = Optional.fromNullable("bob");
    assertEquals("bob", optionalName.get());
    // null instance
    assertSame(Optional.absent(), Optional.fromNullable(null));

    查询方法(均为非静态方法)

    boolean isPresent() 如果该Optional 包含非null引用,返回true。
    T get() 返回Optional 所包含的引用,若引用缺失,则抛出IllegalStateException。
    T or(T) 返回Optional 所包含的引用,若引用缺失,返回默认值。
    T orNull() 返回Optional 所包含的引用,若引用缺失,返回null。
    Set<T> asSet() 返回Optional所包含的singleton不可变集合,若为空,返回空集合。

    public void testIsPresent_no() {
            assertFalse(Optional.absent().isPresent());
        }
    
        public void testIsPresent_yes() {
            assertTrue(Optional.of("training").isPresent());
        }
    
        public void testGet_absent() {
            Optional<String> optional = Optional.absent();
            try {
                optional.get();
                fail();
            } catch (IllegalStateException expected) {
            }
        }
    
        public void testGet_present() {
            assertEquals("training", Optional.of("training").get());
        }
        
        public void testOr_T_present() {
            assertEquals("a", Optional.of("a").or("default"));
        }
    
        public void testOr_T_absent() {
            assertEquals("default", Optional.absent().or("default"));
        }
    
        public void testOrNull_present() {
            assertEquals("a", Optional.of("a").orNull());
        }
    
        public void testOrNull_absent() {
            assertNull(Optional.absent().orNull());
        }
    
        public void testAsSet_present() {
            Set<String> expected = Collections.singleton("a");
            assertEquals(expected, Optional.of("a").asSet());
        }
    
        public void testAsSet_absent() {
            assertTrue("Returned set should be empty", Optional.absent().asSet().isEmpty());
        }
    
        public void testAsSet_presentIsImmutable() {
            Set<String> presentAsSet = Optional.of("a").asSet();
            try {
                presentAsSet.add("b");
                fail();
            } catch (UnsupportedOperationException expected) {
            }
        }
    
        public void testAsSet_absentIsImmutable() {
            Set<Object> absentAsSet = Optional.absent().asSet();
            try {
                absentAsSet.add("foo");
                fail();
            } catch (UnsupportedOperationException expected) {
            }
        }
  • 相关阅读:
    计算几何
    差三角
    约瑟夫
    字符编码
    河南省赛之Substring
    移动字母
    抽屉原理
    不要为了完成代码而写代码
    分布式文件系统优化
    降低代码的复杂度
  • 原文地址:https://www.cnblogs.com/jiawei-whu/p/4438730.html
Copyright © 2011-2022 走看看