JavaAPI


JavaAPI: 是Java预先定义的类或接口功能的说明文档,目的是提供给开发人员进行帮助说明

一、Object类

1.1 概念

    Object类是所有Java类的祖先。每个类都是用Object类作为父类。所有对象(包括数组)都实现了这个类的方法。如果在类的生命中未使用extends关键字指明其基类,则默认基类为Object类。

1.2 toString方法

1.2.1 toString方法介绍

    当我们使用System.out.println(对象)输出对象的时候,看似输出的是对象,其实输出的是一个字符串。这是因为输出对象的时候,默认会调用类中的toString()方法。
    如果我们方法中没有定义toString()方法,那么就会使用Object类中的toString()方法。下面是 jdk1.8 中toString()方法的定义:

	/*
	getClass().getName()负责拿到类的类名,`@`就是一个分隔符
	hashCode()拿到对象在内存中的哈希值
	Integer.toHexString(hashCode())负责将对象在内存中的哈希值转换为16进制
	最后将拼接的字符串返回
	*/
    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

1.2.2 toString方法重写

    上述就是Object类中的toString()方法,其目的是拼接类名和@和对象在内存中的16进制哈希地址,而子类中要求看到对象的值,这个时候就是父类中的方法不满足子类中的需求了,所以我们在我们创建的类中对toString()方法进行重写,使得输出内容符合我们的预期。这里我们可以直接使用IDEA工具使用ctrl+o键选中要重写的方法,这时IDEA便会将重写的方法自动生成,其输出格式类似于json字符串,可以清晰的看清楚对象的属性。

1.3 equals方法

1.3.1 ==号和equals方法的引入

我们在以前学习的==号的时候,对象这种符号有一个初步的认识
1.当等号两端都是基本类型时,会判断值是否相等
2.当等号两端都是引用数据类型时,会判断引用对象所指向的内存空间是否相等
注意: 基本数据类型和引用数据类型无法比较,并且等号两端类型必须一致,要么符合继承关系
    和toString()方法一致,我们不想通过引用数据类型地址来判断等号两端是否相等,比如下述例子,我们一般会认为下面两个对象一致,但是在内存中由于地址的不一致,导致双等号判断结果为false

        String a = new String("abc");
        String b = new String("abc");

1.3.2 String类中的equals方法

    有时候我们更重视的是对象的值,而不是对象的地址是否相等。Java中恰好已经有类实现了根据值判断是否相等的方法,这个类就是String类,而实现比较值的方法则是String类的equals()方法,这个方法是重写了Object类中的equals()方法,进而实现了根据对String对象的值判断结果是否相等的。下面是jdk1.8String类中equals()方法的声明,首先根据内存地址判断,然后进行了字符串的匹配,代码十分完美,如果地址一致不需要字符串匹配就返回true而不是一味的进行字符串匹配,这样会十分消耗性能

    public boolean equals(Object anObject) {
        if (this == anObject) {// 首先根据内存地址判断
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {// 如果字符串长度一致,进而进行字符串的匹配
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

1.3.3 对equals的重写

    上面String类中之所以可以实现字符串的值比较,是因为String对String类中的equals方法进行了重写,我们需要对象值判断的话就要重写Object类中的equals方法,另外Object类中的equals()方法的实现和双等号一致,通过判断引用所指向内存空间的相同与否返回相应的结果
这是一个简单的重写equals()方法的例子,重写的equals()方法既可以根据内存地址判断,还可以通过对象值的一致判定对象的相等。

public class Person {

    int age;

    String name;

    @Override
    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        Person person = (Person) anObject;
        if (this.age == person.age && this.name.equals(person.name)) {
            return true;
        }
        return false;
    }
}

1.4 TODO

二、基本类型包装类

1.为什么需要包装类?

	1.对象化:Java是一种面向对象的编程语言,基本数据类型不是对象,不能享受面向对象编程的诸多特性,
		包装类可以把基本数据类型包装起来,是他们可以像对象一样被处理。
	2.便于存储和传输:在Java中集合类只能存储对象,通过包装类将基本数据类型转为对象就可以进行存储。
	3.提供了更多功能和方法:包装类为基本数据类型提供了更多功能。例如:Integer可以转化为字符串类型,
		Double类提供了四舍五入等等。
	4.NULL值:基本数据类型不可以赋值null,而包装类可以。在某种情况下,我们需要表示一个不存在的值
	时,就可以使用null表示

    总的来说,就是Java提供的基本数据类型包装类,对基本类型的功能进行了增强,可以面对更复杂的情况基本

2.基本类型和包装类型转换

    在包装类型中有方法可以实现基本类型与包装类型之间的相互转换,例如Integer包装类中的方法:

      int a = 100;
      Integer b = new Integer(a);// 基本数据类型--> 包装类型
      int c = b.intValue();// 包装类型--> 基本类型

    这样虽然可以实现基本数据类型与包装类型之间的相互转换,但是有点麻烦,所以Java中提供了两种方法,可以实现自动化的转换

2.1 自动装箱

      int d = 200;
      // 把基本类型直接赋值给引用类型,进行包装,产生了Integer类的对象,自动装箱
      Integer e = d;

我们在自动装箱的一性debug进入方法,发现来到了这个方法上:

    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

    当我们使用自动装箱创建包装类型时,就会默认调用这个方法,如果我们创建的包装类型值位于[-128,127]范围内,就会返回我们IntegerCache这个包装类中常量池中定义的Integer包装类型对象,这就是为什么我们下面这段代码会输出false的原因,因为只要在[-128,127]范围内的包装类型都会使用Java中早已创建好的Integer对象

    Integer a = 127;
    Integer b = 127;
    System.out.println(a==b);

2.2 自动拆箱

      Integer f = new Integer(50);
      // 把包装类型直接赋值给引用类型,自动拆箱,默认调用了包装类型的intValue()方法
      int g = f;

三、Arrays类

java.util.Arrays 包含了许多数组操作的方法。

3.1 equals()方法

    这是equals(int[] a, int[] a2)方法的实现,Arrays类中还有比较其他类型数组的方法,其基本的实现基本一致,在这里不多赘述,观看源码可知,通过判断对应位置元素是否相等返回结果

    public static boolean equals(short[] a, short a2[]) {
        if (a==a2)
            return true;
        if (a==null || a2==null)
            return false;

        int length = a.length;
        if (a2.length != length)
            return false;

        for (int i=0; i<length; i++)
            if (a[i] != a2[i])
                return false;

        return true;
    }

3.2 toString()方法

    这是toString(int[] a) 方法的实现,也是同样我只举int类型数组的例子,观看源码可知,如果数组为null返回null;如果数组长度为0,返回空字符串;否则返回[元素值,元素值,…]的字符串,就是对数组中的元素循环打印。

    public static String toString(int[] a) {
        if (a == null)
            return "null";
        int iMax = a.length - 1;
        if (iMax == -1)
            return "[]";

        StringBuilder b = new StringBuilder();
        b.append('[');
        for (int i = 0; ; i++) {
            b.append(a[i]);
            if (i == iMax)
                return b.append(']').toString();
            b.append(", ");
        }
    }

3.3 binarySearch()方法

这里就不写源码了,二分查找是一个 O ( l g n ) O(lgn) O(lgn)时间复杂度的查找算法

3.4 sort()方法

    对数组数组排序,不仅可以支持基本数据类型的排序,还可以支持引用数据类型排序,例如,String类型,甚至是我们创建的类型,只需实现Comparable接口即可,这就和前面接口的只是串联起来了,接口对我们的类可以增强,Comparable接口就可以使我们的类增加比大小的功能,下面是一个实例:
Demo1类实现Comparable接口中的compareTo方法,这下sort方法便可以对Demo1类型的数组进行排序了

public class Demo1 implements Comparable<Demo1> {
    private int age;
    private String name;

    @Override
    public int compareTo(Demo1 o) {
        return this.age - o.age;
    }
}

3.4 copyOf(int[] original, int newLength)方法

可以将数组扩容或缩容至指定大小
1.如果newLength小于original.length,数组便会缩容至指定大小,长度超过newLength的数组元素会被舍弃。
1.如果newLength大于original.length,数组便会扩容至指定大小,长度超过original.length的新数组元素会赋默认值0.

四、String类概述

    String是开发中频率最高的类型,字符串是由多个字符组成的一串字符串常量。Java中所有的字符串都是String类的实例。

创建字符串对象的方法

1. 不使用new关键字

String s = “abc”;
创建过程:现在栈中创建一个String类的引用,然后再字符串常量池中查找有没有"abc"。如果常量池中有,直接指向该字符串对象地址,不需要创建对象。如果常量池中没有,会在常量池中添加"abc"字符串,然后让引用指向字符串对象地址。

2. 使用new关键字

String s = new String(“abc”)
一概在队中创建对象,值存在堆内存的对象中。

3. 对比

上述两种方式,不使用new关键字的方式,只是使栈中的引用指向了字符串常量池中的对象地址。而使用new关键字的方式是战中的引用首先在堆中创建类String类对象,然后String对象的值指向了在字符串常量池中的字符串对象,最后使用String引用指向了在堆中创建的String对象的地址,就是对字符串进行了包装,而这个包装类是String类。

五、StringBuffer

5.1 构造方法

5.1.1 public StringBuffer()

源码:调用了父类AbstractStringBuilder中的AbstractStringBuilder(int capacity)方法,初始化类一个长度为16的char类型数组,并且这个数组没有final关键字修饰。前面我们了解到String类封装类一个final关键字修饰的字符数组,所以String对象无法修改字符串的值。而StringBuffer类中封装的字符数组没有final关键字修饰,所以它是可变的

    public StringBuffer() {
        super(16);
    }
	char[] value;
    AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }

5.1.2 StringBuffer(int capacity)

源码:与StringBuffer的无参构造一致,调用了AbstractStringBuilder(int capacity)方法

    public StringBuffer(int capacity) {
        super(capacity);
    }

5.1.3 StringBuffer(String str)

源码:首先创建了一个长度是我们字符串参数长度+16的字符数组,然后字符串参数追加到字符数组中

    public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
    }

5.2 常用方法

5.2.1 添加功能

// 字符串追加
public StringBuffer append(String str)
// 在指定位置添加字符串
public StringBuffer insert(int offset, String str)

5.2.2 删除功能

public StringBuffer deleteCharAt(int index)
public StringBuffer delete(int start, int end)

5.2.3 替换功能

public StringBuffer replace(int start, int end, String str)

5.2.4 翻转功能

public StringBuffer reverse()

5.3 String,StringBuffer和StringBuilder

String 对象的值不可变,适用于少量拼接
StringBuffer 对象值可变,是线程安全的,适用于大量拼接
StringBuilder 对象值可变,非线程安全,是用与大量拼接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值