常见对象
Object类
API概述以及object类的概述
-
API(Application Programming Interface)
应用程序编程接口
-
Java API
就是java提供给我们使用的类,这些类将底层的实现封装了起来
-
object类概述
类层次结构的根类
所有类都直接或者间接的继承自该类
-
构造方法
public Object()
子类的构造方法默认访问的是父类的无参构造
object类的hashCoad()方法
-
public int hashCoad()
返回该对象的哈希码值。默认情况下,该方法会根据对象的地址来计算
不同对象的hashCoad()一般来说不会相同;但是同一个对象的hashCoad()值肯定相同
不是对象的实际地址值,可以理解为逻辑地址值
public class MyTest {
public static void main(String[] args) {
// 类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。
//Object 是所有类的顶层父类,所有的类,都是直接 或间接继承自他
Object x = new Object();
int i = x.hashCode();
Object y = new Object();
int j = y.hashCode();
System.out.println(i);
System.out.println(j);
//不同对象的哈希码值是不一样
}
}
object类的getClass()方法
-
public final Class getClass()
返回此object的运行时类
可以通过class类中的一个方法,获取对象的真实类的全名称
public String getName()
public class MyTest {
public static void main(String[] args) {
//getClass() 获取该类的字节码文件对象。
//Object.java--->Object.class---->当Object.class这个字节码文件加载的时候,JVM 就会为字节码文件来创建对象。
//这个字节码文件对象,用Class 类型来描述。
Object obj1 = new Object();
Object obj2 = new Object();
//获取地址值
System.out.println(obj1);
System.out.println(obj2);
//不同对象的地址值不同
System.out.println(obj1 == obj2);//false
//获取object.class这个字节码文件对象
Class<?> aClass1 = obj1.getClass();
//获取字节码文件对象的真实类的全名称
System.out.println(aClass1);
Class<?> aClass2 = obj2.getClass();
//.class字节码文件对象相同
System.out.println(aClass1 == aClass2);//true
}
}
object类的toString()方法
-
public String toString()
返回该对象的字符串表示
-
源代码:
public String toString(){
return getClass().getName()+“@”+Integer.toHexString(hashCoad());
}
它的值等于:
getClass().getName() + ‘@’ + Integer.toHexString(hashCode())
由于默认情况下的数据对我们来说没有意义,一般建议重写该方法,重写一般是将该类的所有成员变量组成返回即可
-
public class MyTest {
public static void main(String[] args) {
//toString() 获取该对象的地址值,以字符串形式返回
Object obj = new Object();
String s = obj.toString();
System.out.println(s);
//当你打印一个对象名的时候,默认在调用object类中的toString()
System.out.println(obj);
System.out.println(obj.toString());
//类中没有重写toString()方法时打印的是地址值,但是打印地址值没有意义,而打印成员变量更有意义
//当输出一个对象名(默认带 .toString),输出的不是地址值,说明该类重写了父类Object中的toString()
}
}
//IDEA中,按alt+insert,自动重写toString方法
object类的equals()方法
-
指示其他某个对象是否与次对象“相等”
源代码:
public boolean equals(Object obj){
return(this==obj);
}
-
默认情况下比较的是对象的引用是否相同
-
由于比较对象的引用没有意义,一般建议重写该方法,用于比较成员变量的值是否相等
import java.util.Objects;
public class MyTest {
public static void main(String[] args) {
Object obj1 = new Object();
Object obj2 = new Object();
//默认比较地址值
System.out.println(obj1.equals(obj2));//false
Student s1 = new Student("鹿秀儿",22);
Student s2 = new Student("鹿秀儿", 22);
//==比较地址值
System.out.println(s1 == s2);//false
//student重写了equals()方法,比较成员变量
System.out.println(s1.equals(s2));//true
}
}
class Student{
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = 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;
}
//重写equals()方法
@Override
public boolean equals(Object o) {
//比较地址值是否相同
if (this == o) return true;
//判断是不是该类型的引用
if (o == null || getClass() != o.getClass()) return false;
//向下转型
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
}
/* ==和equals()方法的区别
==是一个比较运算符,既可以比较基本数据类型,也可以比较引用数据类型
==比较基本数据类型比的是两个值是否相等,比较引用数据类型比的是两个对象地址值是否相同
equals()是object类中的方法,只能比较引用类型,默认比较的是两个地址值是否相同
*/
object类的equals()方法代码优化
-
object类的equals()方法代码优化
提高效率
提高健壮性
@Override
public boolean equals(Object o) {
//比较地址值是否相同--效率
if (this == o) return true;
//判断是不是该类型的引用
if (o == null || getClass() != o.getClass()) return false;
//向下转型
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
object类的clone()方法
- clone()的权限修饰符是受保护的,在用的时候,让该类重写该方法,并把该方法的权限修饰符改为public
- 对象的克隆:浅克隆和深克隆
- 使用clone()方法采用的是浅克隆的方式
对象浅克隆要注意的细节
- 如果一个对象需要调用clone的方法克隆,那么该对象所属的类必须要实现Cloneable接口
- Cloneable接口只不过是一个标识接口而已,没有任何方法。
- 对象的浅克隆就是克隆一个对象的时候,如果被克隆的对象中维护了另外一个类的对象,这时候只是克隆另外一个对象的地址,而没有把另外一个对象也克隆一份。
- 对象的浅克隆也不会调用到构造方法的。
对象的深克隆:采用IO流来实现 使用 ObjectOutputStream 将对象写入文件中,然后再用ObjectInputStream读取回来
public class MyTest {
public static void main(String[] args) throws CloneNotSupportedException {
DogFather dogFather = new DogFather("狗王");
Dog dog1 = new Dog("旺旺", 2,dogFather);
System.out.println(dog1.name);//旺旺
System.out.println(dog1.age);//2
System.out.println(dog1.dogFather.name);//狗王
//克隆操作,如果克隆中有被引用的,那么克隆的就是引用的地址值
Dog dog2 = (Dog) dog1.clone();
dog2.name="哈哈";
dog2.dogFather.name="狗爹";
System.out.println(dog2.name);//哈哈
System.out.println(dog1.name);//旺旺
System.out.println(dog1.dogFather.name);//狗爹
System.out.println(dog2.dogFather.name);//狗爹
}
//一个接口中,没有任何的抽象方法,这种接口我们称之为标记接口。目的就是给类打一个标记,让虚拟机支持克隆操作。
}
class Dog implements Cloneable{
String name;
int age;
DogFather dogFather;
public Dog(String name, int age, DogFather dogFather) {
this.name = name;
this.age = age;
this.dogFather = dogFather;
}
//ctrl+o 重写方法
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class DogFather{
String name;
public DogFather(String name) {
this.name = name;
}
}
/* 对象的浅克隆:就是克隆一个对象的时候,如果被克隆的对象中维护了另外一个类的对象,
这时候只是克隆另外一个对象的地址,
而没有把 另外一个对象也克隆一份。
*/
Scanner类
scanner的概述和构造方法原理
-
scanner的概述:JDK5以后用于获取用户的键盘输入
-
scanner的构造方法原理
Scanner(InputStream source)
System类下有一个静态的字段:
public static final InputStream in; 标准的输入流,对应着键盘录入
scanner类的hasNetXxx()和nextXxx()方法的讲解
-
基本格式
hasNextXxx() 判断下一个是否是某种类型的元素,其中Xxx可以是Int,Double等
如果需要判断是否包含下一个字符串,则可以省略Xxx
nextXxx() 获取下一个输入项,Xxx的含义和hasNextXxx()的Xxx相同
public class MyTest {
public static void main(String[] args) {
/* Scanner(InputStream source)
构造一个新的 Scanner,它生成的值是从指定的输入流扫描的。*/
//in
//public static final InputStream in“标准”输入流。此流已打开并准备提供输入数据。通常,此流对应于键盘输入或者由主机环境或用户指定的另一个输入源。
InputStream in= System.in;
Scanner sc = new Scanner(in);
//nextXXX 系列的方法
/*sc.nextInt();
sc.nextDouble();
sc.nextLine();*/
/* hasNextXxx() 判断下一个是否是某种类型的元素, 其中Xxx可以是Int, Double等。
如果需要判断是否包含下一个字符串,则可以省略Xxx*/
System.out.println("请输入一个整数");
if(sc.hasNextInt()){
int i = sc.nextInt();
}else{
System.out.println("你输入的类型不正确,请重新输入");
}
//关闭扫描器
sc.close();
}
}
scanner获取数据出现的小问题及解决方案
两个常用方法
- public int nextInt():获取一个int类型的值
- public String nextLine():获取一个String类型的值
- public String next():获取一个String类型的值
public class MyTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个整数");
int i = sc.nextInt();
System.out.println(i);
System.out.println("请输入一个字符串");
//当你先录入整数,然后使用nextLine();录入字符串时,会发现字符串没让你录入,原因就是你上次敲了个回车换行默认被nextLine()录入了,
//但是这不是我想要的效果,那怎么解决。
//解决方式1:可以在录入字符字符串时,在创建一个Scanner对象。
//解决方式2:可以使用next() 来录入字符串
sc = new Scanner(System.in);
String s = sc.nextLine();
//String s = sc.next();
System.out.println(s);
}
}
public class MyTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串");
String s = sc.nextLine();
//next() 你输入的字符串中有空格,那么他在录入时,遇到第一个空格后面的内容,不会录入进来
//String s = sc.next();
System.out.println(s);
}
}
String类
string类的概述
-
什么是字符串
字符串是由多个字符组成的一串数据(字符序列)
字符串可以看成是字符数组,每一个字符从左往右编有索引,从0开始
-
string类的概述
通过JDK提供的API,查看string类的说明
可以看到这样的两句话
- 字符串字面值“abc”也可以看成是一个字符串对象
- 字符串是常量,一旦被创建,就不能被改变
string类的构造方法
常见构造方法
- public String():空构造
public class MyTest {
public static void main(String[] args) {
// String() 初始化一个新创建的 String 对象,使其表示一个空字符序列
String s = new String();
//String 类他重写了父类的toString方法,打印的是字符串字面值
System.out.println(s);
//"" 空串
System.out.println("");
}
}
//intern()取这个字符串在常量池的地址值
- public String(byte[ ] bytes):把字节数组转成字符串
public class MyTest {
public static void main(String[] args) {
// public String( byte[] bytes):把字节数组转成字符串
byte[] bytes = {97, 98, 99, 100, -28, -67, -96};
String s = new String(bytes);
System.out.println(s);//abcd你
}
}
- public String(byte[ ] bytes,int offset,int length):把字节数组的一部分转成字符串(offset表示的是从第几个索引开始, length表示的是长度)
public class MyTest {
public static void main(String[] args) {
//把字节数组的一部分转换成字节 0 起始索引 3表示转换3个字节
byte[] bytes = {97, 98, 99, 100, -28, -67, -96};
String s = new String(bytes, 0, 3);
System.out.println(s);//abc
}
}
// StringIndexOutOfBoundsException 字符串索引越界
- public String(char[ ] value):把字符数组转成字符串
public class MyTest {
public static void main(String[] args) {
//把一个字符数组转换成字符串
char[] chars={'a','b','c','d','你','好'};
String s = new String(chars);
System.out.println(s);
}
}
- public String(char[ ] value,int offset,int count):把字符数组的一部分转成字符串
public class MyTest {
public static void main(String[] args) {
//把字符数组的一部分转换成字符串,4 表示起始索引 2 转换2个字符
char[] chars={'a','b','c','d','你','好'};
String s = new String(chars, 4, 2);
System.out.println(s);//你好
}
}
- public String(String original):把字符串常量值转成字符串
public class MyTest {
public static void main(String[] args) {
//把字符串常量值转成字符串
//定义一个字符串常量
String t = "aabbccdd";
String s = new String(t);
System.out.println(s);//aabbccdd
}
}
- public int length():返回此字符串的长度
public class MyTest {
public static void main(String[] args) {
//返回此字符串的长度
String s="abcdefgh";
int l = s.length();
System.out.println(l);//8
}
}
string的特点一旦被创建就不能改变
- String的特点:一旦被创建就不能改变,因为字符串的值是在堆内存的常量池中划分空间,分配地址值的
public class MyTest {
public static void main(String[] args) {
String s="hello";
s="world"+"java";
System.out.println(s);
}
}
string常见题目
- String s = new String(“hello”);和String s = “hello”;的区别
- 看程序写结果
string类的判断功能
判断功能
- public boolean equals(Object obj):比较字符串的内容是否相同,区分大小写
public class MyTest2 {
public static void main(String[] args) {
//比较字符串的内容是否相同,区分大小写
//String 类 已经重写过了父类的equals方法不再比较地址值是否相同,而是比较两个字符串的字面内容是否相同
String s1 = new String("Hello,world");
String s2 = new String("hello,world");
String s3 = new String("Hello,world");
String s4="hello,world";
System.out.println(s1.equals(s2));//false
System.out.println(s1.equals(s3));//true
System.out.println(s2.equals(s4));//true
}
}
- public boolean equalsIgnoreCase(String str):比较字符串的内容是否相同,忽略大小写
public class MyTest {
public static void main(String[] args) {
//比较字符串的内容是否相同,忽略大小写
String s1 = new String("Hello,world");
String s2 = new String("hello,world");
String s3 = new String("Hello,world");
String s4="hello,world";
System.out.println(s1.equalsIgnoreCase(s2));
System.out.println(s1.equalsIgnoreCase(s3));
System.out.println(s2.equalsIgnoreCase(s4));
}
}
- public boolean contains(String str):判断字符串中是否包含传递进来的字符串
public class MyTest {
public static void main(String[] args) {
//判断字符串中是否包含传递进来的字符串
String s1 = new String("Hello");
String s2 = new String("Hello,world");
System.out.println(s1.contains(s2));//false
System.out.println(s2.contains(s1));//true
}
}
- public boolean startsWith(String str):判断字符串是否以传递进来的字符串开头
public class MyTest {
public static void main(String[] args) {
//判断字符串是否以传递进来的字符串开头
String s1 = new String("Hello");
String s2 = new String("Hello,world");
System.out.println(s2.startsWith(s1));//true
}
}
- public boolean endsWith(String str):判断字符串是否以传递进来的字符串结尾
public class MyTest {
public static void main(String[] args) {
//判断字符串是否以传递进来的字符串结尾
String s1 = new String("world");
String s2 = new String("Hello,world");
System.out.println(s2.endsWith(s1));//true
}
}
- public boolean isEmpty():判断字符串的内容是否为空串""
public class MyTest {
public static void main(String[] args) {
//判断字符串的内容是否为空串""
String s1 = new String("");
String s2 = new String("Hello,world");
System.out.println(s1.isEmpty());//true
System.out.println(s2.isEmpty());//false
}
}
模拟用户登录
import java.util.Scanner;
public class MyTest {
public static void main(String[] args) {
//输入正确的账号密码
String name="luxiuer";
String password="666666";
Scanner sc = new Scanner(System.in);
//用来限定输入次数
for (int i = 3; i > 0; i--) {
System.out.println("请输入账号");
String x = sc.nextLine();
//3次机会均不正确就结束循环
if(i==1){
System.out.println("您的银行卡已成功锁定");
break;
//比较输入对象与正确账号的字面值是否相同,相同就可以进入输入密码步骤
}else if(name.equals(x)){
System.out.println("请输入密码");
String y = sc.nextLine();
//比较输入对象与正确密码的字面值是否相同
if(password.equals(y)){
System.out.println("账号密码正确,当前余额0.00元");
break;
}else{
System.out.println("密码错误,还剩余"+(i-1)+"次");
continue;
}
}else{
System.out.println("账号错误还剩余"+(i-1)+"次");
}
}
}
}
string类的获取功能
- public int length():获取字符串的长度
public class MyTest {
public static void main(String[] args) {
//获取字符串的长度
String s="abcdefghijk";
System.out.println(s.length());//11
}
}
- public char charAt(int index):获取指定索引位置的字符
public class MyTest {
public static void main(String[] args) {
//获取指定索引位置的字符
String s="abcdefghijk";
System.out.println(s.charAt(4));//e
}
}
- public int indexOf(int ch):返回指定字符在此字符串中第一次出现处的索引
public class MyTest {
public static void main(String[] args) {
//返回指定字符在此字符串中第一次出现处的索引
String s="abcdefghijk";
System.out.println(s.indexOf('d'));//3
}
}
- public int indexOf(String str):返回指定字符串在此字符串中第一次出现处的索引
public class MyTest {
public static void main(String[] args) {
//返回指定字符串在此字符串中第一次出现处的索引
String s="abcdefghijk";
System.out.println(s.indexOf("efg"));//4
}
}
- public int indexOf(int ch,int fromIndex):返回指定字符在此字符串中从指定位置后第一次出现处的索引
public class MyTest {
public static void main(String[] args) {
//返回指定字符在此字符串中从指定位置后第一次出现处的索引
String s="abcdeabcde";
System.out.println(s.indexOf('b', 2));//6
}
}
- public int indexOf(String str,int fromIndex): 返回指定字符串在此字符串中从指定位置后第一次出现处的索引
public class MyTest {
public static void main(String[] args) {
//返回指定字符串在此字符串中从指定位置后第一次出现处的索引
String s="abcdeabcde";
System.out.println(s.indexOf("ab", 2));//5
}
}
- public String substring(int start):从指定位置开始截取字符串,默认到末尾
public class MyTest {
public static void main(String[] args) {
//从指定位置开始截取字符串,默认到末尾
String s="abcdeabcde";
System.out.println(s.substring(2));//cdeabcde
}
}
- public String substring(int start,int end):从指定位置开始到指定位置结束截取字符串
public class MyTest {
public static void main(String[] args) {
//从指定位置开始到指定位置结束截取字符串(带头不带尾)
String s="abcdeabcde";
System.out.println(s.substring(2,5));//cde
}
}
字符串的遍历
- 正向遍历
public class MyTest {
public static void main(String[] args) {
//正向遍历字符串
String l="鹿秀儿";
for (int i = 0; i < l.length(); i++) {
//charAt根据索引提取字符
char c = l.charAt(i);
System.out.println(c);
}
}
}
- 反向遍历
public class MyTest {
public static void main(String[] args) {
//反向遍历字符串
String l = "鹿秀儿";
for (int i = l.length() - 1; i >= 0; i--) {
char c = l.charAt(i);
System.out.println(c);
}
}
}
统计不同类型字符个数
public class MyTest {
public static void main(String[] args) {
String str="asdfASFAEZSf5244dsfsdf555asdfa36425444asdfasdf";
int xiao=0;
int da=0;
int num=0;
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if(c>='a'&&c<='z'){
xiao++;
}else if(c>='A'&&c<='Z'){
da++;
}else{
num++;
}
}
System.out.println("大写字母有" + da + "个");
System.out.println("小写字母有" + xiao + "个");
System.out.println("数字有" + num + "个");
}
}
string类的转换功能
- public byte[ ] getBytes():把字符串转换为字节数组
public class MyTest {
public static void main(String[] args) {
//把字符串转换为字节数组
String s="abcde";
byte[] bytes = s.getBytes();
for (int i = 0; i < bytes.length; i++) {
System.out.println(bytes[i]);
}
}
}
- public char[ ] toCharArray():把字符串转换为字符数组
public class MyTest {
public static void main(String[] args) {
//把字符串转换为字符数组
String s="abcde";
char[] chars = s.toCharArray();
System.out.println(chars);//abcde
}
}
- public static String valueOf(char[ ] chs):把字符数组转成字符串
public class MyTest {
public static void main(String[] args) {
//把字符数组转成字符串
char[] chars={'a','b','c','d','e'};
System.out.println(String.valueOf(chars));//abcde
}
}
- public static String valueOf(int i):把int类型的数据转成字符串
public class MyTest {
public static void main(String[] args) {
//把int类型的数据转成字符串
int s=12345678;
System.out.println(String.valueOf(s));//12345678
}
}
//String类的valueOf方法可以把任意类型的数据转成字符串
- public String toLowerCase():把字符串转成小写
public class MyTest {
public static void main(String[] args) {
//把字符串转成小写
String s="AaBbCcDdEe";
System.out.println(s.toLowerCase());//aabbccddee
}
}
- public String toUpperCase():把字符串转成大写
public class MyTest {
public static void main(String[] args) {
//把字符串转成大写
String s="AaBbCcDdEe";
System.out.println(s.toUpperCase());//AABBCCDDEE
}
}
- public String concat(String str):把字符串拼接
public class MyTest {
public static void main(String[] args) {
//把字符串拼接
String s="Aa";
System.out.println(s.concat("Bb").concat("Cc"));//AaBbCc
}
}
按要求转换字符
public class MyTest {
public static void main(String[] args) {
//把一个字符串的首字母转成大写,其余为小写
String s="AaBbCcDd";
System.out.println(s.substring(0, 1).toUpperCase().concat(s.substring(1).toLowerCase()));//Aabbccdd
}
}
string类的其他功能
String的替换功能
- public String replace(char old,char new):将指定字符进行互换
public class MyTest {
public static void main(String[] args) {
//将指定字符进行互换
String s="AaBbhahaCcDd";
System.out.println(s.replace('a', 't'));//AtBbhthtCcDd
}
}
- public String replace(String old,String new):将指定字符串进行互换
public class MyTest {
public static void main(String[] args) {
//将指定字符串进行互换
String s="AaBbhahaCcDd";
System.out.println(s.replace("haha", "hehe"));//AaBbheheCcDd
}
}
String的去除字符串空格
- public String trim():去除两端空格
public class MyTest {
public static void main(String[] args) {
//去除两端空格
String s=" hello ";
System.out.println(s);//两端有空格
System.out.println(s.trim());//两端无空格
}
}
String的按字典顺序比较两个字符串
-
public int compareTo(String str)
会对照ASCII 码表 从第一个字母进行减法运算,返回的就是这个减法的结果
如果前面几个字母一样会根据两个字符串的长度进行减法运算,返回的就是这个减法的结果
如果字符串一模一样,返回的就是0
public class MyTest {
public static void main(String[] args) {
int i="abc".compareTo("abcd");
System.out.println(i);
}
}
-
public int compareToIgnoreCase(String str)
跟上面一样 只是忽略大小写的比较
public class MyTest {
public static void main(String[] args) {
int j="abc".compareToIgnoreCase("ABC");
System.out.println(j);
}
}
把数组转成字符串
public class MyTest {
public static void main(String[] args) {
//把数组中的数据按照指定个格式拼接成一个字符串
int[] arr={1,2,3,4,5};
String num="[";
for (int i = 0; i < arr.length; i++) {
if(i==arr.length-1){
num+=arr[i]+"]";
}else{
num+=arr[i]+",";
}
}
System.out.println(num);
}
}
字符串反转并断点查看
import java.util.Scanner;
public class MyTest {
public static void main(String[] args) {
//把字符串反转
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串");
String s = sc.nextLine();
String j = "";
for (int i = s.length() - 1; i >= 0; i--) {
j += s.charAt(i);
}
System.out.println(j);
}
}
在大串中查找小串出现的次数
public class MyTest {
public static void main(String[] args) {
//在大串中查找小串出现的次数
String s="woaijavawozhenaijavawozhendeaijavawozhendehenaijavaxinbuxinwoaijavagun";
//先给小串替换了
String t = s.replace("java", "*");
int num=0;
for (int i = 0; i < t.length() - 1; i++) {
if(t.charAt(i)=='*'){
num++;
}
}
System.out.println("java出现了" + num + "次");
}
}
完