常用类

Posted sx-xiaoL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了常用类相关的知识,希望对你有一定的参考价值。

常用类

内部类

Object类

  • 超类、基类,所有类的直接或间接父类,位于继承树的最顶层。

  • 任何类,如果没有书写extends显示继承某个类,都默认直接继承Object类,否则为间接继承。

  • Object类中所定义的方法,是所有对象都具备的方法。

  • Object类型可以存储任何对象。

    • 作为参数,可以接受任何对象。

    • 作为返回值,可以返回任何对象。

getClass()放法

  • public final Class<?> getClass()

  • 返回引用中存储的实际对象类型。

  • 应用:通常用于判断两个引用中实际存储对象类型是否一致。

hashCode方法

  • public int hashCode()

  • 返回该对象的哈希码值。

  • 哈希值根据对象的地址或字符串或数字使用hash算法计算出来的int类型的数值。

  • 一般情况下相同对象返回相同的哈希码。

toString()方法

  • public String toString()

  • 返回该对象的字符串表示(表现形式)。

  • 可以根据程序需求覆盖该方法。如:展示对象各个属性值。

equals()方法

  • public boolean equals(Object obj)

  • 默认实现为(this==obj),比较两个对象地址是否相同。

  • 比较的是两个对象的地址。

  • 可进行覆盖,比较两个对象的内容是否相同。进行以下步骤:

    • 比较两个引用是否指向同一个对象。

    • 判断obj是否为null.

    • 判断两个引用指向的实际对象类型是否一致。

    • 强制类型转换。

    • 依次比较各个属性值是否相同。

finalize()方法

  • 当对象被判定为垃圾对象时,由JVM自动调用此方法,用以标记垃圾对象,进入回收队列。

  • 垃圾对象:没有有效引用此对象时,为垃圾对象。

  • 垃圾回收:由GC销毁垃圾对象,释放数据存储空间。

  • 自动回收机制:JVM的内存耗尽,一次性回收所有垃圾对象。

  • 手动回收机制:使用System.gc();通知JVM执行垃圾回收。

包装类

  • 基本数据类型(存放在栈中)所对应的引用数据类型(存放在堆中)。

  • Object类可统一所有数据,包装类的默认值时null.

    基本数据类型 包装类型
    byte Byte
    short Short
    int Integer
    long Long
    float Float
    double Double
    boolean Boolean
    char Character

类型转换与装箱、拆箱

  • 拆箱:引用类型转换成基本类型。
  • 装修:基本类型转换成引用类型。
package inner;

public class Demo01 
    public static void main(String[] args) 
        //JDK1.5之前
        //类型转换:装箱 基本类型转换成引用类型
        int num1=10;//基本类型
        //使用Integer类创建对象
        Integer integer1=new Integer(num1);
        Integer integer2=Integer.valueOf(num1);
        System.out.println("装箱");
        System.out.println(integer1);
        System.out.println(integer2);
        //类型转换:拆箱  引用类型转换成基本类型
        Integer integer3=new Integer(100);
        int num2=integer3.intValue();
        System.out.println("拆箱");
        System.out.println(num2);
        //JDK1.5之后,提供自动装箱和拆箱功能
        int age=30;
        //自动装箱
        Integer integer4=age;
        System.out.println("自动装箱");
        System.out.println(integer4);
        //自动拆箱
        int age2=integer4;
        System.out.println("自动拆箱");
        System.out.println(age2);
    

  • 八种包装类提供不同类型间的转换方式:

    • Number父类中提供的6个共性方法。
    • parseXXX()静态方法。
    • valueOf()静态方法。

基本类型和字符串之间发转换

package inner;

public class Demo02 
    public static void main(String[] args) 
        //基本类型转换成字符串
        int i = 100;
        //1.使用+号
        String s1 = i + "";
        //2.使用Integer中的toString()
        String s2 = Integer.toString(i);
        System.out.println(s1);//100
        System.out.println(s2);//100
        //字符串转换成基本类型
        String str="150";
        //1.使用Integer.parseXXX();
        int n=Integer.parseInt(str);
        System.out.println(n);//150
         //boolean字符串形式转成基本类型,“true”转成true,非true转成false
        String str2="true";
        boolean b=Boolean.parseBoolean(str2);
        System.out.println(b);//true
    

注意:需保证类型兼容,否则抛出NumberException异常。

初识常用类

初识常用类

大家好呀!我是小笙!我学习了韩顺平老师的类和对象的知识,收获颇丰!现在来和大家分享笔记!

常用类

包装类(Wrapper)

包装类的分类

包装类基本数据类型直接父类
booleanBooleanObject
charCharacterObject
byteByteNumber
shortShortNumber
intIntNumber
longLongNumber
floatFloatNumber
doubleDoubleNumber

Boolean

Character

Number父类下的直接子类

装箱 & 拆箱

  • 自动拆装箱
  • 手动拆装箱
public class Wrapper01 
    public static void main(String[] args) 
        // jdk5以前手动装箱&手动拆箱;jdk5之后可以自动拆装箱
        // 以Character为例
        char name = 'n';
        // 手动装箱
        Character ch1 = new Character(name); // 不推荐
        Character ch2 = Character.valueOf(name);
        // 手动拆箱
        char name2 = Character.valueOf(ch2); // 本质就是使用charValue方法
        char name3 = ch1.charValue();

        // 自动装箱
        Character ch3 = name; // 本质使用的就是valueOf方法
        // 自动拆箱
        char CH4 = ch3; // 本质就是使用charValue方法
    

接下来我对于自动拆装箱的底层进行追踪结果

首先打四个断点,分别探索这四个断点的跳转

以下是依次跳转的函数

总结

  1. 手动拆装箱和自动拆装箱底层没有本质区别
  2. 包装类转 <=>基本数据类型
    • 基本数据类型 --> 包装类 装箱 本质:valueOf函数
    • 包装类 --> 基本数据类型 拆箱 本质:charValue函数

习题

// 如下输出结果是什么
习题1
Object obj = true? new Integer(1):new Double(2.0); // 三元运算符是一个整体
System.out.println(obj); // 1.0
习题2
Object obj1;
if(true)
    obj1 = new Integer(1);
else
    obj1 = new Double(2.0);

System.out.println(obj); // 1

包装类 <=> String类

Wrapper Vs String
public class WrapperVsString 
    public static void main(String[]args)
        // String类 转换成 包装类
        String age = "120"; 
        Integer age2 = Integer.valueOf(age);  // 方式一:valueOf函数 本质上就是parseInt()方法
        Integer a2 = Integer.parseInt(age); // 方式二:parseInt函数
        Integer age3 = new Integer(age);  //不推荐,本质就是parseInt()方法

        // 包装类 转换成 String类
        Integer height = 180; // 自动装箱
        String h = String.valueOf(height); // 方式一:valueOf函数 本质就是调用toString()方法
        String h2 = height + "";  // 方式二: 类型转换 Integer + ""
        String h3 = height.toString(); // 方式三: toString()函数

        /*
         *   String.valueOf()源码
         *   public static String valueOf(Object obj) 
         *       return (obj == null) ? "null" : obj.toString();
         *   
         * 
         *   Integer.valueOf()源码
         *   public static Integer valueOf(String s) throws NumberFormatException 
         *        return Integer.valueOf(parseInt(s, 10)); // 10指的是传入的数字是十进制数
         *   
         *
         *   new Integer()源码
         *   @Deprecated(since="9")
         *   public Integer(String s) throws NumberFormatException 
         *          this.value = parseInt(s, 10);
         *   
         */
    

Wrapper类的常用方法

Integer 官方文档

以Integer包装类为例

包装类的相关面试题

public class Wrapper02 
    public static void main(String[] args) 
        /*
         * 源码:IntegerCache.low -128   IntegerCache.high 127
         *     public static Integer valueOf(int i) 
         *         if (i >= IntegerCache.low && i <= IntegerCache.high)
         *             return IntegerCache.cache[i + (-IntegerCache.low)];
         *         return new Integer(i);
         *     
         * 如果valueOf(value) value > -128 && value < 127 则 返回 IntegerCache.cache[i + (-IntegerCache.low)]
         * 否则 返回新对象Integer
         */
        System.out.println(new Integer(1) == new Integer(1));  // false
        Integer a = 1;
        Integer b = 1;
        System.out.println(a==b); // true
        Integer m = 128;
        Integer n = 128;
        System.out.println(m==n); // false
        Integer x = 128;
        int y = 128;
        System.out.println(x==y); // true
        
    

String类

String类的概述

public static void main(String[] args) 
       /**
         * String
         * 概念:是一组字符序列 本质上是char[] value 字符数组实现
         * "Al_tair"被称为字符常量 用双引号括起来的字符序列
         *  一个字符占用两个字节(每个字符不区分字母和汉字)
         * public final class String 说明String的final类,不能被其它类继承
         * private final byte[] value 用于存放字符串 value是用final修饰的类型,该数组不能指向新地址,但是能修改它的值
         */
    String name = "Al_tair";

接口和构造器

String内存图

// 运行代码,内存图如下
class code
    public static void main(String[] args)
        String a = "Al_tair";
        String b = new String("Al_tair");
    

内存图: 字符串 VS 字符数组

结合代码和内存图分析

class Text
    String str = new String("lns");
    // final指的是char类型数据存储的地址不能改变,但是值是可以改变的
    final char[] ch = 'j','a','v','a';
    public void change(String str,char[] ch)
        str = "zlr";
        ch[1] = 'c';
    
    public static void main(String[] args) 
        Text text = new Text();
        text.change(text.str,text.ch);
        System.out.println(text.str.toString()+" and "+text.ch[1]); // lnsandc
    

String类的常用方法

  • equals 区别大小写,判断字符串的内容是否相同
  • equalsIgnoreCase 忽略大小写 来判断字符串的内容是否相同
  • length 获取字符串的个数,或者称为字符串长度
  • indexOf 获取字符在字符串中第一次出现的索引,索引从0开始,如果没有找到则返回-1
  • lastindexOf 获取字符在字符串中最后一次出现的索引,索引从0开始,如果没有找到则返回-1
  • substring 截取指定范围的字串
  • trim 去掉字符串前后的空格
  • charAt 获取某索引处的字符
  • compareTo 比较两个字符串的大小,如果前者大于等于后者,则返回自然数;反之后者大,则返回负数
  • intern 如果常量池中已经包含值相同的字符串,则返回常量池中的字符串引用地址,否则将String对象添加到常量池中,并返回String对象的引用
// equals()方法源码
public boolean equals(Object anObject) 
    if (this == anObject)  // 地址是否相同
        return true;
    
    if (anObject instanceof String)  // 是否为String类或者String父类
        String aString = (String)anObject;
        if (!COMPACT_STRINGS || this.coder == aString.coder) 
            return StringLatin1.equals(value, aString.value);
        
    
    return false;

@HotSpotIntrinsicCandidate
public static boolean equals(byte[] value, byte[] other) 
    if (value.length == other.length) 
        for (int i = 0; i < value.length; i++) 
            if (value[i] != other[i]) 
                return false;
            
        
        return true;
    
    return false;


// 占位符的讲解 涉及方法format <=> c语言输出
// %s,%d,%.3f,%c
String name = "lns";
int age = 18;
double height = 185.35;
char gender = '男';

String Info = "姓名:%s\\t年龄:%d\\t身高:%.3f\\t性别:%c";
String show = String.format(Info,name,age,height,gender);
System.out.println(show); // 姓名:lns	年龄:18	身高:185.350	性别:男

String 官方文档

相关习题

// 习题1
String a = "l";
String b = new String("l");
System.out.println(a.equals(b)); // true
System.out.println(a == b); // false
System.out.println(a == b.intern()); // true
System.out.println(b == b.intern()); // false

// 习题2
// 2.1创建了几个对象 答:2
String s = "hello";
s = "haha";

// 2.2 创建了几个对象 答:1  结论:编译器会做优化,判断常量池对象是否有引用指向
String str = "hello" + "haha";  // 等价于 String str = "hellohaha";

// 2.3 创建了几个对象 答:3  结论:字符串常量相加地址存放在常量池,字符串变量相加地址存放在String对象中
// sum 指向的是value[](String对象),再指向常量池中"HelloString"字符串
public static void main(String[]args)
    String m = "Hello";
    String n = "String";
    /*
     * 解读:
     * 1. 创建新对象 new StringBuilder();
     * 2. 通过append函数添加字符串 “Hello”
     * 3. 通过append函数添加字符串 “String”
     * 4. 返回new String("HelloString");
     */
    String sum = m + n;

// 分析sum 的指向和底层源码
// debug test
// first insert
public StringBuilder() 
    super(16);

//secong insert  str = "Hello"
public StringBuilder append(String str)   
    super.append(str);
    return this;

// third insert str = "String"
public StringBuilder append(String str) 
    super.append(str);
    return this;

// last one
public String toString() 
    // Create a copy, don't share the array
    return isLatin1() ? StringLatin1.newString(value, 0, count): StringUTF16.newString(value, 0, count);


StringBuffer类

概念:代表可变的字符序列,可以对字符串内容进行增删,是一个容器

构造方法

Constructor and Description
StringBuffer()构造一个没有字符的字符串缓冲区,初始容量为16个字符。
StringBuffer(CharSequence seq)构造一个包含与指定的相同字符的字符串缓冲区 CharSequence
StringBuffer(int capacity)构造一个没有字符的字符串缓冲区和指定的初始容量。
StringBuffer(String str)构造一个初始化为指定字符串内容的字符串缓冲区。
/*
 * Constructs a string buffer with no characters in it and an
 * initial capacity of 16 characters.
 * StringBuffer()构造器
 */
@HotSpotIntrinsicCandidate
public StringBuffer() 
    super(16); // 初始容量为16个字符 存储在父类的value数组中

String类 <=> StringBuffer类

String类和StringBuffer类的区别

  • String保存的是字符串常量,里面的值不能更改,每次值的更新实际上就是更改地址,效率低
  • Stringbuffer保存的是字符串变量,里面的值是可以改变的,不需要每次都更改地址,效率高

String类和StringBuffer类的相互转换

public static void main(String[] args) 
    // String和StringBuffer的相互转换
    // String => StringBuffer
    String str = "lns";
    StringBuffer stringBuffer = new StringBuffer(str); // 方式一: 使用StringBuffer构造器
    StringBuffer append = new StringBuffer().append(str); // 方式二: 使用的是append方法

    // StringBuffer => String
    StringBuffer sbr = new StringBuffer("zlr");
    String s = sbr.toString(); // 方式一: 使用toString方法
    String s1 = new String(sbr); // 使用String构造器 

常用方法

public static void main(String[] args) 
    // 常用方法
    // append 增
    StringBuffer stringBuffer = new StringBuffer("");
    stringBuffer.append("lns"); // lns
    /*
     *  append源码
     *  不管传入什么数据类型,返回StringBuffer类型
     *  public synchronized StringBuffer append(String str) 
     *      toStringCache = null;
     *      super.append(str);
     *      return this;
     *  
     */

    // delete 删除
    // 删除索引范围 [start,end)
    stringBuffer.delete(0,1); // 删除第一个字符 ns

    // replace 替换
    // 替换范围[start,end)
    stringBuffer.replace(0, 1,"ln"); // lns

    // indexOf 查找
    // 查找第一次在字符串中出现的索引,如果查找到会返回你查找的字符串首个字母索引,如果找不到返回-1
    stringBuffer.indexOf("ns"); // 1

    // length 长度
    System.out.println(stringBuffer.length()); // 3

相关习题

// 习题1
String str = null;
StringBuffer sb = new StringBuffer();
sb.append(str);
System.out.println(sb); // null
System.out.println(sb.length()); // 4  
/*
 *  // 底层分析
 *  // StingBuffer类
 *  public synchronized StringBuffer append(String str) 
 *      toStringCache = null;
 *      super.append(str); // 跳转到父类
 *      return this;
 *  
 *  // AbstractStringBuilder抽象类
 *  public AbstractStringBuilder append(String str) 
 *      if (str == null) 
 *          return appendNull(); // 跳转到该方法
 *      
 *      int len = str.length();
 *      ensureCapacityInternal(count + len);
 *      putStringAt(count, str);
 *      count += len;
 *      return this;
 *  
 *  // appendNull方法
 *  private AbstractStringBuilder appendNull() 
 *      ensureCapacityInternal(count + 4);
 *      int count = this.count;
 *      byte[] val = this.value;
 *      if (isLatin1()) 
 *          val[count++] = 'n';
 *          val[count++] = 'u';
 *          val[count++] = 'l';
 *          val[count++] = 'l';
 *       else 
 *          count = StringUTF16.putCharsAt(val, count, 'n', 'u', 'l', 'l');
 *      
 *      this.count = count;
 *      return this;
 *  
 */
 StringBuffer sb = new StringBuffer(str); // 抛出空指针异常 NullPointerException
 /*
 * AbstractStringBuilder(String str) 
 *    int length = str.length(); // str为null 
 *    int capacity = (length < Integer.MAX_VALUE - 16)
 *           ? length + 16 : Integer.MAX_VALUE;
 *    final byte initCoder = str.coder();
 *    coder = initCoder;
 *    value = (initCoder == LATIN1)
 *           ? new byte[capacity] : StringUTF16.newBytesFor(capacity);
 *    append(str);
 * 
 */

StringBuilder类

概念:一个可变的字符序列。 线程不安全。 此类设计用作简易替换为StringBuffer在正在使用由单个线程字符串缓冲区的地方。 在可以的情况下,建议使用这个类别优先于StringBuffer ,因为它在大多数实现中将更快。

大部分与 StringBuffer类似

特殊点:没有做互斥处理,因此在单线程下使用

// 源码剖析 区别在于关键字 synchronized 保证线程安全
// StringBuffer 的append方法
@Override
@HotSpotIntrinsicCandidate
public synchronized StringBuffer append(String str) 
    toStringCache = null;
    super.append(str);
    return this;


// StringBuilder 的append方法
@Override
@HotSpotIntrinsicCandidate
public StringBuilder append(String str) 
    super.append(str);
    return this;

String,StringBuffer,StringBuilder的区别

  • String:不可变字符序列,效率低,但是因为存在常量池所以复用率高
  • StringBuffer:可变字符序列,效率较高(增删),线程安全 、
  • StringBuilder:可变字符序列,效率最高,线程不安全

使用原则

  • 如果字符串存在大量的修改操作,一般使用StringBuffer或者StringBuider
  • 如果字符串存在大量的修改操作,并在单线程的情况,使用StringBuilder
  • 如果字符串存在大量的修改操作,并在多线程的情况,使用StringBuffer
  • 如果字符串很少修改,被多个对象引用,使用String 比如:配置信息等

Math类

概念:Math类包含执行基本数学运算的方法

常用方法

public static void main(String[] args) 
    // Math类中大部分是静态方法,可以直接通过类名.方法名访问
    // abs 绝对值
    int abs = Math.abs(-10);
    System.out.println(abs); // 10

    // pow 求幂
    double pow = Math.pow(2,4);
    System.out.println(pow); // 16.0

    // ceil 向上取整,返回>=该参数的最小整数(整数会转换成double型)
    double ceil = Math.ceil(-3.002);
    System.out.println(ceil); // -3.0

    // floor 向下取整,返回<=该参数的最大整数(整数会转换成double型)
    double floor = Math.flo

以上是关于常用类的主要内容,如果未能解决你的问题,请参考以下文章

初识常用类

Java常用类--String类常用方法

StringUtils工具类常用方法汇总

常用集合类

Java五个最常用的集合类之间的区别和联系

Java入土---常用类