Object & String & 数组
Object简述
- 这个老祖宗类中的方法我们需要先研究一下,因为这些方法都是所有子类通用的。
- 任何一个类默认继承Object。就算没有直接继承,最终也会间接继承。
object中需要了解的方法
- protected Object clone()// 对象克隆
- int hasCode() //获取对象哈希值
- boolean equals(Object obj) // 判断两个对象是否相等
- String toString() // 将对象转换成字符串的形式
- protected void finalize() //垃圾回收器负责调用的方法
toString()
- 将java对象转换成“字符串”表示方法
- sun公司建议重写toString();
- 输出引用,会自动调用toString()方法
Animal a = new Animal();
`System.out.println(a) //自动调用了toStirng方法```
equals()
- 在java中“”是用来比较基本数据类型的
§ 如果用 == 来判断对象是否相等 会调用toString()方法
§ 比较的是对象的内存地址
- equals() 是用来比较引用数据类型是否相同
- equals()都要重写 idea中生成 alt+ ins
因为在object类中equals()是判断 所以要重写
所有的类都要写equals() 一定要写彻底
finalize() 了解即可
- finalize()只有一个方法体,没有代码 protected修饰
- 不需要手动调用,jvm垃圾回收器负责调用
- finalize() 方法实际上是sun为程序元准备的一个时机类似于静态代码块 (垃圾回收时机)类似遗书
- 例如在开发中有这样的需求所有对象在释放时,请记录回收时间这样的话就可以写在finalize方法里面
- 建议启动垃圾回收器 System.gc(); 只是建议 可能启动,可能不启动
String
概述
- 字符串一旦创建不可变。
- 在java中用双引号引起来的都是String对象
- java中规定,双引号引起来的字符串是不可变的
- 在JDK中,双引号引起来的字符串都是直接储存在方法区字符串常量池
- String s = “abc”;
- 栈中有局部变量,变量保存了内存地址指向方法区中的常量池”abc”(直接指向)
- String s1= new String (“abcdef”)
- 先创建了对象在堆中,堆中有引用指向常量池”abcdef”
- String类已经重新写好了equals()方法,可直接调用
- String 类已经重写好了toString()方法
String的构造方法
- String s = “abc”;
- String s = new String(“abc”);
- String s = new String(byte数组);
- String s = new String(byte数组,起始下标, 长度);
- String s = new String(char数组);
- String s = new String(char数组,起始下标, 长度);
String常用方法
- compareTo() 判断字符串大小
- contains() //判断是否包含
- endsWith() 判断是否以它结尾
- equalsIgnoreCase() 判断相等不相等 忽略大小写
- getByte() 将字符串转换成Byte数组 (ascll码)
- indexOf() 返回该字符出现在字符串中的第一次索引
- replace() 替换
- split() 拆分字符串,返回String数组
- startsWith() 判断字符串是否以该字符开始
- toLowerCase() 转换小写
- toUpperCase() 转换大写
- trim() 去前后空格
StringBuffer/StringBuilder
String Buffer 是线程安全的
synchronized 同步
String builder 非线程安全的
使用局部变量是用非线程安全的(因为不存在线程安全问题)
连接字符串,初始化16个字符, append()添加
频繁进行字符串拼接不建议使用“+”
数组
基本概念
- java中的数组属于引用数据类型(数组的父类是Object)
- 数组是一个容器,可以容纳多个元素
- 可储存的元素
- 基本数据类型的数据
- 引用数据类型的数据
- 数组存储在堆内存中
- 数组中如果存储的是java对象,实际上是存储的对象的引用
- 所有的数组都有length属性,用来获取数组中元素的个数
- java中的数组要求数组中的元素类型统一
- 例如: int数组只能存储int类型元素
- 数组在内存方面存储的时候数组中的元素内存地址是连续的
- 所有数组都是拿着首元素的内存地址当作整个数组的内存地址
- 数组中的下标从0开始,以1递增 最后一个 length-1
创建数组
- 静态初始化
语法:int[] array = {1,2,3,4,5,6};
- 动态初始化
语法:int[] array = new int[5];// 这里面的5代表的是元素个数
初始化5个元素的一维数组int类型,默认值为0;
- 创建数组时 ,如果知道数组的值 直接静态初始化,否则动态初始化
- 在java中创建数组可以以c++的方式写
int[] a = {};
java风格int a[] = {};
c++风格
读和改
- 所有的数组都有length属性
- 读
**数组名[下标]**
- 数组名[a.length-1] //访问最后一个元素
- 改
**a[下标] = 值;**
- Object数组
- Object数组什么样的数据都可以储存,万能的口袋
优缺点
优点
检索效率高
- 每一个元素的内存地址在空间存储上是连续的
- 每一个元素类型相同,所占用的空间大小一样
- 知道一个元素的内存地址,知道每一个元素占用空间的大小,又知道下标,所以通过一个数学表达式,就可以计算出某个下标元素的地址,直接通过地址定位,所以检索效率是最高的
缺点
- 由于为了保证内存地址的连续,增删改效率较低
- 因为在增删改时,后面的元素都要向前或者向后位移
- 数组不能储存大数据量
- 很难在堆内存中找到一块特别大的且连续的内存空间
- 对于数组中最后一个元素的增删改是没有任何效率影响的
深入一维数组
- 对于数组来说:实际上只能存储java对象的内存地址
- 数组存入的元素是引用
- 父类型的数组是可以储存子类型对象的
例如:Animal[] animals ={ new Cat(), new Dog()}
有继承关系
数组的扩容
- 在java中数组一旦长度确定不可以改变,满了就需要扩容
- 先创建一个大容量的数组,将小容量的数组拷贝到大容量数组中
数组拷贝: System.arraycopy(五个参数);
拷贝源 2.源的起点 3. 目标 4.目标的起点 5.要烤多长
Arrays工具类的使用
- java.util.Arrays; 包下
- 排序 Arrays.sort(数组)
- 二分法查找 Arrays.binarySearch(数组,要查找的值)
二维数组
- 二维数组是特殊的一维数组
- 特殊在这个一维数组中没一个元素都是一维数组
创建二维数组
静态初始化:
int[][] a = {
{ }
{ }
};
动态初识化:
int[][] a1 = new int [3][4];"
//表示三行四列 三个一维数组,每个一维数组里面有4个元素
二维数组的length属性
**a.length**
是二维数组中有几个一维数组**a[0].length**
是二维数组中下标为0的以为数组中有几个元素
二维数组的读和改
读
**数组名[1][1];**
表示第二个一维数组中第二个元素
改
**数组名[下标][下标] = 值;**
二维数组的遍历
//二维数组的遍历
int[][] arr={
{1,2,3},
{2,3,4},
{3,4,5}
};
for(int i = 0; i < arr.length;i++){
for(int j = i; j < arr[i].length;j++){
System.out.println(arr[i][j]);
}
}
冒泡排序
int[] arr2 = {6,5,4,3,2,1};
//冒泡排序
for(int i = arr2.length - 1;i > 0; i--){
for(int j = 0;j < i;j++){
if(arr2[j] > arr2[j+1]){
int temp;
temp = arr2[j];
arr2[j] = arr2[j+1];
arr2[j+1] = temp;
}
}
}
for(int i : arr2){
System.out.print(i);
}