guava学习笔记-基本工具

使用Optional类避免null

null代表不确定性,有可能这个对象不存在(大多数情况);有可能是成功或失败;有可能是对象存在但对象为空(在集合中的情况)。任何不确定性因素都可能会给程序埋下隐患。Optional类强迫你思考null的真正含义,去除null的含糊,让程序更优雅的处理null的情况。可以避免抛出空指针异常。使用Optional除了赋予null语义,增加了可读性,最大的优点在于它是一种傻瓜式的防护。Optional迫使你积极思考引用缺失的情况,因为你必须显式地从Optional获取引用。直接使用null很容易让人忘掉某些情形,尽管FindBugs可以帮助查找null相关的问题,但是我们还是认为它并不能准确地定位问题根源。

比如有如下方法,你想从一个Map集合中找到对应key的value值。当结果返回null的时候,到底是这个key不存在了?还是这个key对应的value为null了?

    public Integer findFromMap(Integer key){
        Map<String, Integer> map = Maps.newHashMap();
        map.put("foo", null);
        map.put("bar", 1);

        System.out.println(map.get(key));
        return map.get(key);
    }

Optional类或许可以解决这个问题,它强迫你不能返回null,一定要返回一个有意义的值。

        //不存在时使用,不用返回null
        Optional<String> absentString = Optional.absent();

        //确定存在不为空,如果为null立即返回空指针异常
        Optional<String> presentString = Optional.of("must exist");

        //不确定是否为空
        Optional<String> possibleNullString = Optional.fromNullable(findSomething(param));

        //如果不存在返回默认值
        String defaultString = possibleNullString.or("not exist");

        //判断是否存在
        if(possibleNullString.isPresent()){

            //返回存在值
            possibleNullString.get();
        }

        //返回Optional所包含引用的单例不可变集
        possibleNullString.asSet();

前置条件: 让方法中的条件检查更简单

    public void testPreconditions(String param1, String param2, boolean state) {
        //检查expression是否为true,用来检查传递给方法的参数。检查失败时抛出的异常IllegalArgumentException
        checkArgument(param1 != null && param2 != null);
        //检查state是否true,检查失败时抛出的异常IllegalStateException
        checkState(state, "state must be false");
        //检查是否为null,检查失败时抛出的异常NullPointerException
        checkNotNull(param1);
        checkNotNull(param2, "param2 can not be null!");
        //检查index作为索引值对某个列表、字符串或数组是否有效。index>=0 && index<size *
        int index = 1;
        int size = 10;
        checkPositionIndex(index, size);
        //检查index作为位置值对某个列表、字符串或数组是否有效。index>=0 && index<=size *
        checkElementIndex(index, size);
    }

Object方法

  • equals
    避免抛出空指针异常

  • hashcode
    用对象的所有字段作散列[hash]运算应当更简单。Guava的Objects.hashCode(Object…)会对传入的字段序列计算出合理的、顺序敏感的散列值。你可以使用Objects.hashCode(field1, field2, …, fieldn)来代替手动计算散列值

  • toString
    更方便使用

    @Test
    public void testOjbects(){
        boolean flag = Objects.equal("a", "b");
        Objects.hashCode("aaa", "bbb");
        String string =  MoreObjects.toStringHelper(this).add("x", 1).addValue(123).toString();
        String expected = "TestGuava{x=1, 123}";
        assertEquals(expected, string);
    }

链式风格的比较器

   @Test
    public void testOrder(){
        Function<String, String> convertToUpper = new Function<String, String>() {
            @Override
            public String apply(String input) {
                if(input == null || input == "")
                    return null;
                return input.toUpperCase();
            }
        };
        //当阅读链式调用产生的排序器时,应该从后往前读。
        Ordering<String> ordering = Ordering.natural().nullsLast().onResultOf(convertToUpper);
        List<String> strings = Arrays.asList("b", "c", null, "a");
        List<String> expectedString = ordering.sortedCopy(strings);
        List<String> actualString = Arrays.asList("a", "b", "c", null);
        assertEquals(expectedString, actualString);
        //获取可迭代对象中最大的k个元素。
        List<String> string2  =  Arrays.asList("a", "b", "d");
        assertEquals(ordering.greatestOf(string2, 2), Arrays.asList("d", "b"));
        //返回两个参数中最小的那个。如果相等,则返回第一个参数。
        List<String> string3  =  Arrays.asList("e", "f", "g");
        assertEquals(ordering.min(string3), "e");
        //返回最小的的k个原生
        ordering.leastOf(string3, 2);
    }
Guava类库中的Table是一个双键的Map,可以理解为一个行列式的数据结构。 Table可以用来表示一个映射,其中每个键都有一个与之关联的值,而且这个键需要由两个参数来确定。在Table中,第一个键称为"行键",第二个键称为"列键",而对应的值称为"值"。 Table的实现方式可以看作是一个Map<RowKey, Map<ColumnKey, Value>>的嵌套结构,其中RowKey和ColumnKey分别表示行键和列键,Value表示对应的值。 Table提供了多种视图,包括行视图、列视图、单元格视图等,这些视图可以方便地进行表格的操作和查询。 下面是一个简单的示例代码: ```java Table<String, String, Integer> table = HashBasedTable.create(); table.put("row1", "col1", 1); table.put("row1", "col2", 2); table.put("row2", "col1", 3); table.put("row2", "col2", 4); System.out.println(table.get("row1", "col1")); // 输出1 System.out.println(table.row("row1")); // 输出{col1=1, col2=2} System.out.println(table.column("col1")); // 输出{row1=1, row2=3} System.out.println(table.cellSet()); // 输出[(row1,col1)=1, (row1,col2)=2, (row2,col1)=3, (row2,col2)=4] ``` 在上面的示例中,我们创建了一个Table对象,并往其中添加了四个元素。然后,我们分别通过get方法、row方法、column方法和cellSet方法获取了对应的视图,并输出了它们的内容。 需要注意的是,Table中的行键、列键和值都可以为null,但是在使用时需要特别注意空指针异常的问题。此外,Table中的行键和列键必须实现equals和hashCode方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值