7、Java常用类
7、Java常用类
7.1 字符串相关的类
String
(JDK9底层改为byte[]存储)
String的定义:字符串,使用一对 “ ” 引起来表示。
String 是声明为final的,不可被继承。
String实现了Serializable接口:表示字符串是支持序列化的;
实现了Comparable接口:表示Strng可以比较大小String内部定义了 final char[] value 用于存储字符串数据
String:代表不可变的字符序列。简称:不可变性。
体现:a.当对字符串重新赋值时,需要重新指定内存区域赋值,不能使用原有的value进行赋值。
b.当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值;
c.当调用String的replace( ) 修改指定字符或字符串时,也需要重新指定内存区域赋值;通过字面量的方式
String str="xx"
(区别于new)给一个字符串赋值,此字符串值声明在 字符串常量池中。字符串常量池中 是不会存储相同内容的字符串的。
String的实例化与存放方式:
方式一:通过字面量定义的方式
String s1 = "xxx"
-- 字符串常量对象存储在 字符串常量池方式二:通过new+构造器的方式
String s3 = new String("xxx")
--- 字符串非常量对象 存储在堆中面试题:String s = new String("abc"); 方式创建对象,在内存中创建了几个对象?
两个,一个是 堆空间中new结构,
另一个是 char[]对应的常量池中的数据:"abc"

小结:
字符串的创建有两种方式,它们的本质都是 字符串常量池中的字符串
通过字面量定义的字符串,地址和value都相同;
通过非字面量(即new String)定义的字符串,地址(变成了堆中的对象地址)不同,但是value依旧是引用常量池中的value。三种拼接情况:
常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量。
只要其中有一个是变量,结果就在堆中
如果拼接的结果调用intern()方法,返回值就在常量池中
String s1 = "a"; String s2= "b"; String s3 = "a"+"b"; //常量 + 常量 --> 常量池 String s4 = "a" + s2; //常量 + 变量 --> 堆 String s5 = s1 + s2; //变量 + 变量 --> 堆 String s6 = (s1+s2).intern(); //(变量+变量).intern() -->常量池
String是不可变的引用类型:(基本数据类型传递值,引用类型传递地址)
面试题:调用chang( ) 后的str 与 ch的值:
public class StringTest { String str = new String("good"); char[] ch = { 't', 'e', 's', 't' }; public void change(String str, char ch[]) { str = "test ok";//字符串是不可变的, 字符常量池的good不会改变,会新增一个testok ch[0] = 'b'; } public static void main(String[] args) { StringTest ex = new StringTest(); ex.change(ex.str, ex.ch); System.out.print(ex.str);//---> str 仍然为good System.out.println(ex.ch);//---> ch 变为 best } }
String与其他类型的转换:
转基本类型,包装类
//String --》基本类型,包装类 .parseXxx(str); //基本类型,包装类 --》String String.valueOf(xxx);
转字符数组
.toCharArray(); //String --》 char[] new String(charArr); //char[] --》 String 调用String的构造器
转字节数组 (编码,解码)
//String --》 byte[] 可以自定义编码格式 getBytes("默认/gkd/utf8") .getBytes(); //byte[]--》String 解码格式要与编码一致 String(Arr,"默认/gdk") new String(byteArr);
String常用方法:
int length() :返回字符串的长度: return value.length
char charAt(int index): : 返回某索引处的字符return value[index]
boolean isEmpty() :判断是否是空字符串:return value.length == 0
String toLowerCase() :使用默认语言环境,将 String 中的所有字符转换为小写
String toUpperCase() :使用默认语言环境,将 String 中的所有字符转换为大写
String trim(): :返回字符串的副本,忽略前导空白和尾部空白
boolean equals(Object obj): :比较字符串的内容是否相同
boolean equalsIgnoreCase(String anotherString) :与equals方法类似,忽略大
小写
String concat(String str) :将指定字符串连接到此字符串的结尾。 等价于用“+”
int compareTo(String anotherString): :比较两个字符串的大小 (挨个字符比较),涉及到字符串排序
String substring(int beginIndex, int endIndex) : :左闭右开 [ ) boolean endsWith(String suffix): :测试此字符串是否以指定的后缀结束
boolean startsWith(String prefix): :测试此字符串是否以指定的前缀开始
boolean startsWith(String prefix, int toffset): :测试此字符串从指定索引开始的子字符串是否以指定前缀开始 boolean contains(CharSequence s) :当且仅当此字符串包含指定的 char 值序列时,返回 true
int indexOf(String str): :返回指定子字符串在此字符串中第一次出现处的索引
int indexOf(String str, int fromIndex): :返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
int lastIndexOf(String str): :返回指定子字符串在此字符串中最右边出现处的索引
int lastIndexOf(String str, int fromIndex): :返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
注:indexOf和lastIndexOf方法如果未找到都是返回-1 String replace(char oldChar, char newChar): :返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。
String replace(CharSequence target, CharSequence replacement):使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。
String replaceAll(String regex, String replacement) :使用给定的replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
String replaceFirst(String regex, String replacement) :使用给定的replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。 boolean matches(String regex): :告知此字符串是否匹配给定的正则表达式。
String[] split(String regex): :根据给定正则表达式的匹配拆分此字符串。
String[] split(String regex, int limit): :根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中。
可变字符串
面试高频:String,StringBuffer,StringBuilder 三者的异同?
String:不可变的字符序列;底层使用 final char[]存储 --不可变引用类型
StringBuffer:可变的字符序列;线程安全,效率低;底层使用 char[]存储 --可变引用
StringBuilder:可变的字符序列;线程不安全的,效率高(JDK5.0新增);底层使用char[]存储
源码分析:
--对于String:根据构造器参数创建对应字符数组 String str = new String(); //char[] value = new char[0]; String str1 = new String("ab"); //new char[]{'a','b'}; --对于StringBuffer与StringBuilder:会默认创建一个16大小的字符数组 StringBuffer sb1 = new StringBuffer(); //char[] value = new char[16] StringBuffer sb2 = new StringBuffer("abc");//new char["abc.length()"+16] “xx”+16 StringBuffer sb3 = new StringBUffer(5); //new char[5] 创建指定大小数组
可变字符串 可以自定义指定字符数组的容量
new StringBuffer(int capacity)
就算传入字符串,可变数组对象依旧会留出16个空间
new StringBuffer("abc")--》char[3+16]
可变字符串 会留出一个count变量来记录有效字符的个数
sb2.length()--》3
扩容问题:当要添加的数据底层数组盛不下时,(默认情况下)会把底层数组扩容 2倍+2,同时将原有数据复制到新数组中。
效率:StringBuilder > StringBuffer > String
StringBuffer常用方法:
append(xxx) 添加,返回本身
delete(int start, int end );
setCharAt(int n , char ch ) / replace(int start, int end ,String str ) 修改
charAt(int n )
insert(int offset , xxx)
length( )
reverse() 翻转
substring(int start,int end) 截取
7.2 日期时间API
JDK8之前
java.lang.System类
此方法适于计算时间差
//返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差---时间戳 long time = System.currentTimeMillis(); //静态方法
计算世界时间的主要标准有:
UTC(Coordinated Universal Time)
GMT(Greenwich Mean Time)
CST(Central Standard Time)
java.util.Date类(及其子类 java.sql.Date)
//1.构造器的使用: Date date1 = new Date(); //创建一个对应当前时间的Date对象 Date date2 = new Date(date1.getTime()); //创建指定毫秒数的Date对象 //2.两个方法的使用: toString(); //显示当前的年,月,日,时,分,秒 getTime(); //获取当前Date对象对应的毫秒数
- java.sql.Date 对应着数据库中的日期类型的变量
如何将java.util.Date 对象转化为 java.sql.Date对象? (父->子)
java.sql.Date date3 = new java.sql.Date( date1.getTime() ) --date1为 util.Date对象
java.text.SimpleDateFormat类
Date类的API不易于国际化,大部分被废弃了,java.text.SimpleDateFormat类是一个不与语言环境有关的方式来 格式化和解析 日期的具体类。
在实例格式化对象时,可以使用默认格式,也可以使用指定格式(一般用 "yyyy-MM-dd HH:mm:ss");
必须按照指定的格式进行 格式化 和 解析,否则报错。 new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ); .format( ); .parse( );
Date date = new Date(); SimpleDateFormat sdf1 = new SimpleDateFormat(); //默认格式化对象 sdf1.format(date); //日期 --> 字符串 sdf1.parse("年-月-日 上/下午xx:xx"); //字符串--> 日期 SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //指定格式对象
字符串 “2020-09-08” 转 java.sql.Date:
String strTime = "2020-09-08"; //1.创建指定格式的 SimpleDateFormat()对象, (按照指定格式)将字符串 转化为 Date SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); //2.将 字符串 转化为 java.util.Date 对象 --->.parse() Date date1 = sdf.parse( strTime ); //3.将 java.util.Date对象 转化为 java.sql.Date对象 --->.getTime() java.sql.Date Mydate = new java.sql.Date(date1.getTime());
java.util.Calendar( 抽象) 类
Calender是一个日历相关的类,用于完成日期字段之间相互操作的功能,可变性
Calender类具有许多日期相关的操作(操作本身),通常通过 Calender.getInstance()来实例化对象,
通过get(int field)方法来取得想要的时间信息 YEAR、MONTH、DAY_OF_WEEK、HOUR_OF_DAY 、MINUTE、SECOND(月份0-11,星期1-7)
//1.实例化 new GregorianCalendar(); //创建其子类对象 X Calender calender = Calender.getInstance(); //调用其静态方法getInstance() √ //2.常用方法 get(),set(),add(),getTime(),setTime() calender.get(Calender.DAY_OF_MONTH); calender.set(Calender.DAY_OF_MONTH,10); //可变性--改变了本身 calender.add(Calender.Day_OF_MONTH,-2); //Date <---> 日历类 Date date = calender.getTime(); //日历类 -->Date calender.setTime(date); //Date -->日历类
JDK8之后
问题:(1.0 Date --> 1.1 Calender 依旧存在 问题)
可变性:像日期和时间这样的类应该是不可变的。
偏移性:Date中的年份是从1900开始的,而月份都从0开始。 月份需要-1
格式化:格式化只对Date有用,Calendar则不行。
此外,它们也不是线程安全的;不能处理闰秒等。
java.time
LocalDate, LocalTime , LocalDateTime 类
创建对象
//now(): 获取当前的日期,时间,日期+时间 (静态方法),创建对象 LocalDate.now(); LocalTime.now(); LocalDateTime localDateTime = LocalDateTime.now(); //of(): 设置指定的 年,月,日,时,分,秒 (静态方法),创建对象 LocalDateTime localDateTime1 = LocalDateTime.of(2020,5,2,12,12,12);
getXxx( )
.getDayOfMonth(); //当月的第几天 .getDayOfWeek(); //星期的第几天 .getMonth(); //月(英文名) .getMonthValue(); //月(数字) .getMinuete(); //分钟
withXxx( ),plusXxx( ) ,minusXxx( ) 返回新对象, 体现不可变性
LocalDateTime localDateTime2 = localDateTime.withHorr(4); //修改后会返回一个新对象 withDayOfMonth()/withDayOfYear()/withMonth()/withYear() //修改为 plusDays(), plusWeeks(),plusMonths(), plusYears(),plusHours() //添加 minusMonths() / minusWeeks()/minusDays()/minusYears()/minusHours() //减少
Instant类(类似于Date类)
创建对象 (两个都是静态方法)
//now():获取UTC(本初子午线)对应的标准时间 Instant instant = Instant.now(); //ofEpochMilli(): 通过给定的毫秒数,获取Instant对象-->Date(long millis) Instant instant = Instant.ofEpochMilli(xxxL);
其他方法
//添加时间的偏移量 (东八区 +8) OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHors(8)); //toEpochMilli(): 获取时间戳(返回1970-01-01 00:00:00到当前时间的毫秒数) long milli = instant.toEpochMilli();
java.time.format.DateTimeFormatter类 (格式化与解析)
三种创建方式 (都是静态方法,常用 .ofPattern(“yyyy-MM-dd hh:mm:ss”) )
//1.预定义的标准格式 ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME DateTimeFormatter dtf = DateTimeFormatter.ISO_LOCAL_DATE_TIME; //2.本地化相关的格式 .ofLocalizedDateTime(FormatStyle.LONG) //3.自定义的格式 .ofPattern(“yyyy-MM-dd hh:mm:ss”)
格式化与解析 .format() .parse()
LocalDateTime date = LocalDateTime.now(); String strTime = dtf.format(date); //日期-->字符串 dtf.parse(strTime); //字符串-->日期
7.3 Java比较器
对于Java中的对象,正常情况下 只能比较 == 或 != ,而大小的比较 >,<
只存在于基本数据类型。 当我们需要对对象进行大小的比较时, 就需要使用到 Comparable 或 Compatator 中的任意一个接口
Comparable 接口:
- (自然排序)-- 长期的比较使用,使类拥有该功能。
对于String, 包装类等 都默认实现了Comparable接口,重写了compareTo(obj)方法,能够比较两对象的大小(默认从小到大排列)
重写compareTo(obj)的规则:
当前对象this > 形参对象obj,返回正整数
当前对象this < 形参对象obj,返回负整数
当前对象this = 形参对象obj,返回 0 对于自定义类,如果需要排序,可以让自定义类实现Comparable接口,重写compareTo()方法
class Goods implements Comparable{ int price; //商品价格 String name; //商品名称 puublic int compareTo(Object o){ //按价格从低到高排序,(价格一致按名称排序) if(o instanceof Goods){ Goods goods = (Goods)o; if(this.price > goods.price) return 1; else if(this.price < goods.price) return -1; else { //reutn 0; return -this.name.compareTo(goods.name); //加个- 变成从大到小排序 } }else{ throw new RuntimeException("传入参数类型有误!"); } } }
Comparator 接口:
- (定制排序)--- 临时性的比较,要用的时候 new 一个实现类.compare(a,b)
背景:当元素的类型没有实现java.lang.Comparable 接口而又不方便修改代码
或者实现了java.lang.Comparable 接口的排序规则不适合当前的操作,
那么可以考虑使用 Comparator 的对象来 排序。重写compare ( Object o1,Object o2 ) 方法,比较o1和o2的大小, (默认从小到大)
返回正整数,则o1 > o2
返回负整数,则o1 < o2
放回0,则o1=o2
Arrays.sort(all, new Comparator() { @Override public int compare(Object o1, Object o2) { Goods g1 = (Goods) o1; Goods g2 = (Goods) o2; return g1.getName().compareTo(g2.getName()); } });
7.5 其他常用类
System类
System类代表系统,系统级的很多属性和控制方法都放置在该类的内部。该类位于java.lang包。
由于该类的构造器是private的,所以无法创建该类的对象,也就是无法实例化该类。其内部的成员变量和成员方法都是static的,所以也可以很方便的进行调用。成员变量:
System类内部包含in、out和err三个成员变量,分别代表标准输入流(键盘输入),标准输出流(显示器)和标准错误输出流(显示器)。成员方法:
native long currentTimeMillis():返回时间戳
void exit(int status):退出程序(0正常退出 、非0异常退出) 一般在图形界面编程中使用
void gc():该方法的作用是请求系统进行垃圾回收。至于系统是否立刻回收,则取决于系统中垃圾回收算法的实现以及系统执行时的情况。
String getProperty(String key): :该方法的作用是获得系统中属性名为key的属性对应的值。
System.getProperty("java.version"); System.getProperty("java.home"); System.getProperty("os.name"); System.getProperty("os.version"); System.getProperty("user.name"); System.getProperty("user.home"); System.getProperty("user.dir");
Math类
java.lang.Math 提供了一系列静态方法用于 科学 计算。其 方法的参数和返回为 值类型一般为double 型。
abs 绝对值 acos,asin,atan,cos,sin,tan 三角函数 sqrt 平方根 pow(double a,doble b) a 的b 次幂 log 自然对数 exp e 为底指数 max(double a,double b) min(double a,double b) random() 返回0.0 到1.0 的随机数 long round(double a) double 型数据a 转换为long 型(四舍五入) toDegrees(double angrad) 弧度—> 角度 toRadians(double angdeg) 角度—> 弧度
BigInteger类
Integer类作为int的包装类,能存储的最大整型值为2^31 -1 ; Long类也是有限的,最大为2^63 -1。
java.math包的BigInteger 可以表示不可变的任意精度的整数。BigInteger 提供所有 Java 的基本整数操作符的对应物,并提供 java.lang.Math 的所有相关方法。
另外,BigInteger 还提供以下运算:模算术、GCD 计算、质数测试、素数生成、位操作以及一些其他操作。
//构造器 BigInteger(String val): 根据字符串构建BigInteger对象 //常用方法 public BigInteger abs():返回此 BigInteger 的绝对值的 BigInteger。 BigInteger add(BigInteger val) :返回其值为 (this + val) 的 BigInteger BigInteger subtract(BigInteger val) :返回其值为 (this - val) 的 BigInteger BigInteger multiply(BigInteger val) :返回其值为 (this * val) 的 BigInteger BigInteger divide(BigInteger val) :返回其值为 (this / val) 的 BigInteger。整数相除只保留整数部分。 BigInteger remainder(BigInteger val) :返回其值为 (this % val) 的 BigInteger。 BigInteger[] divideAndRemainder(BigInteger val):返回包含 (this / val) 后跟 (this % val) 的两个 BigInteger 的数组。 BigInteger pow(int exponent) :返回其值为 (this exponent ) 的 BigInteger。
BigDecimal类
一般的Float类和Double类可以用来做科学计算或工程计算,但在商业计算中,要求数字精度比较高,故用到java.math.BigDecimal类。
BigDecimal类支持不可变的、任意精度的有符号十进制定点数。
//构造器 public BigDecimal(double val) public BigDecimal(String val) //常用方法 public BigDecimal add(BigDecimal augend) public BigDecimal subtract(BigDecimal subtrahend) public BigDecimal multiply(BigDecimal multiplicand) //(被除数,指定精度,取整规则) public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现