[Guava源码分析](6)Objects分析

简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SunnyYoona/article/details/71079778 1.
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SunnyYoona/article/details/71079778

1. 私有构造器

private Objects() {}

2. 判断两个可能为null的对象是否相等

public static boolean equal(@Nullable Object a, @Nullable Object b) {
        return a == b || (a != null && a.equals(b));
    }

当一个对象中的字段可以为null时,实现Object.equals方法会很痛苦,因为不得不分别对它们进行null检查。使用Objects.equal帮助你执行null敏感的equals判断,从而避免抛出NullPointerException。

System.out.println(Objects.equal("a", "a")); // returns true
System.out.println(Objects.equal(null, "a")); // returns false
System.out.println(Objects.equal("a", null)); // returns false
System.out.println(Objects.equal(null, null)); // returns true

注意:

JDK7引入的Objects类提供了一样的方法Objects.equals。

3. hashcode(Object... objects)

Guava的Objects.hashCode()会对传入的字段属性计算出合理,顺序敏感的散列值。

假设有一个Book类,有4个属性:title,author,publisher,isbn。我们可以通过Objects.hashCode方法:

public int hashCode() {
    return Objects.hashCode(title,author,publisher,isbn);
 }

Objects.hashcode方法是使用Arrays.hashCode实现的:

public static int hashCode(@Nullable Object... objects) {
    return Arrays.hashCode(objects);
  }

Arrays.hashCode:

public static int hashCode(Object a[]) {
        if (a == null)
            return 0;
        int result = 1;
        for (Object element : a)
            result = 31 * result + (element == null ? 0 : element.hashCode());
        return result;
    }

注意:

JDK7引入的Objects类提供了一样的方法Objects.hash(Object...)

4. toString

使用 Objects.toStringHelper可以轻松编写有用的toString方法。

public class Studnet {
    public void test(){
        String str1 = Objects.toStringHelper(this).toString();
        String str2 = Objects.toStringHelper(this).add("name","xiaosi").toString();
        String str3 = Objects.toStringHelper("Stu").add("age",25).toString();
        String str4 = Objects.toStringHelper("Stu").add("name","xiaosi").add("age",25).toString();
        String str5 = Objects.toStringHelper("Stu").omitNullValues().add("name", "xiaosi").add("school",null).toString();
        System.out.println("str1->" + str1);
        System.out.println("str2->" + str2);
        System.out.println("str3->" + str3);
        System.out.println("str4->" + str4);
        System.out.println("str5->" + str5);
    }
    public static void main(String[] args) {
        Studnet studnet = new Studnet();
        studnet.test();
    }
}

结果:

str1->Studnet{}
str2->Studnet{name=xiaosi}
str3->Stu{age=25}
str4->Stu{name=xiaosi, age=25}
str5->Stu{name=xiaosi}
4.1 toStringHelper(Object self)

备注:这个方法在2016年6月弃用,使用

根据Object对象self来生成ToStringHelper对象

@Deprecated
  public static ToStringHelper toStringHelper(Object self) {
    return new ToStringHelper(MoreObjects.simpleName(self.getClass()));
  }

重载函数 根据class对象clazz生成ToStringHelper对象

@Deprecated
  public static ToStringHelper toStringHelper(Class<?> clazz) {
    return new ToStringHelper(MoreObjects.simpleName(clazz));
  }

重载函数 根据字符串形式的className生成ToStringHelper对象

@Deprecated
  public static ToStringHelper toStringHelper(String className) {
    return new ToStringHelper(className);
  }
4.2 内部类ToStringHelper
public static final class ToStringHelper {
        private final String className;
        private ValueHolder holderHead = new ValueHolder();
        private ValueHolder holderTail = holderHead;
        private boolean omitNullValues = false;
        // 构造函数 通过字符串格式的className构造ToStringHelper
        private ToStringHelper(String className) {
            this.className = checkNotNull(className);
        }
        // 存放输出的键值对  类似于链表
        private static final class ValueHolder {
            String name;
            Object value;
            ValueHolder next;
        }
        // 设置是否过滤value为null的值
        public ToStringHelper omitNullValues() {
            omitNullValues = true;
            return this;
        }
        // 添加待输出的键值对(name,value)
        public ToStringHelper add(String name, @Nullable Object value) {
            return addHolder(name, value);
        }
        // 重载函数
        ....
        // 不建议这样使用 可以使用addValue(String,Object);代替
        public ToStringHelper addValue(@Nullable Object value) {
            return addHolder(value);
        }
        // 重载函数
        ...
        private ValueHolder addHolder() {
            ValueHolder valueHolder = new ValueHolder();
            holderTail = holderTail.next = valueHolder;
            return valueHolder;
        }
        private ToStringHelper addHolder(@Nullable Object value) {
            ValueHolder valueHolder = addHolder();
            valueHolder.value = value;
            return this;
        }
        private ToStringHelper addHolder(String name, @Nullable Object value) {
            ValueHolder valueHolder = addHolder();
            valueHolder.value = value;
            valueHolder.name = checkNotNull(name);
            return this;
        }
        @Override public String toString() {
            // create a copy to keep it consistent in case value changes
            boolean omitNullValuesSnapshot = omitNullValues;
            String nextSeparator = "";
            StringBuilder builder = new StringBuilder(32).append(className)
                    .append('{');
            // 输出键值对
            for (ValueHolder valueHolder = holderHead.next; valueHolder != null;
                 valueHolder = valueHolder.next) {
                // 如果value为null 不可过滤 或者 value不为null
                if (!omitNullValuesSnapshot || valueHolder.value != null) {
                    builder.append(nextSeparator);
                    nextSeparator = ", ";
                    if (valueHolder.name != null) {
                        builder.append(valueHolder.name).append('=');
                    }
                    builder.append(valueHolder.value);
                }
            }
            return builder.append('}').toString();
        }
    }

只要给定想要输出的键值对,ToStringHelper就会自动帮助你格式化输出。

Objects.toStringHelper("Stu").add("age",25).toString();
目录
相关文章
|
1月前
|
Java
Optional源码分析(涉及Objects源码和Stream源码)
本文分析了Java中Optional类的源码,包括其内部的Objects.requireNonNull方法、EMPTY定义、构造方法、ofNullable方法、isEmpty方法以及如何与Stream类交互,展示了Optional类如何避免空指针异常并提供流式操作。
36 0
Optional源码分析(涉及Objects源码和Stream源码)
|
5月前
|
Java 编译器
Guava Optional类分析
Guava Optional类分析
Guava Optional类分析
|
5月前
|
存储 Java 索引
JavaSE——集合框架一(5/7)-Set系列集合:Set集合的特点、底层原理、哈希表、去重复原理
JavaSE——集合框架一(5/7)-Set系列集合:Set集合的特点、底层原理、哈希表、去重复原理
50 1
|
存储 设计模式 缓存
Java源码分析:Guava之不可变集合ImmutableMap的源码分析
Java源码分析:Guava之不可变集合ImmutableMap的源码分析
61 0
|
6月前
|
SQL JSON Java
Java【问题记录 02】对象封装+固定排序+list All elements are null引起的异常处理+Missing artifact com.sun:tools:jar:1.8.0
Java【问题记录 02】对象封装+固定排序+list All elements are null引起的异常处理+Missing artifact com.sun:tools:jar:1.8.0
75 0
|
设计模式 搜索推荐 算法
JDK中的排序:Arrays.sort的源码实现
JDK中的排序:Arrays.sort的源码实现
543 0
JDK中的排序:Arrays.sort的源码实现
|
Java API
JAVA文档并发演示---并发高级对象摘录(Tutorial - Concurrency Lesson--High Level Concurrency Objects)
JAVA文档并发演示---并发高级对象摘录(Tutorial - Concurrency Lesson--High Level Concurrency Objects)
JAVA文档并发演示---并发高级对象摘录(Tutorial - Concurrency Lesson--High Level Concurrency Objects)
|
存储 缓存 Java
Guava中这些Map的骚操作,让我的代码量减少了50%
Guava是google公司开发的一款Java类库扩展工具包,内含了丰富的API,涵盖了集合、缓存、并发、I/O等多个方面。使用这些API一方面可以简化我们代码,使代码更为优雅,另一方面它补充了很多jdk中没有的功能,能让我们开发中更为高效。
187 0
|
存储 安全 Java
源码解析JDK 1.8 中的 Map.merge()
源码解析JDK 1.8 中的 Map.merge()
源码解析JDK 1.8 中的 Map.merge()
|
消息中间件 缓存 算法
Guava 源码分析(Cache 原理)
Google 出的 Guava 是 Java 核心增强的库,应用非常广泛。 我平时用的也挺频繁,这次就借助日常使用的 Cache 组件来看看 Google 大牛们是如何设计的。