Java(3)常用类
@
Java常用类
一、字符串相关的类
1、String类
-
介绍
-
String声明为final的,不可被继承
-
String实现了Serializable接口:支持序列化;
String实现了Comparable接口:可比较大小;
-
String内部定义了
final char[] value
用于存储字符串数据 -
String代表不可变的字符序列,简称:不可变性,体现如下:
- 首先明确:①、什么是“字面量的定义方式”:
String s = “abc”;
。②、通过字面量的方式给一个字符串赋值,此时字符串声明在字符串常量池中。③、字符串常量值中不会存储相同内容的字符串。 - 体现:对字符串进行重新赋值、连接、修改时,都是重新在字符串常量池中开辟内存空间。①、当对字符串重新赋值时,需要重新指定内存区域赋值,不能使用原有的 value 进行赋值。②、当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能在原有的 value 上操作。③、当调用 String 的 replace() 方法修改指定字符或字符串时,也必须重新指定内存区域赋值。
- 首先明确:①、什么是“字面量的定义方式”:
-
-
String不同实例化方式的对比(面试题)
-
方式一:通过字面量的方式定义:
String s1 = "abc";
- s1中的数据声明在方法区的字符串常量池
-
方式二:通过new + 构造器的方式:
String s2 = new String();
- s2中保存的地址值,是数据在堆空间中开辟空间后对应的地址值。
-
-
String s = new String("abc"); 创建了几个对象?(面试题)
- 一个是因为
new
:在堆空间中创建的对象 - 一个是因为
char[]
:在方法区的字符串常量池中创建了数据
- 一个是因为
-
字符串特性(面试题)
注意:final定义的变量,也视为常量。面试题中会出现混淆一下我们。
-
程序题(面试题)
public class StringTest {
String str = new String("good");
char[] ch = { 't', 'e', 's', 't' };
public void change(String str, char ch[]) {
str = "test ok";
ch[0] = 'b';
}
public static void main(String[] args) {
StringTest ex = new StringTest();
ex.change(ex.str, ex.ch);
System.out.println(ex.str);
System.out.println(ex.ch);
}
}
/*
结果为
good
best
因为:
1、传递给形参的都是引用数据类型,由值传递机制可知,把变量的地址传递给了形参。
2、str的地址传递给形参:形参要改变数据内容,就需要另外开辟内存,但是没有影响到str
3、数组的地址传递给形参:形参要改变数据内容,直接在上面操作,导致ch数据改变
*/
-
String常用方法
方法 功能 int length() 返回字符串长度 char charAt(int index) 返回某个索引处的字符 boolean isEmpty() 判断是否是空串 String toLowerCase()
String toUpperCase()所有字符变小写、大写 String trim() 去掉前后空格 boolean equals(Object obj) 比较字符串内容是否相同 String concat(String str) 拼接 int compareTo(String anotherString) 比较大小 String substring(int beginIndex)
String substring(int beginIndex, int endIndex)返回子串 其他方法
-
boolean endsWith(String suffix)
boolwan startsWith(String prefix)
boolean startsWith(String prefix, int toffset)
-
boolean contains(CharSequence s)
-
int indexOf(String str)
int index(String str, int fromIndex)
int lastIndexOf(String str)
int lastIndexOf(String str, int fromIndex)
-
String replace(char oldChar, char newChar)
String replace(CharSequence taget, CharSquence replacement)
-
-
字符串与其他类型的转换
-
字符串--->基本数据类型、包装类:
Integer.parseInt(String s)
,类似的可以用Byte、Short、Long、Float、Double类调用相应的方法。基本数据类型、包装类--->字符串:
str.valueOf(int n)
-
字符串--->字符数组:String类的方法
public char[] toCharArray()
和String类的方法public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
字符数组--->字符串:String类的构造器
String (char[])
和String(char[], int offset, int length)
-
字符串--->字节数组:String类的方法
public byte[] getBytes()
和public byte[] getBytes(String charsetName)
字节数组--->字符串:String类的构造器
String(byte[])
和String(byte[], int offset, int length)
-
2、StringBuffer类
-
介绍
-
代表可变的字符序列
-
很多方法和String相同
-
作为参数传递时,方法内部可以改变值
-
-
StringBuffer类不同于String,其对象必须使用构造器生成。有三个构造器
- StringBuffer():初始容量为16的字符串缓冲区
- StringBuffer(int size):指定容量
- StringBuffer(String str):指定内容
-
常用方法
含义 方法 拼接 append(xxx) 删除 delete(int start, int end) 替换 replace(int start, int end, String str) 插入 insert(int offset, xxx) 逆转 reverse() -
方法链原理
-
3、StringBuilder类
-
介绍:StringBuilder 和 StringBuffer 非常类似,均代表可变的字符序列,而且提供相关功能的方法也一样。
-
对比三者(面试题)
字符串名 解释 底层 特点 存在时间 String 不可变字符序列 char[] 不可变 JDK1.0 StringBuffer 可变字符序列 char[] 效率低、线程安全 JDK1.0 StringBuilder 可变字符序列 char[] 效率高、线程不安全 JDK5.0 - 作为参数传递的话,方法内部String不会改变其值,StringBuffer和StringBuilder 会改变其值
二、JDK8以前的日期时间API
1、java.lang.System类
返回当前时间与1970年1月1日0时0分0秒之间的时间差,单位是毫秒数:public static long currentTimeMillis()
2、java.util.Date类
-
构造器
- Date():获取本地当前时间(这个日期是动态的,每次运行都是当前时间)
- Date(long date):自己输入一个long类型的时间毫秒数,来构造Date类型的日期(一般用空参构造器调用getTime()方法)
-
方法
- getTime():返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象 表示的毫秒数
- toString():把此 Date 对象转换为以下形式的 String: dow mon dd hh:mm:ss zzz yyyy 其中: dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat),zzz是时间标准。
-
java.util.Date类和java.sql.Date类的转换
-
java.util.Date--->java.sql.Date
@Test public void test02(){ Date date1 = new Date(); System.out.println(date1); java.sql.Date date2 = new java.sql.Date(date1.getTime()); System.out.println(date2); } //javjava..Date只有一个构造器就是public Date(long date),所以用构造器转换就ok
-
java.sql.Date--->java.util.Date:这个转换是不存在的,因为sql.Date是util.Date的子类
-
3、java.text.SimpleDateFormate类
-
Date类的API不易于国际化,大部分被废弃了,java.text.SimpleDateFormat 类是一个不与语言环境有关的方式来格式化和解析日期的具体类。
-
构造器
- SimpleDateFormat()
- SimpleDateFormat(String pattern)
-
格式化:日期--->文本:
public String format(Date date)
- 使用空参构造器时,默认格式化为:20-11-18 下午10:58
- 带参构造器,开发中常用的指定格式为:
yyyy-MM--dd hh:mm:ss
解析:文本--->日期:
public Date parse(String source)
1. 使用空参构造器时,默认只能解析格式为:20-11-18 下午10:58的文本 2. 会抛出异常,因为可能格式不能识别。
4、java.util.Calendar类
- Calendar是一个抽象基类
- 获取Calendar实例的方法
- 使用
Calendar.getInstance()
- 调用他的子类
GregorianCalendar
的构造器
- 使用
- 常用方法
- get:获得当前日历信息
- set:设置日历信息
- add:设置,加就是正数,减就是负数
- getTime():得到Date类型的日期时间
- setTime(Date date):把Date类型的时间设置为Calendar类型的时间
- 注意事项
- 获取月份时:一月是0,二月是1,以此类推,12月是11
- 获取星期时:周日是1,周一是2 ,以此类推,周六是7
三、JDK8中新的日期时间API
1、LocalDate、LocalTime、LocalDateTime
-
引入:Java 8 吸收了第三方jar包 Joda-Time 的精华。(如果所在的公司用的是java8以前的版本,不放使用这个包)
-
LocalDate、LocalTime、LocalDateTime 类是其中较重要的几个类,它们的实例 是不可变的对象,分别表示使用 ISO-8601日历系统的日期、时间、日期和时间。 它们提供了简单的本地日期或时间,并不包含当前的时间信息,也不包含与时区 相关的信息
- LocalDate代表IOS格式(yyyy-MM-dd)的日期,可以存储 生日、纪念日等日期
- LocalTime表示一个时间,而不是日期
- LocalDateTime是用来表示日期和时间的,这是一个最常用的类之一
-
方法
-
实例化:提供了静态方法来获得实例
now()、now(Zoneld zone) 静态方法,根据当前时间创建对象/指定时区的对象 of() 静态方法,根据指定日期/时间创建对象 -
getXxx方法
方法 描述 getDayOfMonth()、getDayOfYear() 获得月份天数(1-31) /获得年份天数(1-366) getDayOfWeek() 获得星期几(返回一个 DayOfWeek 枚举值) getMonth() 获得月份, 返回一个 Month 枚举值 getMonthValue()、getYear() 获得月份(1-12) /获得年份 getHour()、getMinute()、getSecond() 获得当前对象对应的小时、分钟、秒 -
修改日期时间的方法
方法 描述 withDayOfMonth()、withDayOfYear()、withMonth()、withYear() 将月份天数、年份天数、月份、年份修改为指定的值并返回新的对象 plusHours()、plusDays()、plusWeeks()、plusMonths()、plusYears() 向当前对象添加几小时、几天、几周、几个月、几年 minusHours()、minusDays()、minusWeeks()、minusMonths()、minusYears() 向当前对象减去几小时、几天、几周、几个月、几年
-
2、瞬时:Instant
-
引入:在处理时间和日期的时候,我们通常会想到年,月,日,时,分,秒。然而,这只是 时间的一个模型,是面向人类的。第二种通用模型是面向机器的,或者说是连 续的。在此模型中,时间线中的一个点表示为一个很大的数,这有利于计算机 处理。java.time包通过值类型Instant提供机器视图,不提供处理人类意义上的时间 单位。Instant表示时间线上的一点,而不需要任何上下文信息
-
方法
3、格式化与解析
4、其他API
四、Java比较器
1、说明
Java中的对象,只能用==和!=,而不能使用< 和 >。如果类实现了Comparable或Comparator接口,就可以进行大小比较,从而进行排序。
2、自然排序:Comparable接口使用举例
-
String、包装类实现了Comparable接口,重写了compareTo()方法,可以比较两个对象的大小
- 重写compareTo的规则
- 如果当前对象this大于形参对象obj,返回正整数
- 如果当前对象this小于形参对象obj,返回负整数
- 如果当前对象this等于形参对象obj,返回零
- 重写compareTo的规则
-
对于自定义类,要排序,需要实现Comparable接口,重写compareTo()方法,在compareTo()方法中指明如何排序。
-
如果我们没有对自定义类实现Comparable接口,就对其进行排序,会报错:
Exception in thread "main" java.lang.ClassCastException: CompareDemo.Goods cannot be cast to java.lang.Comparable
-
实现Comparable接口代码
class Goods implements Comparable{ private String name; private double price; @Override public int compareTo(Object o) { if(o instanceof Goods){ Goods goods1 = (Goods) o; return Double.compare(this.price, goods1.price); } throw new RuntimeException("类型不一致"); } }
-
此时,我们在进行排序,就会按照我们重写的CompareTo()里面的逻辑进行排序。
public class GoodsCompareTest { public static void main(String[] args) { Goods[] goods = new Goods[4]; goods[0] = new Goods("a",4.0); goods[1] = new Goods("b",3.0); goods[2] = new Goods("c",2.0); goods[3] = new Goods("d",1.0); Arrays.sort(goods); System.out.println(Arrays.toString(goods)); } }
-
3、定制排序:Comparator接口
-
说明:当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用 Comparator 的对象来排序,强行对多个对象进行整体排 序的比较。
-
重写:重写compare(Object o1,Object o2)方法,比较o1和o2的大小:如果方法返 回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示 o1小于o2
-
代码实现
public class GoodsCompareTest { public static void main(String[] args) { Goods[] goods = new Goods[4]; goods[0] = new Goods("a",4.0); goods[1] = new Goods("b",3.0); goods[2] = new Goods("c",2.0); goods[3] = new Goods("d",1.0); Arrays.sort(goods, new Comparator<Goods>() { @Override public int compare(Goods o1, Goods o2) { return o1.getName().compareTo(o2.getName()); } }); System.out.println(Arrays.toString(goods)); } }
4、两者对比
- Comparable接口的自然排序是永久性的。是让类实现了这个接口,那么这个类就一直拥有可排序的特性,随时可以对其对象进行排序。
- Comparator接口的定制排序是临时性的。只能用这一次。
五、其他常用类
1、System类
-
介绍
- System类代表系统,系统级的很多属性和控制方法都放置在该类的内部。 该类位于java.lang包。
- System类的构造器是private的,内部的成员变量和成员方法都是static的。所以可以直接
System.属性/方法
来方便的调用。
-
成员变量
- System类内部包含in、out和err三个成员变量,分别代表标准输入流 (键盘输入),标准输出流(显示器)和标准错误输出流(显示器)。
-
成员方法
-
native long currentTimeMillis()
:1970年1月1号0时0分0秒至今的毫秒数。 -
void exit(int status)
:该方法的作用是退出程序。其中status的值为0代表正常退出,非零代表 异常退出。使用该方法可以在图形界面编程中实现程序的退出功能等。 -
void gc()
:请求系统进行垃圾回收。至于系统是否立刻回收,则 取决于系统中垃圾回收算法的实现以及系统执行时的情况。 -
String getProperty(String key)
:获得系统中属性名为key的属性对应的值。系统中常见 的属性名以及属性的作用如下表所示
-
2、Math类
- 介绍:java.lang.Math提供了一系列静态方法用于科学计算。其方法的参数和返回值类型一般为double型
3、BigInteger类
-
引入:Integer类作为int的包装类,能存储的最大整型值为231 -1,Long类也是有限的, 最大为263 -1。如果要表示再大的整数,不管是基本数据类型还是他们的包装类 都无能为力,更不用说进行运算了。java.math包的BigInteger可以表示不可变的任意精度的整数。BigInteger 提供 所有 Java 的基本整数操作符的对应物,并提供 java.lang.Math 的所有相关方法。 另外,BigInteger 还提供以下运算:模算术、GCD 计算、质数测试、素数生成、 位操作以及一些其他操作。
-
构造器:
public BigInteger(String val)
:根据字符串构建BigInteger对象。 -
常用方法
4、BigDecimal类
- 引入:一般的Float类和Double类可以用来做科学计算或工程计算,但在商业计算中,要求数字精度比较高,故用到java.math.BigDecimal类。BigDecimal类支持不可变的、任意精度的有符号十进制定点数
- 构造器:
public BigDecimal(double val)
public BigDecimal(String val)
- 常用方法:同上