1 工具类
1.1 工具类的概念
- 定义: 把很多已经完成的通用功能的方法分类放到类中, 这些类就叫工具类.
- 工具类起名: XxxUtil、XxxUtils、XxxTool、XxxTools等, 其中Xxx表示一类事物,比如ArrayUtil、StringUtil、JdbcUtil.
- 工具类存放的包起名: util、utils、tool、tools等.
1.2 工具类的设计
-
使用 static 修饰的工具类.
只需要调用工具方法的工具类名.
必须把工具类的构造器私有化, 防止创建工具类的对象来调用静态方法, 可以节约内存.
-
没有使用static修饰的工具
没有静态修饰, 所以必须使用工具类的对象去调用工具方法.
必须把工具类设计为单例模式.
//自定义的工具类
//专门操作数组的工具类
public class ArrayUtil {
//构造器私有化
private ArrayUtil(){};
//有静态修饰: 类.方法()
//没有静态修饰: 对象.方法()
public static void sort (int[] arr){
java.util.Arrays.sort(arr);
System.out.println(java.util.Arrays.toString(arr));
}
public static void binarySearch(int[] arr,int key){
int index = java.util.Arrays.binarySearch(arr, key);
System.out.println(index);
}
}
//测试
public class ArrayUtilDemo {
public static void main(String[] args) {
int[] arr = {2,5,7,8,5,3};
ArrayUtil.sort(arr);
ArrayUtil.binarySearch(arr,4);
}
}
1.3 单例模式
- 单例设计模式( singleton )最常用、最简单的设计模式, 单例的编写有N种写法.
目的: 让应用中的某个类有且只有一个实例(一个类在堆内存只存在一个对象).
写单例模式的步骤( 单讲饿汉式 ):
-
必须在该类中, 自己先创建出一个私有化对象.
-
私有化自身的构造器, 防止外界通过构造器创建新的工具类对象.
-
向外暴露一个公共的静态方法用于返回自身的对象.
public class ArrayUtil {
//构造器私有化
//不让外界随意创建对象
private ArrayUtil() {}
//事先创建好外界需要的私有化对象
//这里不能用public 因为反射可以访问私有构造器去创建对象
private static ArrayUtil instance = new ArrayUtil();
//提供一个公共的静态方法,来返回获得该对象
public static ArrayUtil getInstance(){
return instance;
}
//数组操作
public static void sort (int[] arr){
java.util.Arrays.sort(arr);
System.out.println(java.util.Arrays.toString(arr));
}
public static void binarySearch(int[] arr,int key){
int index = java.util.Arrays.binarySearch(arr, key);
System.out.println(index);
}
}
public class ArrayUtilDemo {
public static void main(String[] args) {
int[] arr = {2,5,7,8,5,3};
ArrayUtil.getInstance().sort(arr);
ArrayUtil.getInstance().binarySearch(arr,6);
}
}
使用枚举完成:
public enum ArrayUtil {
INSTANCE;
public static void sort (int[] arr){
java.util.Arrays.sort(arr);
System.out.println(java.util.Arrays.toString(arr));
}
public static void binarySearch(int[] arr,int key){
int index = java.util.Arrays.binarySearch(arr, key);
System.out.println(index);
}
}
public class ArrayUtilDemo {
public static void main(String[] args) {
int[] arr = new int[]{2,5,7,8,5,3};
ArrayUtil.INSTANCE.sort(arr);
}
}
2 包装类
2.1 基本类型包装
2.2 装箱和拆箱
2.2.1 手动装箱和拆箱
装箱: 把基本类型数据转成对应的包装类对象.
拆箱: 把包装类对象转成对应的基本数据类型.
装箱操作:
方式一:Integer num1 = new Integer(1);
方式二:Integer num2 = Integer.valueOf(1);//推荐使用
拆箱操作:
Integer num3 = Integer.valueOf(17);//装箱操作
int val = num3.intValue();//拆箱操作
2.2.2 自动装箱和拆箱
自动装箱: 可把一个基本类型变量直接赋给对应的包装类变量.
自动拆箱: 可以把包装类对象直接赋给对应的基本数据类型变量.
Integer ig = 1;//自动装箱操作
int i = i;//自动拆箱操作
把字符串转换为int类型操作:
int num = Integer.parseInt("1");
如果传入的数据是非数字组成, 如“ABC123”, 此时报错NumberFormatException.
2.2.3 缓存设计
- 定义:从性能上考虑, 把常用数据存储到缓存区域, 使用时不需要每次都创建新的对象, 可以提高性能.
-
Byte、Short、Integer、Long: 缓存范围[-128,127];
-
Character:缓存范围[0,127];
public static void main(String[] args) {
Integer i1 = Integer.valueOf(1);//利用缓存提升性能
Integer i2 = Integer.valueOf(1);
System.out.println(i1 == i2);// true
Integer i3 = 1; // 底层等价于
Integer i4 = 1;
System.out.println(i3 == i4);// true
}
拓展:
-
如果要比较两个对象的数据是否相等, 必须使用equals方法来判断.
-
==比较的是两个数据的内存空间是否是同一块, equals比较的是存储数据是否相等.
-
int类型的默认值为0, Integer的默认值为null, 在开发中建议使用Integer.因为Integer既可以表示0也可以表示null.
2.3 BigDecimal
- 定义: BigDecimal 用于处理金钱或者任意精度要求高的数据.
BigDecimal不能直接把赋值和运算操作, 只能通过构造器传递数据, 而且必须使用字符串类型的构造器, 操作BigDecimal主要是加减乘除四个操作.
//常用的加减乘除以及大小比较
public class BigDecimalDemo {
public static void main(String[] args) {
System.out.println(0.01+0.09);
BigDecimal b1 = new BigDecimal(0.09);
BigDecimal b2 = new BigDecimal(0.01);
System.out.println(b1.add(b2));
//建议使用String类型参数构造器创建BigDecimal
BigDecimal b3 = new BigDecimal("0.09");
BigDecimal b4 = new BigDecimal("0.01");
//加
System.out.println(b3.add(b4));
//减
System.out.println(b3.subtract(b4));
//乘
System.out.println(b3.multiply(b4));
//对结果四舍五入
System.out.println(b3.multiply(b4).setScale(3, RoundingMode.HALF_UP));
//divide除不尽会报错
System.out.println(b3.divide(b4));
//当出现报错时我们可以采取,保留3位,四舍五入
System.out.println(b3.divide(b4,3,RoundingMode.HALF_UP));
//比较大小
//b3>b4 1
//b3<b4 -1
//b3=b4 0
System.out.println(b3.compareTo(b4));
}
}
3 字符串
字符串( 字符序列 ), 表示把多个字符按照一定得顺序排列起来.
字符串的本质是char[],char表示一个字符,char[]表示同一种类型的多个字符。
字符串的分类( 根据同一个对象, 内容能不能改变而区分 ):
- 不可变的字符串——String: 当String对象创建完毕之后,该对象的内容是不能改变的, 一旦内容改变就变成了一个新的对象.
- 可变的字符串——StringBuilder/StringBuffer: 当StringBuilder对象创建完毕之后, 对象的内容可以发生改变, 当内容发生改变的时候, 对象保持不变.
3.1 String
String类, 表示不可变的字符串, 当String对象创建完毕之后, 该对象的内容是不能改变的.
- String对象的创建的两种方式:
1、直接创建:String s1 = "ABCD";//直接存储在方法区的常量池中,节约内存
2、通过构造器创建:String s2 = new String("ABCD");
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KYw4VsVH-1597834818215)(Z:\笔记\img\String创建对象内存分析.png)]
String对象的空值:
表示引用为空(null): String str1 = null;没有初始化,没有分配内存空间.
内容为空字符串: String str2 = “”;已经初始化,分配内存空间,不过没有内容
判断字符串非空:字符串不为null并且字符内容不能为空字符串(“”)
public class StringUtil {
public static boolean isEmpty(String str){
//trim除去前后空格 length判断长度是否为0
return str == null || str.trim().length() == 0 ; //判断字符串是否为空
}
}
字符串的比较操作:
-
使用”==”号:比较两个字符串引用的内存地址是否相同
-
使用equals方法:比较两个字符串的内容是否相同
3.2 String常用方法
- int length() 返回此字符串的字符个数
- char charAt(int index) 返回指定索引位置的字符
- int indexOf(String str) 返回指定子字符串在此字符串中第一次出现处的索引位置
- boolean equals(Object anObject) 比较内容是否相同
- boolean equalsIgnoreCase(String anotherString) 忽略虑大小写,比较内容是否相同
- String toUpperCase() 把当前字符串转换为大写
- String toLowerCase() 把当前字符串转换为小写
- String substring(int beginIndex):从指定位置开始截取字符串
- String substring(int beginIndex, int endIndex):截取指定区域的字符串
- boolean endsWith(String suffix)
- boolean startsWith(String prefix)
- replace(char oldChar, char newChar)
3.3 StringBuilder和StringBuffer
StringBuffer和StringBuilder都表示可变的字符串,功能方法相同的,区别是:
-
StringBuffer:StringBuffer中的方法都使用了synchronized修饰,保证线程安全但性能较低
-
StringBuilder:StringBuilder中的方法没有使用synchronized修饰,线程不安全但但是性能较高
-
开发中建议使用StringBuilder,具体用法如下:
如果事先知道需要拼接多少个字符,可以在创建StringBuilder对象时指定字符数组容量,缺省为16
使用append方法在原字符串后面继续拼接字符串(链式语法)
public class StringBuilderDemo {
public static void main(String[] args) {
//使用String完成字符串的拼接
String s1 = "你好";
String s2 = "世界";
String s3 = s1 + s2;//得到一个新字符串
System.out.println(s3);
//每次拼接都会得到一个新的字符串(对象)
//如果在循环中来拼接字符串,会得到大量的字符串对象,浪费内存,所以在循环建议不要使用String
//解决方案:使用StringBuilder(线程不安去,效率高)/StringBuffer(线程安全,效率低)
//功能在哪个方法中?方法是否是静态的?需要什么参数和返回什么数据?
//如有不是静态方法,有什么可用的构造器
//append: 追加,在字符串后面加上,非静态方法
//构造器
//StringBuilder()
//StringBuilder(int capacity):指定容量
StringBuilder sb = new StringBuilder();
sb.append("你好");
sb.append("世界");
System.out.println(sb);
sb.append("你好").append("世界");
System.out.println(sb);
//StringBuilder deleteCharAt(int index):删除指定索引位置的字符
}
}
4.总结
4.1 什么是工具类?工具类如何设计?
工具类: 把很多已经完成的通用功能的方法分类放到类中
用Public static修饰 :只需要调用工具方法的工具类名.
必须把工具类的构造器私有化, 防止创建工具类的对象来调用静态方法, 可以节约内存.
没用static修饰 :没有静态修饰, 所以必须使用工具类的对象去调用工具方法
4.2 什么是单例设计模式?有哪些实现方式?
最常见,最简单的设计模式
-
必须在该类中, 自己先创建出一个私有化对象.
-
私有化自身的构造器, 防止外界通过构造器创建新的工具类对象.
-
向外暴露一个公共的静态方法用于返回自身的对象.
4.3 掌握八大基本数据类型的包装类
Byte,Short,Integer,Long,Float,Double,Character,Boolean
4.4 基本类型和包装类的区别
通常成员变量都会使用包装类,局部变量使用基本数据类型
基本类型只能进行±/运算,不能实现功能,而包装类可以实现功能,进行±/运算时需要拆箱
4.5 什么是装箱和拆箱?
装箱:将基本数据类型转换为对应的包装类对象
拆箱:将包装类对象转换为对应的基本数据类型
4.6 什么是自动装箱和拆箱
自动装箱:可以把基本数据类型直接赋值给对应的包装类对象
自动拆箱:可以把包装类对象直接赋值给对应的基本数据类型
4.7 BigDecimal的加减乘除和保留精度操作、
BigDecimal a = new BigDecimal("1.1");
BigDecimal b = new BigDecimal("0.1");
a+b : System.out.println(a.add(b));
a-b : System.out.println(a.subtract(b));
a*b : System.out.println(a.multiply(b).setScale(2,RoudingMode.HALF_UP));
a/b : System.out.println(a.divide(b,2,RoudingMode.HALF_UP));
4.8 String对象的创建和数据的存储?画内存
图
直接创建:String s1 = “ABCD”;
构造器创建:String s2 = new String(“ABCD”);
4.9 String中常用的方法
public class StringDemo {
public static void main(String[] args) {
String str = "Hello Word ";
//返回长度
System.out.println(str.length());
//返回索引位置
System.out.println(str.charAt(4));
//返回子字符串第一出现在原来字符串的索引位置
System.out.println(str.indexOf("ll"));
//内容是否相等
System.out.println(str.equals("Hello Word"));
//不管大小写内容是否相等
System.out.println(str.equalsIgnoreCase("hello word"));
//把数据全部变成大写
System.out.println(str.toUpperCase());
//把数据全部变成小写
System.out.println(str.toLowerCase());
//拿出需要的某个字符串
System.out.println(str.substring(8));
//拿出需要的某段字符串
System.out.println(str.substring(8, 9));
//开头是不是非空
System.out.println(str.startsWith(""));
//是不是以某个结束
System.out.println(str.endsWith("Word "));
//去掉前后字符串的空格
System.out.println(str.trim());
}
}