您的位置:首页 > 编程语言 > Java开发

Java 常用类总结(SE基础)

2021-04-27 21:23 831 查看

本篇博客对java常用类相关知识进行了归纳总结,比较详细,适用于学习和复习。

1. 字符串相关的类

1.1 String

String
是一个
final
类,代表不可变的字符序列。不可被继承。

String
对象的字符内容是存储在一个字节数组
byte[]
中。JDK1.8中存储的是
char[]
注意区别。

  • String
    实现了
    Serializable
    接口,支持序列化
  • 实现了
    Comparable
    接口,表示可以比较大小
  • 通过字面量的方式(区别于
    new
    )给一个
    String
    赋值,此时的字符串值在字符串常量池中(和方法区在同一个地方)
  • String
    进行连接操作、重新赋值、
    replace()
    等操作时,会重新指定内存区域赋值,不使用原有的
    value
    进行赋值
String str = "hello";  //字面量赋值
String s1 = new String();//本质上为,this.value = new byte[0]
String s2 = new String(String str); //放一个String类型的参数
String s3 = new String(byte[] a);
String s3 = new String(byte[] a,int off,int length);//构造方法,放char[]也是可以的

考虑如下代码:

String s1 = "javaEE";
String s2 = "javaEE";
String s3 = new String("javaEE");
String s4 = new String("javaEE");

这里,

s1==s2
true
s1==s3
,
s1==s4
,
s3==s4
均为
false

原因如下:

实际上,通过构造方法来构造

String
会指向
value
,而
value
再去指向字符串常量。

String s3 = new String("javaEE");
在内存中创建了两个对象:一个是堆中的
value
结构,一个是常量池中的字符串数据。

  • intern()
    返回字符串对象的规范表示。 这里会返回一个字符串常量。内存空间在常量池中。

另外,有一个关于形参实参方面的需要注意:

public class StringTest {
String str = new String("hello");
char[]ch = {'t','e','s','t'};

public void change(String str,char ch[]){
str = "hello,world";
ch[0]='b';
}

public static void main(String[] args) {
StringTest st = new StringTest();
st.change(st.str, st.ch);
System.out.println(st.str);
System.out.println(st.ch);
}
}

这里的结果为:"hello" /n "best"

类似于C语言中,根据指针进行交换两个指针中的内容,值传递过程中,实际参数的值传入形参,形成副本,方法结束后形参消失,实际参数值并没有改变。

另外还有一点需要注意:

String str = null; //这个指针指向null,并没有实例化
System.out.println(str);//输出”null“
System.out.println(str.length());//异常

1.2 String的常用方法

String
的常用方法总结如下(未总结的请自己查阅):

同时还需要注意的一些方法如下,重要程度依次降低,但仍需掌握:

注意:上表下部的4个

int
方法如果未找到,返回的均为-1

再举例一些方法(一些可能不太常用的):

String regex
一般都用正则表达式表示

String转换为基本数据类型或包装类

调用包装类的静态方法:对应的类型,如要转

int
,调用
Integer.parseInt(str)

基本数据类型、包装类转为String

调用

String
重载的
valueOf(xxx)

另外

int num = 100;
String str = num+"";  //存在变量才会返回堆中,如果常量相加则会返回常量池

这样也可以转换为

String
,但是需要注意,该类型是在堆中生成了
value
数组,和
new String
的方式类似。

String与char[], byte[]的相互转换

String
-->
char[]
:调用
String.toCharArray
即返回了一个
char[]

char[]或byte[] --> String
:直接调用构造器

String
-->
byte[]
:调用
String.getBytes
即返回了一个
byte[]
,使用默认的字符集(例如"gbk、utf-8"等)进行转换。

getBytes(Charset charset)
使用给定的
charset
将该
String
编码为字节序列,将结果存储到新的字节数组中。不同的编码方式返回的可能不同。

1.3 StringBuffer与StringBuilder

String
StringBuffer, StringBuilder
之间的异同?

String
:不可变的字符序列,注意理解不可变性

StringBuffer
: 56c 可变的字符序列,线程安全,效率较低(都是同步方法)

StringBuilder
:jdk5.0新增,可变的字符序列,线程不安全,效率高

final byte[] value  //String中的
byte[] value  //StringBuffer和StringBuilder中的

StringBuffer

String str = new String();// new char[0]
String str1 = new String("abc");//new char[] {'a','b','c'};

StringBuffer sb = new StringBuffer();//new char[16] 初始容量为16
sb.append('a');// value[0]='a';依次进行

StringBuffer sb1 = new StringBuffer("abc");//new char["abc".length()+16]
System.out.println(sb.length()); //return的是count,每append操作count+=len,这里为1,并不是value.length

接下来看

StringBuffer
的扩容机制

简述:一般情况下,若容量不够的时候,扩充为原来容量的2倍+2,同时将原有数组的元素复制到新数组中

JDK15中,源码已经改变,为:

private int newCapacity(int minCapacity) {
int oldLength = value.length;
int newLength = minCapacity << coder;
int growth = newLength - oldLength;
int length = ArraysSupport.newLength(oldLength, growth, oldLength + (2 << coder));
if (length == Integer.MAX_VALUE)
56c
{
throw new OutOfMemoryError("Required length exceeds implementation limit");
}
return length >> coder;
}

ArraysSupport.newLength
这里就是比较
growth
oldLength + (2 << coder)
谁大,大者加上
oldLength
(这样就成了2倍+2)。这里coder原始值为0,我只看了
append
相关源码,
coder
值并没有变,其他源码没有看,注意可能发生改变。

JDK1.8中是直接进行移位操作+2的,现版本已更新。

StringBuffer常用方法

StringBuilder
的API与之相同,只是线程不安全,没有保证同步。

2. 日期时间

2.1 JDK8之前的日期时间

java.lang.System
中的
static long currentTimeMillis()
返回当前时间与1970年1月1日00:00:00之间的时间差(以毫秒为单位)。适用于计算时间差。(时间戳)

计算世界时间的主要标准有:

UTC
,
GMT
,
CST

java.util.Date

java.sql
中也有一个
Date
类,是java.util.Date的子类

表示特定的时间,精确到毫秒

两个构造器的使用:

构造器一: 创建一个当前时间的

Date
对象

Date date = new Date();
System.out.println(date);//sout自带.toString,输出:Mon Apr 26 01:16:00 CST 2021
System.out.println(date.getTime());//返回当前date对象对应的时间戳

//Date中的无参构造源码
public Date() {
this(System.currentTimeMillis());
}

构造器二: 创建了一个指定时间的

Date
对象

Date date1 = new Date(1619371381884L); //随便找了个时间戳
System.out.println(date1);

构造器的其余方法均已过时,不建议使用。

java.sql.Date
对应的是数据库中的日期时间类,一般在数据库交互时使用

java.sql.Date date2 = new java.sql.Date(1619371381884L); //2021-04-26
System.out.println(date2);

该类没有无参构造。输出形式不同。

两种

Date
互转:

Date date3 = (Date)date2;  //子类转父类
System.out.println(date3);
java.sql.Date date4 = new java.sql.Date(new Date().getTime()); //父类转子类,不能强制类型转换
ad0

java.text.SimpleDateFormat

允许进行格式化:日期-->文本,解析:文本-->日期

格式化:

解析:

Date parse(String text,  ParsePosition pos)
从字符串中解析文本以产生一个
Date

pattern
举例如下图:

demo1默认模式

SimpleDateFormat sdf = new SimpleDateFormat();
Date date = new Date();
String format = sdf.format(date);
System.out.println(date); //Mon Apr 26 02:38:11 CST 2021
System.out.println(format); //2021/4/26 上午2:38

//解析过程
String str = "2021/4/16 上午12:38";  //格式有要求
Date date1 = sdf.parse(str);
System.out.println(date1); //Fri Apr 16 00:38:00 CST 2021

使用指定模式:

SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy,MM,dd HH:mm:ss aaa");
String str2 = sdf1.format(date);
System.out.println(str2); //2021,04,26 02:47:22 上午
//解析的话也需要按这种模式进行,正常模式通常为”yyyy-MM-dd hh:mm:ss“
String str3 ="2021,04,26 02:47:22 上午";
Date date2 = sdf1.parse(str3);
System.out.println(date2); //Mon Apr 26 02:47:22 CST 2021

Calendar

Calendar
是一个抽象类,主要用于完成日期字段之间的相互操作。

Calendar
提供了一种类方法
getInstance
,用于获取此类型的一般有用的对象。
Calendar
getInstance
方法返回一个
Calendar
对象,其日历字段已使用当前日期和时间进行初始化:

Calendar rightNow = Calendar.getInstance();
调用了它的子类
GregorianCalendar
的构造器

Calendar calendar = Calendar.getInstance();
System.out.println(calendar.getClass());//class java.util.GregorianCalendar

Calendar
对象可以产生实现特定语言和日历风格的日期时间格式化所需的所有日历字段值(例如日语 - 公历,日语 - 繁体)。
Calendar
定义某些日历字段返回的值的范围及其含义。 例如,日历系统第一个月的值为
MONTH == JANUARY
为所有日历。 其他值由具体的子类定义,如
ERA
。 有关详细信息,请参阅各个实体文档和子类文档。

常用方法:

void set(int field,  int v
1044
alue)
将给定的日历字段设置为给定的值。

void add(int field,  int amount)
根据日历的规则,将指定的时间量添加或减去给定的日历字段。

final Date getTime()
返回一个
Date
表示此物体
Calendar
的时间值

void setTime(Date date)
使用给定的
Date
设置此日历的时间

demo
如下:

Calendar calendar = Calendar.getInstance();
//get
int i = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(i);//获取这个月的第几天,本实例为26,当前时间4/26
System.out.println(calendar.get(Calendar.DAY_OF_YEAR));//类似上一个
//set
calendar.set(Calendar.DAY_OF_MONTH,12);
int j = calendar.get(Calendar.DAY_OF_MONTH);  //12,改变了
System.out.println(j);
//add
calendar.add(Calendar.DAY_OF_MONTH,3);
j = calendar.get(Calendar.DAY_OF_MONTH); //15,还是改变,增加3天
System.out.println(j);
//getTime
Date date = calendar.getTime(); //Thu Apr 15 03:10:28 CST 2021,返回时间戳
System.out.println(date);
//setTime:Date --> Calendar
calendar.setTime(date);//直接操作当前对象
int days = calendar.get(Calendar.DAY_OF_MONTH);  //15
System.out.println(days);

获取月份时,一月是0;获取星期几时,周日是1

2.2 JDK8中的日期时间

因为之前的类具有4个问题:

  • 可变性:例如
    Calendar
    set
    ,它们都是可变的
  • 偏移性:
    Date
    中的年份都是从1900开始,月份从0开始,如果调用有参构造,会发生偏移。
  • 格式化:格式化只对
    Date
    有用,对于
    Calendar
    则不行
  • 线程不安全

java8中的java.time API已经纠正了过去的缺陷。

时间日期的相关packge:

LocalDate
,
LocalTime
,
LocalDateTime
是其中比较重要的几个类,他们的实例均为不可变实例,使用
ISO-8601
日历系统。

ISO-8601
日历系统是国际标准话组织制定的现代公民的日期和时间的表示法(公历)

相关方法:

上面四个层次其实就是构造、get、set、加减操作。和

Calendar
类似。

localDate
是一个
final
类,有构造方法,类似
String
,
Math
,举例当前时间生成:

LocalDate localDate = LocalDate.now();  //2021-04-27
LocalTime localTime = LocalTime.now();  //19:24:37.171676500
LocalDateTime localDateTime = LocalDateTime.now();  //2021-04-27T19:24:37.171676500

举例设置指定时间:

LocalDateTime localDateTime1 = LocalDateTime.of(2020,10,6,13,12,13);//2020-10-06T13:12:13

举例相关

get
操作:

System.out.println(localDateTime.getMonth()); //APRIL
System.out.println(localDateTime.getMonthValue()); //4

这里的月份是从1开始的。

.with
操作(设置相关属性):

LocalDate localDate1 = localDate.withDayOfMonth(22); //2021-04-22
System.out.println(localDate);  //2021-04-27
System.out.println(localDate1);

locatDate
实例本身并没有发生变化(不可变性)。

加减操作:

LocalDate localDate2 = localDate.plusDays(4); //localDate为4-27
System.out.println(localDate2
25f4
);//2021-05-01
//减的话即将Plus换位minus

2.3 Instant(瞬时)

时间线上的一个瞬时点,可能用来记录应用程序中的事件时间戳。

同样是起始于1970年1月1日00:00:00的一个时间戳(纳秒级)。

相关方法:

时间标准主要有:UTC, GMT, CST,UTC时间与伦敦本地时间相同,与北京相差8个小时(早了8个小时)

Instant instant = Instant.now();
System.out.println(instant); //2021-04-27T11:45:00.321544Z,实际时间19:45,相差8个小时

偏移应用:

OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8));
System.out.println(offsetDateTime);  //2021-04-27T19:48:17.448368100+08:00

返回时间戳(毫秒数):

System.out.println(instant.toEpochMilli());//1619524168468

设置特定时间,和

Date
类似:

Instant instant1 = Instant.ofEpochMilli(1619524168468L);  //2021-04-27T11:49:28.468Z,这里的时间就是毫秒级的了
System.out.println(instant1);

2.4 DateTimeFormatter

三种预定义的标准格式:

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
//格式化:日期-->字符串
LocalDateTime localDateTime = LocalDateTime.now();
String str = dateTimeFormatter.format(localDateTime);  //将当前时间格式化
System.out.println(str); //2021-04-27T19:59:19.0153049

//解析:字符串-->日期
TemporalAccessor temporalAccessor = dateTimeFormatter.parse("2021-04-27T19:59:19.0153049");
System.out.println(temporalAccessor);//{},ISO resolved to 2021-04-27T19:59:19.015304900

本地化相关的格式:

DateTimeFormatter format = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);
//SHORT 2021/4/27 下午8:09,  MEDIUM  2021年4月27日 下午8:10:02,
// 在java15中LONG会异常,1.8不会,DateTime中没有FULL,Date中有
String str1 = format.format(localDateTime);
System.out.println(str1);

自定义格式(类似于

SimpleDateFormat
):

DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
String str1 = format.format(localDateTime); //2021-04-27 08:21:52
System.out.println(str1);
TemporalAccessor temporalAccessor1 = format.parse(str1);
System.out.println(temporalAccessor1);
//{MicroOfSecond=0, HourOfAmPm=8, MilliOfSecond=0, NanoOfSecond=0, MinuteOfHour=21, SecondOfMinute=52},ISO resolved to 2021-04-27

解析同上面即可,注意解析时需要一个

TemporalAccessor
转承。

其他的一些API(不再详细赘述):

以上三种

Date
之间的转换:

3. 比较器

这里牵扯到对象的比较

实现

Comparable
接口(自然排序),重写
compareTo()
方法,重写的规则是:当前对象this大于形参对象obj,返回正整数;this小于,返回负整数;this等于,返回0;

使用

Comparator
接口(定制排序)

适用于该类型没有实现

Comparable
接口,且不方便修改代码;或者实现了
Comparable
接口但是排序规则不适合当前操作

对比:

  • Comparable
    接口的方式可以保证类的对象在任何位置都可以实现比较
  • Comparator
    接口属于临时性的比较

关于应用在之前的博客中已有实现,可参考

(Set, Map, Collections工具类)JAVA集合框架二

4. System, Math, BigInteger 和 BigDecimal

4.1 System

java.lang.System

成员变量:in, out ,err三个,分别代表标准输入流(键盘输入),标准输出流(显示器),标准错误输出流(显示器)

static long currentTimeMillis()
返回当前时间(以毫秒为单位)。表达格式同时间戳。

static void exit(int status)
终止当前运行的Java虚拟机。
status
为0时代表正常退出,非零则为异常退出。

static void gc()
运行垃圾回收器。请求系统进行垃圾回收。

static String getProperty(String key)
获取指定键指示的系统属性。对于常用的
key

4.2 Math

以上为

Math
常用方法总结。可见开发文档。

4.3 BigInteger与BigDecimal

BigInteger

构造方法:

BigInteger
提供所有java的基本整数操作符的对应物,并提供
java.lang.Math
的所有相关方法,另外,还提供一下运算:模算术,GCD计算,质数测试,素数生成,位操作等。

BigDecimal

Float
Double
的精度不能满足用户需求时,可以使用
BigDecimal

构造方法:

BigDecimal(double val)
double
转换为
BigDecimal
,这是
double
的二进制浮点值的精确十进制表示。

BigDecimal(String val)
将BigDecimal的字符串表示
BigDecimal
转换为
BigDecimal

还有很多,只举例了两种常用的。

加减乘除操作类似于

BigInteger
,说明一下
devide

scale
即保留多少位小数,上下文设置用的不多不再赘述。

几种舍入模式:

其中,有些翻译不够准确,解释一下:

ROUND_UP
,即向上舍。0.1203456789,当精度为3的时候,按照
ROUND_UP
模式,结果是0.121

ROUND_DOWN
即向下舍。

ROUND_HALF_EVEN
,像邻近的偶数方向舍。

这几个可以参考对应英文进行理解。

4.4 个人总结的其他类

其实经常用到的还有

Ramdom
,生活中经常用到随机数。

例如取一个随机整数。

Random r1 = new Random();
int i = r1.nextInt(100); //取0到100的随机整数,无 100

其他方法都是与之类似的,具体可参考开发文档。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: