1.Object
是所有类的根基类
位于java.long包下面的类 不需要import语句
2.方法
1.to string()方法
返回对象的字符串表示类的全路径+"@"+对象hash值
子类中可以重写
public String toString(){
return getClass().getName()+"@"+Integer.toHexString(hashCode());
}
测试类
public static void main(String[] args){
Stu stu= new Stu("tom",12);
System.out.println(stu);//等价与 System.out.println(stu.toString());
//String类对toString放进行了重写
String str = "abc";
System.out.println(str);
}
}
2.equals()方法
- 自反性 x.equals(x)结果为true
- 对称性x.equals(y)结果与y.equals(x)结果一致
- 传递性 x.equals(y)为true 且y.equals(z)也为true那么此时x.equals(z)为true
- 一致性 返回的结果应该始终一致
hashcode 哈希码
- 每个对象都有唯一的hash值 能够唯一代表此对象
- 两个对象equals 那么这两个对象的hash值必须一样,在集合中使用
- 如果要重写equals方法 一定要重写hashcode方法
Stu类重写
public class Stu {
private String name;
private int age;
public Stu(String name, int age) {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
/* @Override
public boolean equals(Object obj) {
Stu op;
if (obj instanceof Stu) {
op = (Stu) obj;
return this.name.equals(op.getName()) && this.age == op.getAge();
}
return false;
}
@Override
public int hashCode() {
return this.name.hashCode() + this.getAge();
}*/
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
public static void main(String[] args) {
Object stu1 = new Stu("tom", 12);
Stu stu2 = new Stu("tom", 12);
System.out.println(stu1.equals(stu2));
System.out.println(stu1 == stu2);
System.out.println(stu1.hashCode());
System.out.println(stu2.hashCode());
System.out.println(stu1 == stu2);
String str1 = new String("abc");
String str2 = new String("abc");
// String重写了equals方法 比较的是字符内容是否相等
System.out.println(str1.equals(str2));
System.out.println(str1 == str2);
}
}
3.hashCode()方法
hash值能够唯一的代表此对象
两个对象equals 那么这两个对象的hash值必须一样,重写equals一定要重写hashcode方法
两个对象不相等hashCode值应该不同
native表示本地方法 方法实现java实现的,而是C/C++来实现的
publi native int hashCode();
4.finalize()方法
当GC开始回收这个对象的时候会自动调用
5.clone()方法
克隆对象
public class ObjectDemo implements Cloneable {
private int num;
// 如果是引用类型,并未对成员变量进行克隆 指向的是同一个对象
private Stu stu;
public static void main(String[] args) {
ObjectDemo objectDemo = new ObjectDemo();
Object clone = null;
try {
objectDemo.num = 10;
objectDemo.stu = new Stu();
clone = objectDemo.clone();
objectDemo.stu.setAge(20);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
System.out.println(((ObjectDemo) clone).num);
System.out.println(((ObjectDemo) clone).stu.getAge());
System.out.println(clone);
System.out.println(objectDemo.hashCode());
System.out.println(clone.hashCode());
System.out.println(clone.equals(objectDemo));
}
}
常用类-Objects类
- 工具类 ,为了优雅的解决使用Object类方法时会出现的空指针问题
- 内部的方法都是静态方法
public static void main(String[] args) {
String str = null;
//1,比较对象是否相等
System.out.println(Objects.equals("", null));
//3, 获取hashcode值
System.out.println(Objects.hashCode(str));
int[] ints1 = {1, 2, 3, 45};
int[] ints2 = {1, 2, 3, 45};
System.out.println("数组相等:" + Objects.equals(ints1, ints2));
// 4,deepEquals()常用来比较数组元素是否一一相等
System.out.println(Objects.deepEquals(ints1, ints2));
// 5, isNull 是否为null 如果为null返回结果时true,否则返回false
boolean isNull = Objects.isNull("");
}
面试题-java中四种引用类型
- 从JDK1.2开始,Java中的引用类型分为四种,分别是:
- ①强引用(StrongReference)
- ②软引用(SoftRefernce)
- ③弱引用(WeakReference)
- ④虚引用(PhantomReference)
Reference,引用表示存放的是另外一块内存的起始地址,引用指向某个对象
不同的引用类型对对象生命周期有影响,GC回收不一致
1,强引用(有用并且必需的)
当内存空间不足时,JVM宁可报错(OOM OutOfMemoryError内存溢出)也不会回收此引用引用着的对象空间(当方法没有执行完的时候)
2,软引用 (SoftRefernce 有用非必需)
当内存空间不足时,GC开始回收此类引用引用着的对象空间;如果空间充足不回收
public static void main(String[] args) {
int _1M = 1024 * 1024;
SoftReference<byte[]> by1 = new SoftReference<>(new byte[_1M * 3]);
System.out.println(by1.get().length);
SoftReference<byte[]> by2 = new SoftReference<>(new byte[_1M * 4]);
System.out.println(by1.get());
}
3,弱引用(WeakReference)(有用非必需)
弱引用引用着的对象活不到下一次GC,
public static void main(String[] args) {
int _1M = 1024 * 1024;
WeakReference<byte[]> by1 = new WeakReference<>(new byte[_1M * 3]);
System.out.println(by1.get().length);
WeakReference<byte[]> by2 = new WeakReference<>(new byte[_1M * 2]);
//通知GC开始回收
System.gc();
System.out.println(by1.get());
System.out.println(by2.get());
}
4,虚引用(PhantomReference)
虚引用主要用来跟踪对象被垃圾回收器回收的活动
2.String类
- 是一个字符串类,是一个不可变的字符串
1.构造方法
String s1 = new String();
String s2 = new String();
char[] chars = {'9','中','c','e'};
String s3 = new String(chars,2,3);
byte[] bytes = {65,66,67,68,97,98,99,100};
String s4 = new String(bytes);//字符的ASCII码值
System.out.println(s4);
2.常见的字符编码
- ASCII每个字符都占用一个字节 128
- ISO-859-1,欧洲用到的字符是远远多于128个的,对ASCII编码进行扩展 两个字节可以存储655536字符
- GBK /GB2312 针对于中文的字符编码 中文汉字一般占用2个字节
- 乱码 字符的编码和解码用的字符编码不一致
- UTF 定义了一套规范 统一全球的编码规范
- UTF-8 中文汉字一般占用3个字节
- UTF-16
3.比较判断方法
length()返回字符串字符序列长度
equals()返回boolean值
equalsIgnoreCase()返回boolean值
startsWith()返回boolean值
endsWith()返回boolean值
4.字符串搜索
indexOf()
lastIndexOf()
返回字符或者字符串出现的索引值
如果找不到 返回值都是-1
String s1 = new String("javasm");
char[] str = {'j','a','v','a'};
String s2 = new String("JAVASM");
int length = s1.length();
// length() 字符串中字符的长度
System.out.println("字符串长度:"+length);
// 1,equals()比较的是字符序列是否一一相等
System.out.println("使用equals进行比较" + flag1);
// 2,equalsIgnoreCase()比较的是字符序列是否一一相等
boolean flag2 = s1.equalsIgnoreCase(s2);
System.out.println("使用equalsIgnoreCase忽略大小写进行比较" + flag2);
// 3,startsWith() 是否以某个字符串开头
boolean flag3 = s1.startsWith("Java", 0);
System.out.println("是否以某个字符串开头" + flag3);
// 4,endsWith()是否已某个字符串结束
boolean flag4 = s2.endsWith("SM");
System.out.println("是否以某个字符串结束" + flag4);
String a= "javaweb";
//5.字符首次出现的索引值
int index = a.indexOf('e');
System.out.println("字符首次出现的索引值:"+index);
//6.字符最后出现索引值
int lastindex = a.lastIndexOf('a');
System.out.println("字符最后出现的索引值:"+lastindex);
//char->int
//字符串首次或者最后出现的索引值
System.out.println(a.indexOf(97));
int strindex = a.indexOf("va");
int strlastindex = a.lastIndexOf("va");
System.out.println("字符串首次出现的索引值"+strindex);
System.out.println("字符串最后出现的索引值"+strlastindex);
5.提取字符串
- char charAt()返回char
- String trim()去除前后空格 中间空格无效
- replace()替换
- replaceAll()替换所有
public static void main(String[] args) {
String s1 = "javasunoracle";//char[] {j,a,v,a}
/* System.out.println(s1.hashCode());
s1 = "sm";
System.out.println(s1.hashCode());*/
// 返回指定的索引对应的字符
char c = s1.charAt(1);// return
System.out.println(c);
String s2 = s1.trim();
System.out.println(s1);
System.out.println("去除前后空格" + s2);
String s3 = s1.replace('a', 'w'); //jwvw
String s4 = s1.replaceAll("av", "wb");
System.out.println(s3);
System.out.println("替换所有" + s4);
System.out.println(s1);// jwvw
// concat 拼接
String s5 = s1.concat("oracle");
System.out.println("拼接 " + s5);
// substring 截取字串
String s6 = s1.substring(4);
// 前闭后开 [)
String s7 = s1.substring(4, 7);
System.out.println(s6);
System.out.println(s7);
// 切分
String[] strs = s1.split("a");
System.out.println(Arrays.toString(strs));
}
// 按指定符号进行拼接字符串
String join = String.join("&", "java", "sun","oa");
System.out.println(join);
6,大小写转换
public static void main(String[] args) {
String s1 = "javaSUNoracle";//char[] {j,a,v,a}
String s2 = s1.toUpperCase();
System.out.println(s2);
String s3 = s1.toLowerCase();
System.out.println(s3);
}
扩展点: **
//可变长参数 传0或者多个都可以 本质上是一个数组来接收
public static String join(CharSequence delimiter, CharSequence... elements) {
Objects.requireNonNull(delimiter);
Objects.requireNonNull(elements);
// Number of elements not likely worth Arrays.stream overhead.
StringJoiner joiner = new StringJoiner(delimiter);
for (CharSequence cs: elements) {
joiner.add(cs);
}
return joiner.toString();
}
7,格式转换
public static void main(String[] args) throws UnsupportedEncodingException {
String s1 = "中国abc";
//1,转字节数组,默认使用UTF-8进行编码解码
byte[] bytes = s1.getBytes("GBK");
System.out.println(Arrays.toString(bytes));
String string = new String(bytes,"GBK");
System.out.println(string);
//2,转字符数组
char[] chars = s1.toCharArray();
System.out.println(Arrays.toString(chars));
}
1.3.字符串常量池
- JVM为了节省内存空间 提高性能 提供了一个字符串常量池
- 在给String引用赋值的时候 会首先查看常量池中是否有此字符序列 如果没有就创建 如果有直接返回内存地址
- 使用+连接字符串的时候 如果都是字符串常量 也是先去常量池中查找;如果+ 旁边有变量 此时生成的字面量会放入一个临时缓冲区中
public static void main(String[] args) {
String s1 = "java";
String s2 = "java";
String s3 = new String("java");
System.out.println(s1 == s2);
System.out.println(s1 == s3);
String s4 = "javasm";
s1 = s1 + "sm";
//s1 = "java" + "sm";
System.out.println(s1 == s4);//true
}
StringBuffer/StringBuilder可变长
1.1. StringBuffer类
StringBuffer是线程安全的,性能较低
StringBuilder线程不安全,性能较高
常用方法
public static void main(String[] args) {
StringBuilder stringBuilder2 = new StringBuilder();
StringBuilder stringBuilder1 = new StringBuilder("ja");
System.out.println(stringBuilder1.hashCode());
//append是追加 在原串后面添加字符串
stringBuilder1.append("va");
stringBuilder1.append("sun");
System.out.println(stringBuilder1);
// 获取长度
System.out.println(stringBuilder1.length());
// 颠倒字符序列 reverse会改动源字符序列
// StringBuilder reverse = stringBuilder1.reverse();
System.out.println("源SB:" + stringBuilder1);
// System.out.println(reverse);
// 索引: [)前开后闭
stringBuilder1.delete(2, 4);
System.out.println("delete :" + stringBuilder1);
//指定索引位 进行插入
stringBuilder1.insert(1, "oracle");
System.out.println("insert:" + stringBuilder1);
}