Object,String,StringBuffer,Date,Math

JavaSE

一.Object类

  1. Java中所有类的直接或者间接父类。
  2. 只有无参构造方法。所以我们定义的类中,才都有无参构造方法。

1.getClass():

本质:在类加载的时候,JVM会为这个类生成一个Class对象,方便我们使用者获得这个类的信息。这个Class对象可以类比于这个类,类和Class对象是一一对应的关系。通过面向对象的语法,访问Class对象我们可以获得类定义的相关信息。
Class对象所对应的Class类是抽取了什么共性而组成的呢?

因为Class类都能:(共性)

  1. 可以定义构造方法。
  2. 可以定义成员变量。
  3. 可以定义成员方法。

Class对象在1.7及以前存放在方法区,1.7之后存在堆中。

作用:

返回此对象运行时的类。

package day11;
public class Demo1GetClass {
    public static void main(String[] args) {
        Test test = new Test();
        Class obj = test.getClass();
        System.out.println(obj.getName());
    }
}
class Test{
    int i;
    public void print(){
    }
}

2.toString()

作用:
  1. 返回该对象的字符串表示。
  2. toString方法会返回一个”以文本方式表示“对象字符串,在没有重写时,默认输出 getClass().getName() + ‘@’ + Integer.toHexString(hashCode())。因此我们一般要重写这个方法,输出它的属性。
注:
//test为对象名
System.out.println(test);    //自动调用toString()
String str = "hello, " + test;  //同上
System.out.println(str);    

3.equals()

作用:

指示其他对象与该对象是否相等。(这里的相等是指两个对象是完全相同的两个对象)我们一般要重写这个equals()方法。让两个对象只要变量相同即可。在改写时要遵守几个定义:

  1. 自反性 (条件一)
  2. 对称性
  3. 传递性
  4. 一致性
  5. null与任何其他对象都不相等。 (条件二)
public class Demo1Equals {
}
class Test{
    int i;
    double j;
    @Override
    public boolean equals(Object obj) {
        if( obj == this )
            return true;
        if(obj == null || this.getClass() != obj.getClass())
            return false;

        Test obj1 = (Test)obj;   //obj是Object类型,没有i,j等成员变量,这里需要强转类型。
        if(this.i != obj1.i)
        {
            return false;
        }
        return  Double.compare(this.j, obj1.j) == 0; //double之间的精确比较应该通过这个方法。返回0则相同,返回非0则不同。
    }
}

4.hashCode()

作用:

返回该对象的哈希码值。

hash函数作用:

A hash function is any function that can be used to map data of arbitrary size onto data of fixed size.
能把无限多的值映射到固定多的值中

对象的hash码值

Object类定义的默认实现一般是通过对象的内部地址转化成一个整数。

与equals()的关系

未重写的equals方法的结果为true时,在没有改equals方法的前提下,则hash码应该相同。但是两对象equals不等,hash码却不一定不同。因为很难做都一对一对应。

5.clone()

作用:
protected Object clone()
      创建并返回此对象的一个副本

这个副本是浅拷贝。是完全生成一个全新的对象。但是浅拷贝不会去生成一个新的引用成员变量所指向的对象,只会单纯拷贝引用变量的地址值,致使拷贝出来的对象指向同一个引用对象。

clone()的权限问题。

在同包的两个类中,当我们在一个类中调用另一个类的对象的clone()方法时,即使clone方法时protected权限的,还是会出现权限问题,因为clone方法都是继承自Object的跨包方法,protected权限的方法跨包时除了在子类中,其他情况是不能访问的,此时的解法只有在调用了clone()方法的类定义下,重载clone()方法,让这个方法与两个类同包,才能使用。

标记接口:

被clone的类必须实现Cloneable接口,该接口是一个空接口。这是一个编程技巧。实现了接口之后,该类可在 instanceof Cloneable时返回true。类可以被看做是Cloneable接口类型了。

将clone()方法改写成一个深拷贝
class FirstLevel implements Cloneable {
    int firstInt;
    double firstDouble;
    SecondLevel second;
    @Override
    public String toString() {
        return "firstInt = " + firstInt + " firstDouble = " + firstDouble + " second = {" + second + "}";
    }
    public FirstLevel(int firstInt, double firstDouble, SecondLevel second)
    {
        this.firstInt = firstInt;
        this.firstDouble = firstDouble;
        this.second = second;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        FirstLevel clone = (FirstLevel)super.clone();   //利用Object的clone()方法,先对当前的FirstLevel进行浅拷贝。
        clone.second = (SecondLevel)clone.second.clone();   //针对复制对象中的引用类型变量进行拷贝
        return clone;
    }
}

6.finalize()

当垃圾回收器确定不存在该对象的更多引用时,对象的垃圾回收器会自己调用这个方法,但不是马上调用。
用户可以重写这个方法,达到配置系统资源,执行其他清除的作用。

二.String类

1.定义:

字符串是由多个字符组成的一串数据。

2.构造方法:

  1. public String() -----> 创建一个空串:"" 一般不用
  2. public String(byte[] bytes)
byte[] bytes = {97, 98, 99};
String s = new String(bytes);
System.out.println(s);
//输出 abc
  1. public String(byte[] bytes, int offset, int length)
byte[] bytes = {97, 98, 99};
String s = new String(bytes, 1, 2);
//输出 bc
  1. public String(char[] value)
char[] value = {'a', 'b', 'c'};
String s = new String(value);
  1. public String(char[] value, int offset, int length)
  2. public String(String orignal)
char[] value = {'a', 'b', 'c'};
String s = new String(value);
String s2 = new String(s);
System.out.println(s2)
System.out.println(s == s2); //输出false
s.equals(s2)  //输出true
//可以看出String类中重写了equals方法。

3.String在Java中的一个特征

字符串是”常量“,但不是字面上的常量。它的值在创建后就不能再更改。
这里的“不可再更改”的意思是,当我们创建一个字符串对象后,如果改变这个字符串对象的内容,则会自动再生成一个字符串对象,让引用变量指向新的字符串对象。

4.面试问题

第一题:
String s = "hello";
s += "world";
s的结果为多少。 ---->  "helloworld"
第一句:

“hello”为字符串字面值常量,存储在字符串常量池中,存储的方式仍然是以一个字符串对象来存储的。
首先判断是否存在这个字符串字面值常量,如果存在,则将该对象的地址直接赋给引用变量s。如果不存在则在常量池中创建一个字符串对象,再将地址赋值给引用变量s。

第二句:

首先判断“world”字符串常量有没有在常量池中,有则下一步,没有则在字符串常量池中创建一个字符串常量"world"。由于字符串是“常量”,是不可改变的,所以需要在堆中创建一个新的字符串对象,将“hello”和“world”拼接起来存入对象。将首地址赋值给引用变量s。
在这里插入图片描述
注:字符串常量池在jdk1.6及以前存储在方法区中,1.7开始存储在堆中,一般还是以存在方法区中为准。

第二题:
String s1 = new String("hello");
String s2 = "hello";    之间的区别
第一句:

首先在字符串常量池中寻找是否存在字符串常量“hello”,若没有则创建一个字符串对象存进字符串常量“hello”,这个字符串对象的字符序列是存储在一个char字符数组中的。
再在堆中创建一个String类的对象,将存储字符串常量“hello”的对象中的char字符数组的首地址赋值给堆中的String类对象的char字符数组,两者指向同一个“hello”字符数组。
再在栈帧中创建String类型的引用变量s1存入堆中String类型对象的首地址,使其指向堆中的String对象。

第二句:

在字符串常量池中查找是否有匹配的字符串。找到后,将其首地址赋值给s2。
在这里插入图片描述

第三题:
String s1 = "hello";
String s2 = "world";
String s3 = "helloworld";
System.out.println(s3 == (s1 + s2));  //false。因为s1+s2会指向堆中的一个新对象。而s3是指向常量池中的一个字符串对象。
System.out.println(s3.equals("hello" + "world")); //true。String改写了equals方法,所以字面值相同即可。
System.out.println(s3 == ("hello" + "world")); // true。因为常量是已知的,JVM会将常量直接拼接,在.class上可以体现---->  s3 == "helloworld";(或者final修饰的引用变量,也直接看成常量。)

总结:

  1. 参与拼接的字符串中有一个引用变量,则要在堆上创建新的字符串对象。
  2. 只有参与拼接的字符串都是字符串常量,此时不会在堆上创建新的字符串对象,而是直接拼接,如果常量池没有则在常量池创建。
  3. 引用变量如果被final修饰,则可看成是字符串常量。

5.功能

①判断功能
  1. boolean equals(Object obj) //用来比较字符串的内容
  2. boolean equalsIgnoreCase(String str) //忽略字符串大小写比较字符串内容
  3. boolean contains(String str) //判断当前字符串对象是否包含,目标字符串的字符序列
  4. boolean startsWith(String str) //判断当前字符串对象,是否已目标字符串的字符序列开头
  5. boolean endsWith(String str)// 判断当前字符串,是否以目标字符串对象的字符序列结尾
  6. boolean isEmpty() 判断一个字符串,是不是空字符串
    注:
  7. 空字符串:""
  8. null代表一个无效的内存地址,是不存在对象的。
②获取功能
  1. int length() // 获取当前字符串对象中,包含的字符个数
  2. char charAt(int index) // 获取字符串对象代表字符序列中,指定位置的字符(字符的位置从0开始编号)
  3. int indexOf(char ch) // 在当前字符串对象中,查找指定的字符,如果找到
    // 就返回字符,首次出现的位置,如果没找到返回-1
  4. int indexOf(String str) // 查找当前字符串中,目标字符串首次出现的位置(如果包含)
    // 找不到,返回-1, 这里的位置是指目标字符串的第一个字符
    // 在当前字符串对象中的位置
  5. int indexOf(int ch,int fromIndex) // 指定,从当前字符串对象的指定位置开始,查找首次出现的指定字符的位置(如果没找到返回-1)
  6. int indexOf(String str,int fromIndex) // 指定,从当前字符串对象的指定位置开始,查找 首次 出现的指定字符串的位置(如果没找到返回-1)
  7. String substring(int start) // 返回字符串,该字符串只包含当前字符串中,从指定位置开始(包含指定位置字符),的那部分字符串
    “zhangsan” -> “san”
  8. String substring(int start,int end) // 返回字符串,只包含当前字符串中,从start位置开始(包含),到end(不包含)指定的位置,
    // 这部分字符串 [start, end) ->[start, end - 1]
    注:
  9. API中形参包含start和end范围的,取值范围都是[start,end)。
③转换功能
  1. byte[] getBytes() // 获取一个用来表示字符串对象字符序列的字节数组
  2. char[] toCharArray() // 获取的是用来表示字符串对象字符序列的字符数组
  3. static String valueOf(char[] chs) // 把字符数组转化为字符串
  4. static String valueOf(int i) //把整数转化成其字符串表示形式
  5. String toLowerCase() //把字符串全部转化为小写
  6. String toUpperCase() // 把字符串全部装华为大写
  7. String concat(String str) //字符串拼接 作用等价于 + 实现的字符串拼接
④替换功能
  1. String replace(char old,char new) // 在新的字符串中,用新(new)字符,替换旧(old)字符
  2. String replace(String old, String new) //在新的字符串中,用新的字符串(new), 替换旧(old)字符串
⑤去空格功能

String类去除空格

  1. String trim() //在新的字符串中,去掉开头和结尾的空格字符
⑥比较功能:
  1. int compareTo(String str)
  2. int compareToIgnoreCase(String str) //忽略大小写的比较
compare的源代码
public interface Comparable<T> {
        int compareTo(T o)
        }
 /*
该接口的意义是定义了一种比较大小的协议。
1.interface Comparable<T> 这里的T代表某种数据类型。
2.该接口定义了一种比较规则:比较结果大于,小于,等于关系与int整数映射关系
       对象1.compareTo(对象2)
       1. 大于:  对象1 > 对象2  ->   > 0 正整数表示大于关系
       2. 小于:  对象1 < 对象2  ->   < 0 负整数表示小于关系
       3. 等于:  对象 等于 对象2 ->   = 0 0表示相等关系
  */     
       
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    private final char value[];   //这个就是指String对象中存放字符的那个字符数组。
    public int compareTo(String anotherString) {
        int len1 = value.length;
        int len2 = anotherString.value.length;
        int lim = Math.min(len1, len2);  //取小的那个
        char v1[] = value;
        char v2[] = anotherString.value;
        int k = 0;
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                return c1 - c2;  //巧妙
            }
            k++;
        }
        return len1 - len2;  //巧妙
    }
    }

作业附加题:

/*
附加题:
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
注意:如果有多个最长回文串,返回其中一个即可
*/
package day13;

import java.util.Scanner;

public class Exercise03 {
    public static void main(String[] args) {
    //解法一: 以每个位为对称轴或者以每个位和下一位为对称轴
        Scanner in = new Scanner(System.in);
        System.out.println("请输入一个String:");
        String str = in.nextLine();
        in.close();
        if(str.length() > 1000) {
            System.out.println("不好意思,超过了1000个字符");
            return;
        }
        if(str.length() == 0) {
            System.out.println("String为空");
            return;
        }
        String subStr = "";
        for(int i = 0; i < str.length() - 1; ++i)
        {
            String sub1 = findLongestString(str,i,i);
            String sub2 = findLongestString(str,i,i+1);
            String sub = sub1.length() > sub2.length() ? sub1 : sub2;
            if(sub.length() > subStr.length())
                subStr = sub;
        }
        System.out.println(subStr);
    }
    private static String findLongestString(String str, int start, int end)
    {
        char[] target = str.toCharArray();
        while(start >= 0 && end < str.length() && target[start] == target[end]) {
            start--;
            end++;
        }
        start++;
        end--;
        return new String(target,start,end - start + 1);  //巧妙运用构造函数。
    }
}

/*
解法二:暴力
 public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.println("请输入一个String:");
        String str = in.nextLine();
        in.close();
        if(str.length() > 1000) {
            System.out.println("不好意思,超过了1000个字符");
            return;
        }
        if(str.length() == 0) {
            System.out.println("String为空");
            return;
        }
        String subStr = "";
        int length = 0;
        for(int i = 0; i < str.length() - 1; ++i)
        {
            for(int j = i + 1; j < str.length(); ++j)
            {
                if(isPalindrome(str,i,j))
                {
                    if((j - i + 1) > length)
                    {
                        subStr = str.substring(i,j+1);
                        length = j - i + 1;
                    }
                }
            }
        }
        System.out.println("最长的回文串为:" + subStr);
    }

    public static boolean isPalindrome(String str, int start, int end)
    {
        while(start < end)
        {
            if(str.charAt(start) != str.charAt(end))
                return false;
            else
            {
                start++;
                end--;
            }
        }
        return true;

    }
 */

6.StringBuffer

String VS StringBuffer:
String类型是不可变的,每次拼接都要重新创建一个对象,再将拼接的结果存入耗费CPU资源。
StringBuffer是一个线程安全的可变字符序列。一个类似String的字符串缓冲区,但是可以修改。

构造方法
1.
public StringBuffer()
StringBuffer s = new StringBuffer();  //capacity默认为16
2.
public StringBuffer(int capacity)  //可以通过自己的预估确定capacity大小,因为扩容所需要消耗的时间还是蛮多的。
3.
public StringBuffer(String str)  //StringBuffer的初始capacity为  16 + str.length()

StringBuffer stringBuffer = new StringBuffer()
int length = stringBuffer.length()  //字符缓冲区中真正包含的字符个数
int capacity = stringBuffer.capacity() // 字符缓冲区本身的大小
添加功能
public StringBuffer append(任意类型 str) // 把其转变为字符串类型,向字符串缓冲区尾部添加字符串
public StringBuffer insert(int offset, 任意类型 str) //在offset位置添加str,而不是在offset前插入。

int i = 10;
stringBuffer.append(i);
System.out.println(stringBuffer.toString());   //10  都是以字符串输出

String s1 = "jiang";
stringBuffer.insert(1,s1);
System.out.println(stringBuffer.toString());   //1jiang0

//链式调用
stringBuffer.insert(1,"haha").append(123).append(false);  //insert,append返回的都是StringBuffer类型对象,且该对象是其本身  return this; 
Other api
删除:
public StringBuffer deleteCharAt(int index)
public StringBuffer delete(int start, int end)  // [start,end)

StringBuffer stringBuffer1 = stringBuffer.deleteCharAt(1); // 删除第二个字符。
                                         .delete(0,10)   //删除第1到第10个字符,下标从0 - 9
替换:
public StringBuffer replace(int start, int end, String str)  [start,end)

StringBuffer s = stringBuffer.replace(0,2,"ahahahah");
反转:
public StringBuffer reverse()  //反转字符缓冲区中的字符序列

StringBuffer s = stringBuffer.reverse();
截取:
public String substring(int start)
public String substring(int start, int end)  //返回一个String,StringBuffer本身不变。 [start,end)

String s = stringBuffer.substring(0,3);
StringBuffer VS StringBuilder

JDK 5开始有了一个单线程使用的等价类 StringBuilder,它在单线程环境下与StringBuffer没有区别。StringBuffer会保障多线程的运行。(待补充)

Date类

构造方法/getTime()
Date date = new Date()
System.out.println(date)   //  Fri Jan 10 16:32:09 CST 2020
Date date = new Date(long date)  //long date参数是从1970年1月1日 00:00:00 GMT 以来到现在,此 Date 对象表示的毫秒数。
//getTime()方法
long time = date.getTime();  // 从1970 年 1 月 1 日 00:00:00 GMT到date所表示时间的经历的毫秒数
//从time中提取对应的year
long year = time / (1000L * 60 * 60 * 24 * 365)  // 求从1970到date是多少年
//用第二种构造方式的好处:
Date date1 = new Date(date.getTime() + (1000L * 60 * 60 * 24 * 2)) //求date后两天的date对象。

DateFormat类

是一个日期/时间 格式化 子类的 抽象类。
一般使用 SimpleDateFormat这个实现子类。

SimpleDateFormat
y 年 
M 月
d 日
H 时
m 分
s 秒
public Date parse(String source)  //parse:解析
public final String format(Date date) // format:格式,版本

SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); //设定你所要的格式
Date date = format.parse("1999/12/21 01:11:20");  //指定格式化为Date的传统格式
System.out.println(date)  //输出传统形式。

Date date = new Date();
String format1 = format.format(date);  //化为指定格式
System.out.println(format1);

Math类

  1. public static int abs(int a) //求绝对值
  2. public static double ceil(double a) // 取整 向大的方向取整
  3. public static double floor(double a)// 取整 向小的方向取
  4. public static int max(int a,int b) min自学
  5. public static double pow(double a,double b) a^b
  6. public static double random() // 返回(带正号)的 double 值,该值大于等于 0.0 且小于 1.0 [0.0 1.0) 随机数。
  7. public static int round(float a) 取整 4舍五入的取整
  8. public static double sqrt(double a) 返回正确舍入的 double 值的正平方根
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值