跳到主要内容

八大常用类

一、设计原则​

1.1 设计原则1 单一原则​

高内聚,低耦合

1.2 设计原则2 开闭原则 OCP(重要)​

对谁开放,对谁关闭

对扩展开放,对修改关闭

1.3 设计原则3 里氏替代原则​

父类可以出现的地方,子类也可以出现(继承多态)

1.4 设计原则4 依赖倒置原则(重要)​

核心是面向接口编程

1.5 设计原则5 接口分离原则​

建立单一接口,不要建立庞大臃肿的接口,尽量细化接口,接口中的方法尽量少

1.6 设计原则6 迪米特法则​

尽量降低类与类之间的耦合

两个类之间不必彼此通信

1.7 设计原则7 组合聚合复用原则​

优先使用对象组合,而不是类继承(要尽量使用合成和聚合,尽量不要使用继承)

二、类与类之间的关系​

2.1 继承、实现​

2.2 依赖和关联​

2.2.1 依赖关系​

一个类A使用到另一个类B,但是这种使用关系是具有偶然性、临时性、是非常弱的。但是类B的变化会影响到类A

类B作为类A的方法参数(或者==局部变量==存在)

2.2.2 关联关系​

比依赖关系强,必然的,长期的,强烈的

类B作为==成员变量==形成存在于类A中

一对一、一对多、多对多关系

package oop2.demo03;

import java.util.ArrayList;
import java.util.List;

public class Test03 {

}


//人类
class People{
//体现了人类与身份证类一对一的关系
private Sfz s = new Sfz();
}

//身份证类
class Sfz{

}

//===========================================================================
//学生类
class Student{
private Clazz c = new Clazz(); //一个学生在一个班级中

}

//班级类
class Clazz{
private Student[] arr = new Student[20]; //一个班级里有多个学生 一对多关系

//或者
private List<Student> list= new ArrayList<>();

}

//====================================================================================多对多
//教师类
class Teach{

//一个老师可以带多个课程
private List<Cou> list = new ArrayList<>();
}

//课程类
class Cou{

//一个课程可以被多个老师带
private List<Teach> list = new ArrayList<>();
}

2.3 聚合、组合​

关联关系的细分出来的聚合、组合,关联关系的一些特例(一对多的具体分析)

2.3.1 聚合​

整体和部分的关系。整体部分可分离,整体的生命周期和部分的生命周期不同

(例如:计算机与CPU、公司与员工、班级与学生的关系)

2.2.4 组合​

整体和部分的关系。整体部分不可分离,比聚合更强,更加紧密

(例如人与头(器官)的关系)

三、常用类 1 包装类​

3.1 引入​

包装类均位于java.lang 包

基本数据类型包装类
byteByte
booleanBoolean
shortShort
charCharacter
intInteger
longLong
floatFloat
doubleDouble

优点:

(1)某些方法的参数必须是对象,为了让基本数据类型的数据作为参数,提供包装类

(2)包装类还可以提供更多功能

(3)其他的特别重要的功能:比如可以实现字符串和基本数据类型之间的转换

package oop2.demo05;
/*
包装类的作用
*/
public class TestA {
public static void main(String[] args) {
String a = "10";

int aa = 10; //基本数据的类型
Integer bb = new Integer(10); //包装类表示的数据


int i = Integer.parseInt(a); //把String类型的数据转成int类型,a被转成int类型并存入i中
int c = i * aa; //

// Integer.parseInt() 常用:转化为int型
// Double.parseDouble() 转为为double型,其他的以此类推

System.out.println(i);
System.out.println(c);

System.out.println(Integer.SIZE); //32

System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);


}
}

3.2 自动装箱、自动拆箱​

自动装箱 基本数据类型 ---> 包装类 自动拆箱 包装类---> 基本数据类型

package oop2.demo05;


//基本类型的数据和包装类之间的相互转化
public class TestB {
public static void main(String[] args) {
int aa = 10;
Integer bb = new Integer(aa); //把基本的数据类型转为包装类

int cc = bb.intValue(); //把包装类转成基本类型

/*
自动装箱 基本数据类型 ---> 包装类
自动拆箱 包装类---> 基本数据类型
*/

int a = 10;
Integer b = a; // 这是JDK的自动装箱 底层使用的是Integer.valueOf() 完成自动装箱过程

int c = b; //自动拆箱
// 底层使用intValue()完成自动拆箱的过程

}
}

3.3 自动装箱、自动拆箱的使用​

注意:

  1. JDK1.5 以后,增加了自动装箱和自动拆箱的功能。
  2. 自动装箱调用valueOf() 方法,而不是new Integer()方法
  3. 自动拆箱调用xxxValue() 方法
  4. 包装类在自动装箱时,为了提高效率,对于-128~127之间的值会进行缓存处理。超过范围后,对象之间不能再使用==进行数值比较,而是使用equals方法
package oop2.demo05;

public class TestC {
public static void main(String[] args) {
int a = 10;
Integer b = 10; //自动装箱
System.out.println(a==b); //自动拆箱 ture b拆箱
System.out.println(b.equals(a)); //自动装箱 ture a装箱,判断a的值是否与b的值相同

//==================================================================================

Integer aa = new Integer(10);
Integer bb = new Integer(10);

System.out.println(aa == bb); //False aa与bb同一类型,不发生拆箱装箱。new两次Integer 缓存的物理地址不一样
System.out.println(aa.equals(bb)); //true


//======================================================================================

Integer aaa = 122; //自动装箱 在-128~127之内
Integer bbb = 122; //自动装箱


System.out.println(aaa == bbb); //true aaa和bbb在-128~127之内,,此种写法,他们是同一类型,同一对象
System.out.println(aaa.equals(bbb)); //true


//======================================================================================

Integer aaaa = 233; //在-127~128之外,同一类型,同一对象
Integer bbbb = 233;
System.out.println(aaaa==bbbb); //false aaa和bbb在-128~127之外,相当于new两次Integer,导致了他们的物理地址不一致
System.out.println(aaaa.equals(bbbb)); //这种情况下,只比较值大小是否相等,只能用equals方法

}
}

四、 常用类 2 String类(重要,重点掌握)​

字符串相关类,面试问的多,但是应用简单

String类的简单掌握方法

package oop2.demo06;

import javax.sound.midi.Soundbank;
import java.util.Locale;
import java.util.UUID;

public class StringB {
public static void main(String[] args) {

String a = "beijing";
String b = ""; //空字符串
String c = null; //空对象 不能使用isEmpty() 方法

System.out.println(a.length()); //返回字符串的长度 重要
System.out.println(b.isEmpty()); //是否为空
System.out.println(a.startsWith("ei")); //判断是否是以 ei 开头
System.out.println(a.endsWith("ing")); //判断是否是 以 ing 结尾
System.out.println(a.toUpperCase()); //转换为英文大写
System.out.println(a.toLowerCase()); //转为小写


System.out.println("================================字符串查找方法(全部掌握)=======================");

System.out.println(a.charAt(0)); //查找字符串中的第n个字母 (底层代码是以char类型的数组,数字从0开始)
System.out.println(a.indexOf("i")); //查找字符串中i,第一次出现的时候,数组索引数值,根据指定的字符串查询指定下标,找不到返回-1

System.out.println(a.indexOf("j",2)); //从指定位置查询字符下标.从数组下标为(2)开始,顺序找,找到j的字符下标

System.out.println(a.lastIndexOf("j",6)); //从数组下标为(6)开始找开始,倒序找,找到j的字符下标

System.out.println(a.substring(2,6)); //从数组下标为(2)到数组下标(6)截取字符串,找到j的字符下标
System.out.println(a.substring(2)); //从数组下标为(2)开始截取字符串,一直到结束


String fileName = "2.3.93.jpg";
int i = fileName.lastIndexOf(".");
System.out.println(i);

//文件后缀
String substring = fileName.substring(i);
System.out.println(substring);

//文件名称
String uuid = UUID.randomUUID().toString(); //随机生成文件名
System.out.println(uuid+substring);



}
}

4.1 字符串的分割、连接、去空格等方法​

package oop2.demo06;

import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

public class StringC {
public static void main(String[] args) throws UnsupportedEncodingException {

String str = "beijing北京";

System.out.println("========================字符串中的转化方法======================");

byte[] bytes = str.getBytes();

String str2 = new String(bytes,"GBK"); //可以给指定的字符串进行重新的编码,我们以后会使用

System.out.println(Arrays.toString(bytes));

System.out.println("========================字符串中的拼接、替换、查询是否含有======================");

String str3 = "b-j-n-u";
System.out.println(str3.contains("b")); //判断是否含有指定的字符串,掌握
System.out.println(str3.replace("b","北")); //把b替换成北 。替换指定的字符串内容,掌握
System.out.println(str3.replaceAll("j","京")); //替换指定的字符串内容,支持正则表达式,掌握


System.out.println(str3.concat("yyy")); //b-j-n-uyyy
str3.concat("a");
str3.concat("b");
str3.concat("c");
System.out.println(str3); //b-j-n-u

str3= str3.concat("a");
str3= str3.concat("b");
str3= str3.concat("c");
System.out.println(str3); //b-j-n-uabc
//str3= str3.concat("a").concat("b").concat("c");

System.out.println("========================字符串分割(掌握)======================");

String str5 = "b-j-n-u";
String[] split = str5.split("-");
System.out.println(Arrays.toString(split)); //分割,按照指定的字符位置开始分割字符串

String str6 = " b j n u ";
System.out.println("------->"+str6.trim()+"<--------"); //去除字符串中的开始和结束的空格


}
}

4.2 字符串的比较大小​

package oop2.demo06;

public class StringD {
public static void main(String[] args) {
String str = "bjnu";
String str2 = "Bjnu";

System.out.println(str.equals(str2)); //是否相等
System.out.println(str.compareTo(str2)); //比较两个字符串的大小,区分大小写的
System.out.println(str.compareToIgnoreCase(str2)); // 比较字符串的大小写,不区分大小写
}
}

4.3 举例子​

package oop2.home;
/*
获得指定后缀yy.uu.jj.png
*/

public class Demo1 {
public static void main(String[] args) {
String str = "yy.uu.jj.png";
int i = str.lastIndexOf("."); //获得最后一个.的下标
System.out.println(str.substring(i)); //根据最后一个点的下标,开始截取
}
}
package oop2.home;
/*
按照要求把对应学科提取出来 ”java-前端-AI-后台-大数据“
*/

import java.util.Arrays;

public class Demo2 {
public static void main(String[] args) {
String str = "java-前端-AI-后台-大数据";
String[] split = str.split("-");
System.out.println(Arrays.toString(split));
}
}
package oop2.home;

/*
从键盘录入一个String身份证,判断是否合法:
位数是否是18位数
前17位数必须是数字
最后一位可以是数字或者是X
*/

public class Demo3 {
public static void main(String[] args) {
String str = "440906200001253285";

if(str.length()==18){
for (int i = 0; i < str.length()-1; i++) {
char c = str.charAt(i);
if(!Character.isDigit(c)){
System.out.println("用户身份证前17位必须是数字");
return;
}
}
char c2 = str.charAt(17);
if(Character.isDigit(c2)||"X".equals(Character.toString(c2))||'X'==c2){
System.out.println("身份证合法");
}else {
System.out.println("不合法");
}

}else {
System.out.println("身份证必须是18位");
}


}


}
package oop2.home;
/*
校验一个邮箱是否合法:123456789@qq.com
必须有@
. 和 @不能在开头和结尾
.必须在@之后,且不能相邻
不能有连续的两个.
@只能有一个
. 只能有一个

*/

public class Demo4 {
public static void main(String[] args) {
String str = "123456789@qq.com";

//获得第一个@的下标
int a1 = str.indexOf("@");


//获得最后一个@的下标
int a2 = str.lastIndexOf("@");


//获得第一个 . 的位置
int b1 = str.indexOf(".");


//获得最后一个 . 的位置
int b2 = str.lastIndexOf(".");


//获得 .. 的下标
int i = str.indexOf("..");

/*
b1>a1+1 所表达的含义
b1的值一定是大于0
@的位置在 . 之前的 @的位置就一定不会在最后
. 必须在@之后且不相邻
*/

if (a1>0 && a1==a2 && b1>a1+1 && b2<str.length()-1 && i<0){
System.out.println("合法");
}else {
System.out.println("非法");
}

}
}

五、常用类 3 StringBuffer和StringBuilder类​

StringBuffer和StringBuilder 非常类似,均代表可变的字符序列。这两个类都是抽象类的,方法一模一样

StringBuffer线程安全,做线程同步检查,效率低

StringBuilder线程不安全,不做线程同步检查,效率较高,建议使用该类

5.1 StringBuilder的使用​

速度对比:

package oop2.demo06;

public class StringF {
public static void main(String[] args) {
String str = "bnu";
StringBuilder builder = new StringBuilder();
long l = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
//str = str.concat("sxt");
//builder.append("sxt");
}

long l1 = System.currentTimeMillis();
System.out.println(l1-l); //查看运行的时间,用以对比StringBuilder 和String运行的速度
}
}
一些常用方法​
package oop2.demo06;

public class StringG {
public static void main(String[] args) {

//String s = "bnu";
StringBuilder builder = new StringBuilder("bnu");
builder.append("北京师范大学"); //内容追加的方法 ,常用。
builder.insert(0,"BNU"); //指定的位置插入字符串。数组下标从0开始
char c = builder.charAt(2); //取出指定下标字符
builder.setCharAt(3,'J'); //设置指定位置的的字符
builder.replace(0,4,"北师大"); //进行指定位置的字符替换 [0,4)
builder.deleteCharAt(3); //删除指定位置字符
builder.delete(1,3); //删除多个字符 [1, 3)
builder.reverse(); //倒序输出字符串

System.out.println(builder);
System.out.println(c);

//String类型与 StringBuilder类 互转
String str = "bnu";
StringBuilder stringBuilder = new StringBuilder(str);
String s = stringBuilder.toString();


}
}

5.2 一些面试题​

StringBuilder 底层默认char数组长度为16

StringBuilder 底层的扩容机制 是 : 原有的数组长度*2+2

package oop2.demo06;

public class StringL {
public static void main(String[] args) {
String str = "abcd";
String a = "a";
String b = "b";
String c = "c";
String d = "d";
//字符串拼接的时候,如果全部是常量 ,和直接写一个结果的含义是一样的
String str2 = "a" + "b" + "c" + "d"; //创建了几个对象? 1个


String str3 = a+b+c+d; //创建了1个对象
//只要含有变量的连接,采用的就是优化的机制:
StringBuilder builder = new StringBuilder();
builder.append(a);
builder.append(b);
builder.append(c);
builder.append(d);



System.out.println(str==str2); //true
System.out.println(str2==str3); //false
}
}

六、常用类 4 Date类和DateFormat类​

我们把1970年1月1日00:00:00 定为基准时间

6.1 Date类​

大部分方法已过时,不常用

package oop2.date;
/*
Date中的三个类

sql包下的类
Date: 只含有年月日
Time: 只含有时分秒
Timestamp: 时间戳,既含有年月日,又含有时分秒
*/

import java.sql.Date;

public class DateB {
public static void main(String[] args) {
//只含有年月日 ,没有时分秒
java.sql.Date date1 = new java.sql.Date(System.currentTimeMillis());
System.out.println(date1);

String d = "2019-9-10";
Date date = Date.valueOf(d);
System.out.println(date); //字符串类型转化为Date类型
}
}

6.2 DateFormat类​

日期格式化的类

package oop2.date;
/*
作用:格式化日期类
*/

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateFormatA {
public static void main(String[] args) throws ParseException {
Date date = new Date();
System.out.println(date);

//时间格式化
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); // 也可以: yyyy年MM月dd日 hh:mm:ss
// DateFormat dateFormat2 = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");

//调用格式方法
String format = dateFormat.format(date);
// String format2 = dateFormat2.format(date);

System.out.println(format);
// System.out.println(format2);


System.out.println("=================== [B] String类型转为Date类型 ====================================");

String str = "2020-09-09 09:09:09";
DateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); //转的格式和string的格式要一致
Date parse = dateFormat1.parse(str);
System.out.println(parse);

}
}

七、常用类 5 Calendar类(日历类)​

在1.7 1.8版本还能用,到高版本也已经过时了。

package oop2.date;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class MyCalendar {
public static void main(String[] args) {
//创建日历类对象

Calendar calendar = new GregorianCalendar();
System.out.println(calendar);
System.out.println(calendar.get(Calendar.YEAR));
System.out.println(calendar.get(Calendar.MONTH));
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));

System.out.println(calendar.get(Calendar.HOUR));

//可以对年月日进行修改实现
calendar.set(Calendar.MONTH,6);

System.out.println(calendar.get(Calendar.MONTH));

int max = calendar.getMaximum(Calendar.DATE); //获得本月中一共有多少天
System.out.println(max);


/*
Calendar和Date 类可以相互转换
*/

//把日期类对象转成日历类对象
Date date = new Date();
Calendar calendar1 = new GregorianCalendar();
calendar1.setTime(date);


//把日历类对象转化为日期类
Date time = calendar1.getTime();

}
}

八、常用类 6 JDK8的新日期类​

引入了 java.time 包 。少用的。常用的还是Date和DateFormat类

package oop2.date;

import java.time.Instant;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

/**
* JDK1.8中新增加的
*/

public class MyTimeA {
public static void main(String[] args) {

//Instant
Instant now = Instant.now();
System.out.println(now);
System.out.println(now.MAX);
System.out.println(now.MIN);
System.out.println(now.EPOCH);


//LocalDate 这个只含有年月日
LocalDate localDate = LocalDate.now();
System.out.println(localDate);

//DateTimeFormatter
DateTimeFormatter dft = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
String format = localDate.format(dft);
System.out.println(format);

// String 类型转LocalDate
LocalDate.parse("2029年09月10日",dft);

}
}

九、常用类 7 Math类和Random类​

9.1 Math类​

package oop2.Mathh;

public class MathA {
public static void main(String[] args) {
System.out.println(Math.PI);

System.out.println(Math.E);
System.out.println(Math.round(3.156)); //四舍五入
System.out.println(Math.ceil(3.16)); //向上取整
System.out.println(Math.floor(3.9)); //向下取整
System.out.println(Math.random()); //产生随机数[0 , 1)



System.out.println(Math.sqrt(64)); //开平方
System.out.println(Math.pow(2,3)); // 2的3次幂
System.out.println(Math.abs(-5)); // 去绝对值
System.out.println(Math.max(2,9)); //比较两个数的大小
System.out.println(Math.min(3,2));

}
}

9.2 Random类 随机数​

package oop2.Mathh;

import java.util.Random;

public class RandomA {
public static void main(String[] args) {
Random random = new Random(); // Random()括号里有数字,则为种子,之后产生的数叫伪随机数

//产生0-10内随机整数
int i = random.nextInt(10); //如过是 nextInt() ,括号没有数,将会产生int类型范围内的数
//其他类型就是nextXXXXX类型

System.out.println(i);

// 产生4位随机数
int s = random.nextInt(9000)+1000;
System.out.println(s);

}
}

十、常用类 8 枚举​

定义枚举要使用enum 关键字

用来限制一些关键信息

package oop2.Mathh;

public class Student {
private String name;
private Gender sex;

public Student(String name , Gender sex){
this.name = name;
this.sex = sex;
}

public Student (){}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Gender getSex() {
return sex;
}

public void setSex(Gender sex) {
this.sex = sex;
}

@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
'}';
}
}
package oop2.Mathh;

public enum Gender {
男,女
}
package oop2.Mathh;

public class TestA {
public static void main(String[] args) {
Student student = new Student("zhangs",Gender.男); //在这里的sex就只能选择Gender里的枚举的内容
}
}