6 常用类的概述和使用
6.1 常见的包
层次:模块-包-类(例如base 模块–java.lang包–String类)
-** java.lang包** - 该包是Java语言的核心包,并且该包中的所有内容由Java虚拟机自动导入。
如:System类、String类、…
- java.util包 - 该包是Java语言的工具包,里面提供了大量工具类以及集合类等。
如:Scanner类、Random类、List集合、…
- java.io包 - 该包是Java语言中的输入输出包,里面提供了大量读写文件相关的类等。
如:FileInputStream类、FileOutputStream类、…
-** java.net包** - 该包是Java语言中的网络包,里面提供了大量网络编程相关的类等。
如:ServerSocket类、Socket类、…
-** java.sql 包** - 该包是Java语言中的数据包,里面提供了大量操作数据库的类和接口等。
如:DriverManager类、Connection接口、…
注:Java程序员在编程时可以使用大量类库,因此Java编程时需要记的很多,对编程能力本身要求不是特别的高。
6.2 Object类的概述(重点)
1)基本概念:
- java.lang.Object类是Java语言中类层次结构的根类,也就是说任何一个类都是该类的直接或者间接子类。
- ** 如果定义一个Java类时没有使用extends关键字声明其父类,则其父类为 java.lang.Object 类。**
- Object类定义了“对象”的基本行为, 被子类默认继承。
- 调用从Object类中继承的equals方法,该方法默认比较两个对象地址。
2)常用方法
- List item
方法声明 | 功能介绍 |
---|---|
Object() | 使用无参方式构造对象 |
boolean equals(Object obj) | 用于判断调用对象是否与参数对象相等。该方法默认比较两个对象的地址是否相等,与 == 运算符的结果一致。若希望比较两个对象的内容,则需要重写该方法。若该方法被重写后,则应该重写hashCode方法来保证结果的一致性。 |
int hashCode() | 用于获取调用对象的哈希码值(内存地址的编号)。若两个对象调用equals方法相等,则各自调用该方法的结果必须相同;若两个调用对象equals方法不相等,则各自调用该方法的结果应该不相同;为了使得该方法与equals方法保持一致,需要重写该方法。 |
String toString() | 用于获取调用对象的字符串形式;该方法默认返回的字符串为:包名.类名@哈希码值的十六进制;为了返回更有意义的数据,需要重写该方法;使用print或println打印引用或字符串拼接引用都会自动调用该方法 |
Class<?> getClass() | 用于返回调用对象执行时的Class实例,反射机制使用 |
案例:
编程实现Student类的封装,特征:学号(id)和姓名,要求提供打印所有特征的方法。
编程实现StudentTest类,在main方法中使用有参方式构造两个Student类型的对象并打印特征。
题目扩展:
如何实现以姓名作为基准判断两个对象是否相等?以及以学号和姓名同时作为基准判断两个对象是
否相等?
package com.lagou.task11;
public class Student {
private int id;
private String name;
public Student() {
}
public Student(int id, String name) {
setId( id ) ;
setName( name );
}
public int getId() {
return id;
}
public void setId(int id) {
if( id >= 0){
this.id = id;
}else{
System.out.println("学号值有误!");
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//为了比较两个对象的内容,也就是学号信息比较
@Override
public boolean equals(Object obj) {
//当调用对象和参数对象指向同一个对象时,则内容一定相同;
if( this == obj ) return true;
//当调用对象不为空而参数对象为空时,则内容不一定相同;
if( null == obj ) return false;
if( obj instanceof Student ){
Student ts = (Student)obj;//强制类型转换,父类转子类
//以学号为基准判断两个对象是否相等 int 数据类型是基本数据类型,内容空间放的就是数据本身,使用 == 就可以判断是否相同
//return this.getId() == ts.getId();
//以姓名为基准判断两个对象是否相等 String 是引用数据类型,内存空间存放的是地址, 使用 == 判断的是地址是否相等
//也就是判断两个对象中姓名字符串的地址是否相等,不够完美
//return this.getName() == ts.getName();
return this.getName().equals(ts.getName());
}else{//类型不一致,则调用重写之后的版本
return false;
}
}
/**
* 为了使得该方法的结果与equals方法的结果保存一致,从而满足Java官方的常规约定,需要重写该方法
*/
@Override
public int hashCode() {
//return getId();//不在表示内存地址的编号
final int type = 12;
return type * 31 + getName().hashCode();
}
/**\
* 为了返回更有意义的字符串数据,则需要重写该方法
*/
@Override
public String toString() {
return "Student[id = " + getId() + ", name = " + getName() + "]";
}
}
package com.lagou.task11;
public class StudentTest {
public static void main(String[] args) {
Student s1 = new Student( 1000,"zhangfei");
Student s2 = new Student( 1001,"guanyu");
Student s3 = s1;
System.out.println( s1 == s2 );
//下面调用从Object类中继承下来的equals方法,该方法默认比较两个对象的地址,可以查看源码验证
//当Student类中重写该方法时,则调用以后的版本,比较内容
boolean b1 = s1.equals( s2 );
System.out.println("-----------------------");
//下面调用从Object类中继承下来的hashCode方法,获取调用对象的哈希码值(内存地址编号)
//当Student类中重写hashCode方法后,则调用重写以后的版本
int ia = s1.hashCode();
int ib = s2.hashCode();
System.out.println("ia = " + ia);
System.out.println("ib = " + ib);
System.out.println("-----------------------");
//下面调用从Object类中继承下来的toString方法,获取调用对象的字符串形式:包名.类名@哈希码的十六进制
//为了返回更有意义的字符串数据,则需要重写该方法
String str1 = s1.toString();
System.out.println("str1 = " + str1);//当打印一个引用变量时,系统会自动调用toString方法
}
}
运行结果:
false
-----------------------
ia = -1432616558
ib = -1235113109
-----------------------
str1 = Student[id = 1000, name = zhangfei]
总结:1)int 等数据类型是基本数据类型,内容空间放的就是数据本身,使用 == 就可以判断是否相同;
2)String 等引用数据类型,内存空间存放的是地址, 使用 == 判断的是地址是否相等;
3)Student ts = (Student)obj; //强制类型转换,父类转子类
6.3 包装类
1、概念
通常情况下,基本数据类型的变量不是对象,为了满足万物皆对象的理念需要对基本数据类型的变量进行打包封装处理变成对象,而负责将这些变量声明为成员变量进行对象处理的相关类,叫做包装类。
2、分类
注意:1)从Java5开始,增加了自动装箱和自动拆箱的功能。
2)在Integer类的内部提供了自动装箱池技术,将-128—127之间的整数已经装箱完毕,无需装箱直接取用自动装箱池中的对象即可,从而提高效率。
总结:
- 基本数据类型对应转换为对应包装物的方式
调用包装类的构造方法或静态方法即可 - 获取包装类对象的基本数据类型变量数值的方式
调用包装类中***value的方法 - 字符串转换为基本数据类型的方式
调用包装类中的parse***方法即可;
6.4 Math类
java.lang.Math类主要用于提供执行数学运算的方法,如:对数,平方根
常用方法:
精确运算: Java.math.BigDecimal
//构造BigDecimal类型的两个对象
BigDecimal bd1 = new BigDecimal("5.2");//参数为字符串
6.5 String类
构造方法
//1、无参构造对象并打印
String str1 = new String();
//2、使用参数指定的btye数组来构造打印数组
byte[] arr = { 97, 98,99,100,101 };
String str2 = new String( bArr, 1, 3);
String str3 = new String( bArr);//使用整个数组
System.out.println( "str2 = " + str2 );//输出:str2 = bcd;
//3、使用字符数组来构造字符串对象
char[] cArr = {'h', 'e', 'l', 'l','o'};
String str4 = new String(cArr, 2, 2);
string str5 = new String( cArr);
//4、使用字符串来构造
String str6 = new String( "world" );
常见笔试考点:
//1、请问下面代码会创建几个对象?分别存放在什么地方?
String str1 = "hello";//创建一个对象,存放在常量池中
String str2 = new String("world");//2个对象,1个在常量池中,1个在堆区
//2、常量池和堆区比较
String str1 = "hello";//常量池
String str2 = "hello";//常量池
String str3 = new String("hello");//堆区
String str4 = new String("hello");//堆区
System.out.println( str1 == str2); //比较地址 true;
System.out.println( str1.equals(str2)); //比较内容 false
System.out.println( str3 == str4 ); //比较地址 true;
System.out.println( str3.equals(str4)); //比较内容 true
//3、常量有优化机制,变量没有
String str5 = "abcd";
String str6 = "ab" + "cd";//常量优化机制,"abcd"
System.out.println( str5 == str6 ); //比较地址 true;
String str7 = "ab";
String str8 = str7 + "cd";
System.out.println( str7 == str8 ); //比较地址 flase;(有新对象产生)
String str1 = new String("hello");
System.out.println( str1.length());//获取字符串长度
for( int i = 0; i < str1.length(); i++ ){
System.out.println( "下标为" + i + "字符为:" + str1.charAt(i));//获取单个字符
}
str1.isEmpty(); //判断字符串是否为空
用两种方法实现
//方法1: 调用integer类中的parseInt()方法即可;
String str2 = "12345";
int ia = Integer.parseInt( str2 );
//方法2:利用ASCII码来实现类型转换并打印
//'1' - '0' = 1
int res = 0;
for( int i = 0; i < str2.length(); i++ ){
res = res * 10 + (str2.charAt(i) - '0');
}
System.out.println( res );
判断字符串是否为回文串:
String str1 = "上海自来水来自海上";
System.out.println( "字符串为" + str1 );
for( int i = 0; i < str1.length() / 2; i++ ){
if( str1.charAt(i) != str1.charAt( str1.length() - i -1 ) ){
System.out.println( str1 + "不是回文串" );
return ;//仅仅用于实现方法的结束
}
}
System.out.println( str1 + "是回文串" );
字符串比较:
String str1 = "hello";
str1.compareTo("world");
一些常用方法:
例子:登录验证
public class StringEqualTest{
public static void main(){
Scanner sc = new Scanner( System.in );
for( int i = 3; i > 0; i-- ){//只有三次输入机会
//1、提示用户从键盘输入用户名和密码信息并使用变量记录
System.out,println( "请输入您的用户名和信息:" );
String name = sc.next();
String password = sc.next();
//2、判断用户名和密码是否正确
if( "admin".equals(name) && "12345".equals(password) ){//防止空指针异常
System.out.println("登录成功");
}
if(1 == i){
System.out.println( "账号已经冻结,请联系工作人员!" );
}else{
System.out.println( "用户名或者密码错误!" );
}
}
sc.close();//关闭扫描器
}
}
正则表达式
正则表达式本质就是一个**“规则字符串”**,可以用于对字符串数据格式进行验证,以及匹配、查找、替换等操作,该字符串使用^运算作为开头标志,使用$运算符作为结尾标志,当然也可以省略。
正则表达式只能对用户的格式进行检查,无法对数据内容进行检查。
String reg = "^[0-9]{6}$";//表示6位0-9的数字,也可采用"\\d{6}"
if( str1.matches( reg ) ){
System.out.println("格式正确");
}
qq账号:非0开头的4-15位数字
String reg = "[1-9]\\d{4,14}";
手机账号规则:要求1开头,第二位数字3,4,5,7,8中的一位,总共11位
String reg = "^1[34578]\\d{9}";
常用函数:
//按照逗号对str进行切分
String str = "1001, zhangfei, 30";
String[] arr = str.sqlit( "," );
//字符替换
String str2 = str1.replace( "我","你" )
6.6 可变字符串类和日期相关类
原因:由于String类描述的字符串内容式常量不可改变,当需要在java代码中描述大量类似的字符串时,只能单独申请和存储,此时造成内存空间的浪费。
为了解决上述问题,可以使用java.lang.StringBulider类和java.lang.StringBuffer类来描述字符序列可以改变的字符串,如"ab"
- StringBuffer类是从jdk1.0开始存在。属于线程安全的类,因此效率比较低。
- StringBulider类是从jdk1.5开始存在,属于非线程安全的类,效率比较高。
自动扩容:当字符串的长度超过字符串对象的初始容量时,该字符串对象会自动扩容,默认扩容算法是**:原始容量 * 2 + 2**