• 2019Java查漏补缺(二)


    查看了公众号:java之间的整理的集和文章,文章地址

    总结和搜索了一下网络知识,总结了一下:

    1.String 的hashcode()方法

    2.switch总结:

    3.如何实现克隆

    1.String 的hashcode()方法

      String也是遵守equals的标准的,也就是 s.equals(s1)为true,则s.hashCode()==s1.hashCode()也为true。此处并不关注eqauls方法,而是讲解 hashCode()方法,String.hashCode()有点意思先来看一下代码:
    public int hashCode() {
    int h = hash;
    if (h == 0 && value.length > 0) {
    char val[] = value;
    for (int i = 0; i < value.length; i++) {
    h = 31 * h + val[i];
    }
    hash = h;
    }
    return h;
    }
    为什么要选31作为乘数呢?
    从网上的资料来看,一般有如下两个原因:
    • 31是一个不大不小的质数,是作为 hashCode 乘子的优选质数之一。另外一些相近的质数,比如37、41、43等等,也都是不错的选择。那么为啥偏偏选中了31呢?请看第二个原因。
    • 31可以被 JVM 优化,31 * i = (i << 5) - i。

    2.switch总结:

    • 底层的switch只能处理4个基本类型的值。其他三种类型需要通过其他方式间接处理,即转成基本类型来处理。
    • 编译器对包装类的处理是通过 拆箱。
    • 对枚举类型的处理,是通过枚举常量的序号及一个数组。
    • 对字符串String的处理,是通过 String 的hash值。
    3.常量池
    常量 可分为 字面常量(也称为直接常量)和 符号常量。
    字面常量: 是指在程序中无需预先定义就可使用的数字、字符、boolen值、字符串等。简单的说,就是确定值的本身。如 10,2L,2.3f,3.5,“hello”,'a',true、false、null 等等。
    符号常量: 是指在程序中用标识符预先定义的,其值在程序中不可改变的量。如 final int a = 5;
    常量池(静态常量池,运行时常量池)
      常量池引入的 目的 是为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享。这是一种 享元模式 的实现。
    1. 字符串常量池属于运行时常量池
    2. 常量池分为:静态常量池(class文件常量池),运行时常量池

    3.如何实现克隆

    浅克隆:
    1. 被复制的类需要实现Clonenable接口(不实现的话在调用clone方法会抛出CloneNotSupportedException异常), 该接口为标记接口(不含任何方法)
    2. 覆盖clone()方法,访问修饰符设为public。方法中调用super.clone()方法得到需要的复制对象。(native为本地方法)
    深克隆
    1.可以通过覆盖Object类的clone()方法实现,
     
    2.也可以通过序列化(Serialization)等方式来实现。
     
    使用序列化实现java的深拷贝
     1 // deepClone()的方法实现
     2 Person person = new Person("sunjs",100);
     3 Person person1 =(Person) person.deepClone();
     4  
     5 //序列化方式
     6 public class CloneUtils {
     7 // 拷贝一个对象
     8 @SuppressWarnings("unchecked")
     9 public static <T extends Serializable> T clone(T obj) {
    10 // 拷贝产生的对象
    11 T clonedObj = null;
    12 try {
    13 // 读取对象字节数据
    14 ByteArrayOutputStream baos = new ByteArrayOutputStream();
    15 ObjectOutputStream oos = new ObjectOutputStream(baos);
    16 oos.writeObject(obj);
    17 oos.close();
    18 // 分配内存空间,写入原始对象,生成新对象
    19 ByteArrayInputStream bais = new ByteArrayInputStream(
    20 baos.toByteArray());
    21 ObjectInputStream ois = new ObjectInputStream(bais);
    22 // 返回新对象,并做类型转换
    23 clonedObj = (T) ois.readObject();
    24 ois.close();
    25 } catch (Exception e) {
    26 e.printStackTrace();
    27 }
    28 return clonedObj;
    29 }
    30 }

  • 相关阅读:
    Python菜鸟之路:Django 序列化数据
    Python菜鸟之路:Django 数据验证之钩子和Form表单验证
    Python菜鸟之路:Django 路由补充1:FBV和CBV
    Python菜鸟之路:Django 文件上传的几种方式
    Python菜鸟之路:Django 分页
    Python菜鸟之路:Django 信号
    Python菜鸟之路:Django 缓存
    《将博客搬至CSDN》
    Java基础语法
    Java基础语法
  • 原文地址:https://www.cnblogs.com/liguo-wang/p/10463863.html
Copyright © 2020-2023  润新知