Day13
eclipse的目录认识
Object类
public int hashCode( )
public int hashCode()返回该对象的哈希码值。(哈希表中提供一种算法)
-
可以理解为地址值(不是实际意义的地址值)Hashtable (java.util)
-
返回值是整数类型
-
输出一个对象名称—>地址值 (类名@十六进制数据)
//创建学生对象
Student s = new Student() ;
System.out.println(s.hashCode());//1829164700 哈希码值
Student s2 = new Student() ;
System.out.println(s2.hashCode());//2018699554
Student s3 = new Student() ;
System.out.println(s3.hashCode());//13110531351
public final Class getClass( )
public final Class getClass() : 通过这个方法获取当前类的字节码文件对象
- 返回此 当前类的运行时类(跟反射有关系)
- Class类下面有一个方法:
- public String getName( )以 String 的形式返回此 Class 对象所表示的实体名称
Student s4 = new Student() ;
Class c = s4.getClass() ;
System.out.println(c);//class com.qianfeng.object_study.Student
//public String getName()
String str = c.getName() ;//获取当前字节码文件对象的全路径名称(包名.类名)
System.out.println(str);//com.qianfeng.object_study.Student
public String toString( )
返回该对象的字符串表示
- 建议所有子类重写该方法(自动生成 alt+shift+s–>s)
- 总结:为了防止输出对象名称,得到地址值---->重写Object类中的toString()方法,获取的是对象中的成员信息
//重写toString()方法
//自动生成
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
//测试类
public class StudentDemo {
public static void main(String[] args) {
//创建学生对象
Student s = new Student() ;
//默认输出对象名称 ---->实际底层执行的Object中的toString()
//输出对象名称--->得到地址值没有意义(看到当前对象的成员)
//System.out.println(s);//com.qianfeng.object_study_02.Student@6d06d69c
/*
* Integer
* public static String toHexString(int i):
* toString()等价于
*
* 某个对象.getClass().getName() + @ + Integer.toHexString(某个对象.hashCode()) ;
*
* * */
//System.out.println(s);
//重写toString方法之后,获取的是对象中的成员信息
Student s2 = new Student("高圆圆",39) ;
Student s3 = new Student("高圆圆",39) ;
System.out.println(s2==s3);
System.out.println("-----------------");
String str = s.getClass().getName()+"@"+Integer.toHexString(s.hashCode()) ;
System.out.println(str);
/*
* 通过观察:toString()的源码
* public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
* */
}
}
public boolean equals(Object obj)
public boolean equals(Object obj)指示其他某个对象是否与此对象“相等”。
- 形式参数是Object类型,需要传递的是该类对象(Object表示任意类)
- equals底层默认的比较是两个对象的地址值是否相同!
逻辑:
* 两个对象:
* 1)比较s1和s2是否属于同一个类型
* 2)s1里面中的name和s2的name比较,如果不一致,返回false
* 3)比较年龄是否相同,如果不一致,返回false
* ...
* 如果比较两个对象是否"相同",重写equasl方法,因为比较对象地址值没意义.
* 重写equals方法,比较两个对象的之间的内容是否相同 (自动生成equals方法)
*
* == :
* 基本类型:比较的是数值是否相同
* 引用类型:比较的是地址值是否相同
* */
public class StudentDemo {
public static void main(String[] args) {
//Student s1 = new Student("高圆圆",39);
//System.out.println(s1);
//Student s2 = new Student("高圆圆",39);
Student s1 = new Student("高圆圆",39,"9527") ;
Student s2 = new Student("高圆圆",39,"9527") ;
System.out.println(s1==s2); //false 比较两个对象的地址值没意义的!
Student s3 = s1 ;
System.out.println(s3==s1);//true
/*equals
* 源码
* public boolean equals(Object obj) {
return (this == obj);
}
* */
//System.out.println("重写之前:"+(s1.equals(s2))) ;//false
System.out.println("重写之后:"+(s1.equals(s2))) ;//true
System.out.println("---------------------------");
//Demo s4 = new Demo();
//System.out.println(s1.equals(s4));//类型不一致,不能比较(false)
}
}
class Demo{}
protected void fifinalize()
protected void finalize() throws Throwable(异常类:范围最大的)
- 当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法
- 什么时候回收不用的对象或者一些变量,在GC空闲时回收…(System类使用)
public class StudentDemo {
public static void main(String[] args) throws CloneNotSupportedException {
Student s = new Student();
//s = null ; //将对象的引用赋值为null
//new Student() ; //匿名对象
//setXXX()赋值
s.setName("张三");
s.setAge(28);
s.setId("007");
//张三---28---007
System.out.println(s.getName()+"---"+s.getAge()+"---"+s.getId());
//当前对象的类实现了cloneable接口就可以使用clone()方法
Object obj = s.clone() ;
Student s2 = (Student)obj;
//张三---28---007
System.out.println(s2.getName()+"---"+s2.getAge()+"---"+s2.getId());
System.out.println("----------------------");
Student s3 = s;
System.out.println(s3.getName()+"---"+s3.getAge());
s3.setName("高圆圆");
s3.setAge(38);
s3.setId("008");
System.out.println(s.getName()+"---"+s.getAge()+"---"+s.getId());
System.out.println(s3.getName()+"---"+s3.getAge()+"---"+s3.getId());
System.out.println(s2.getName()+"---"+s2.getAge()+"---"+s2.getId());
}
}
protected Object clone()
建并返回此对象的一个副本 (复制该对象中的字段)
throws CloneNotSupportedException (浅克隆)
注意:
如果此对象的类不能实现接口 Cloneable,则会抛出 CloneNotSupportedException
Cloneable接口没有成员变量,没有构造方法,没有成员方法,----->标记接口(通用:大部分类自动实现)
//学生类
//要使用clone()方法,必须实现一个接口Cloneable
public class Student extends Object implements Cloneable{
private String name ;
private int age ;
private String id;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age, String id) {
super();
this.name = name;
this.age = age;
this.id = id;
}
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;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
/*
* 重写clone()方法
* */
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
Scanner
一个可以使用正则表达式来解析基本类型和字符串的简单文本扫描器。
创建Scanner对象:
- Scanner sc = new Scanner(System.in) ;
构造方法:
public Scanner(InputStream source)
构造一个新的 Scanner,它生成的值是从指定的输入流扫描的
- 成员方法:
判断功能:
public boolean hasNextXXX() :
针对录入数据之前进行判断,判断下一个录入的数据是否是该xxx类型
获取功能:
public xxx nextXXX()
获取键盘录入的xxx数据
正则表达式:[a-zA-Z0-9]
- qq:不能数字开头,并且9位
- 用户名:有数字或者字母组成.
密码:符合6-16位的数字或者字母
确认密码:密码一致
数字@字母.com
919081924 @ qq.com
数字或字母@字母.com.cn(…)
public class ScannerDemo {
public static void main(String[] args) {
//InputStream in = System.in ; //抽象类多态
//使用Scanner构造方法传递参数
Scanner sc = new Scanner(System.in ) ;
/*
* java.util.InputMismatchException
* 输入的数据类型和接收的数据类型不匹配
* 如何解决?
* */
//加入判断
if(sc.hasNextInt()) {//判断下一个录入的是否是int类型的数据
int a = sc.nextInt() ;
System.out.println(a);
}else {
//提示
System.out.println("您输入的数据和当前类型不匹配");
}
}
}
public class ScannerDemo2 {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in) ;
//录入两个int类型
/*
* int a = sc.nextInt() ; int b = sc.nextInt() ;
* System.out.println("a:"+a+",b:"+b);
*/
/*
* String s1 = sc.nextLine() ; String s2 = sc.nextLine() ;
* System.out.println("s1:"+s1+",s2:"+s2);
*/
//先录入字符串,在录入int
/*
* String s = sc.nextLine() ; //windows /r/n int a = sc.nextInt() ;
* System.out.println("s:"+s+",a:"+a);
*/
//先录入int,在录入字符串
int a = sc.nextInt() ; // /r/n
//创建键盘录入对象
//Scanner sc2 = new Scanner(System.in) ;
String s = sc.nextLine() ;
//String s = sc2.nextLine() ;
System.out.println("a:"+a+",s:"+s);
//细节:
/*
* 先录入int,在录入字符串出现字符串数据没有接收,存在windows自带换号符号 /r/n,将换号符号当做字符串录入
* 怎么解决方案?
* 1)在录入字符串前,创建键盘录入对象
* 2) io流的时候,BufferedReader :流的方式键盘录入
* readLine() ;
* 3)全部都是用String接收,
* String--Integer-->int
* */
}
}
String类
概述:
java.lang.String 类代表字符串。Java程序中所有的字符串文字(例如 “abc” )都可以被看作是实现此类
的实例。
类 String 中包括用于检查各个字符串的方法,比如用于比较字符串,搜索字符串,提取子字符串以及创
建具有翻
译为大写或小写的所有字符的字符串的副本。
特点:
特点
- 字符串不变:字符串的值在创建后不能被更改。
String s1 = “abc”;
s1 += “d”;
System.out.println(s1);
// “abcd” // 内存中有"abc",“abcd"两个对象,s1从指向"abc”,改变指向,指向了"abcd"。 - 因为String对象是不可变的,所以它们可以被共享。
String s1 = “abc”;
String s2 = “abc”;
// 内存中只有一个"abc"对象被创建,同时被s1和s2共享。 - “abc” 等效于 char[] data={ ‘a’ , ‘b’ , ‘c’ } 。
String str = “abc”; 相当于: char data[] = {‘a’, ‘b’, ‘c’};
String str = new String(data);
// String底层是靠字符数组实现的。
构造方法
public String( ) :空参构造
初始化新创建的 String对象,以使其表示空字符序列。
//创建一个String类对象
String s = new String() ;
System.out.println("s:"+s); //不是地址值,说明当前String底层重写了Object的toString方法
System.out.println("length():"+s.length());
System.out.println("--------------------");
public String(char[ ] value)
通过当前参数中的字符数组来构造新的String。传入一个字符数组---->创建字符串对象
char[] chs = {'a','b','c','d','爱','圆','圆'} ;
String s2 = new String(chs) ;
System.out.println("s2:"+s2);
System.out.println("length():"+s2.length());
System.out.println("--------------------");
public String(byte[] bytes)
通过使用平台的默认字符集解码当前参数中的字节数组来构造新的String传入一个字节数组---->构造字符串对象
byte[] bytes = {97,98,99,100,101} ;
String s3 = new String(bytes) ;
System.out.println("s3:"+s3);
System.out.println("length():"+s3.length());
System.out.println("--------------------");
public String(byte[ ] bytes, int offset, int length)
将字节数组的一部分转换成字符串
String s5 = new String(bytes,2,3) ;
System.out.println("s5:"+s5);
System.out.println("length():"+s5.length());
System.out.println("--------------------");
public String(char[ ] value, int begin, int count)
将字符数组的一部分构造成字符串对象
String s4 = new String(chs,4,3) ;
System.out.println("s4:"+s4);
System.out.println("length():"+s4.length());
System.out.println("--------------------");
String(String original)
传入一个字符串值构造字符串对象
String s6 = new String("hello") ;
System.out.println("s6:"+s6);
System.out.println("length():"+s6.length());
获取字符串长度:
public int length()
面试题
数组中有没有length()?------>length属性
字符串中有没有length()?---->有,获取字符串长度,length()
集合中有没有length()?------>没有,size()获取集合的元素数
面试题:
String s1 = new String(“hello”) ;
String s2 = “hello” ;
s1==s2 ? s1和s2分别内存中创建了几个对象!
public class StringDemo3 {
public static void main(String[] args) {
String s1 = new String("hello") ;
String s2 = "hello" ;
System.out.println(s1==s2);//false ==比较的是地址值
/*
* equals方法在String类中已经被重写,所以比较的是内容是否相同
* */
System.out.println(s1.equals(s2));//true
}
}
看程序,写结果
字符串变量相加:先开对应自己的空间在常量池中,然后拼接,查看是否存在这个数据,如果存在,返回地址值
字符串常量相加:先进行拼接,在开空间
public class StringDemo4 {
public static void main(String[] args) {
String s1 = "hello" ;
String s2 = "world" ;
String s3 = "helloworld" ;
System.out.println(s1==s2);//false //默认比较的是地址
System.out.println(s3.equals("helloworld"));//true String重写equals方法,比较是内容是否相同
System.out.println(s3==("hello"+"world")); //true
//使用反编译工具
System.out.println((s1+s2)==s3); //false
System.out.println(s1.equals("hello"));//true
System.out.println(s2.equals("world"));//true