1.常用类和基础API
1.1 String类的理解
1.1.1 类的声明
- final:String不可被继承。
- Serializable:可序列化的接口。凡是实现此接口的类的对象就可以通过网络或本地流进行数据的传输。
- Comparable:凡是实现此接口的类,其对象都可以比较大小。
1.1.2 类内部声明的属性
JDK8中:private final char value[]; //存储字符串数据的容器
- final:指明此value数组一旦初始化,其地址不可变。
JDK9开始为了节省内存空间进行优化(将char改为byte):private final byte[] value; //存储字符串数据的容器
1.1.3 字符串常量的存储位置
- 字符串常量都存储在字符串常量池(StringTable)中。
- 字符串常量池不允许存放两个相同的字符串常量。
- 字符串常量池,在不同的JDK版本中存放的位置不同。
- JDK7之前存放在方法区。
- JDK7及之后存放在堆空间。
1.1.4 String的不可变性
- 当对字符串变量重新赋值时,需要重新指定一个字符串常量的位置进行赋值,不能在原有的位置进行修改。
- 当对现有字符串进行拼接操作时,需要重新开辟空间保存拼接以后的字符串,不能在原有位置进行修改。
- 当调用字符串的replace()替换现有的某个字符时,需要重新开辟空间保存修改以后的字符串,不能在原有位置进行修改。
1.1.5 String实例化的两种方式
- String s1 = “hello”;
- String s2 = new String(“hello”);
- 在内存中创建了两个对象,一个是堆空间中new的对象,另一个是在字符串常量池中生成的字面量。
1.1.6 String的连接操作
- 常量+常量:常量之间拼接和直接写拼接后的常量无区别,比如"helloworld"和"hello"+"world"地址相同。结果仍然存储在字符串常量池中。注意:此时的常量可能是字面量,也可能是final修饰的常量。
- 常量+变量或变量+变量:都会通过new的方式创建一个新的字符串,返回堆空间中此字符串对象的地址。
- 调用字符串的intern():返回的是字符串常量池中字面量的地址。
- concat(xxx):不管是常量还是变量调用该方法,同样不管参数是常量还是变量,调用完后都会返回一个新new的对象。
1.1.7 String的构造器
- public String() :初始化新创建的 String 对象,以使其表示空字符序列。
- public String(String original): 初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的副本。
- public String(char[] value) :通过当前参数中的字符数组来构造新的String。
- public String(char[] value,int offset, int count) :通过字符数组的一部分来构造新的 String。
- public String(byte[] bytes) :通过使用平台的默认字符集解码当前参数中的字节数组来构造新的 String。
- public String(byte[] bytes,String charsetName) :通过使用指定的字符集解码当前参数中的字节数组来构造新的 String。
1.1.8 String与常见的其他结构之间的转换
- String与基本数据类型、包装类之间的转换。
@Test
public void test2(){
int num = 10;
String s1 = num + "";
String s2 = String.valueOf(num);
String s3 = "123";
int i1 = Integer.parseInt(s3);
}
- String与char[]之间的转换
@Test
public void test3(){
String str = "hello";
char[] arr = str.toCharArray();
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
String str1 = new String(arr);
System.out.println(str1);
}
- String与byte[]之间的转换
@Test
public void test4() throws UnsupportedEncodingException {
String str = new String("abc张三");
byte[] arr = str.getBytes();
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
byte[] arr1 = str.getBytes("gbk");
for (int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i]);
}
String str1 = new String(arr);
System.out.println(str1);
String str2 = new String(arr, "utf-8");
System.out.println(str2);
}
1.1.9 String的常用方法
String 类包括的方法可用于检查序列的单个字符、比较字符串、搜索字符串、提取子字符串、创建字符串副本并将所有字符全部转换为大写或小写。
- boolean isEmpty():字符串是否为空。
- int length():返回字符串的长度。
- String concat(xx):拼接。
- boolean equals(Object obj):比较字符串是否相等,区分大小写。
- boolean equalsIgnoreCase(Object obj):比较字符串是否相等,不区分大小写 。
- int compareTo(String other):比较字符串大小,区分大小写,按照 Unicode 编码值比较大小。
- int compareToIgnoreCase(String other):比较字符串大小,不区分大小写。
- String toLowerCase():将字符串中大写字母转为小写。
- String toUpperCase():将字符串中小写字母转为大写。
- String trim():去掉字符串前后空白符。
- public String intern():结果在常量池中共享。
- boolean contains(xx):是否包含 xx。
- int indexOf(xx):从前往后找当前字符串中 xx,即如果有返回第一次出现的下标,要是没有返回-1。
- int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。
- int lastIndexOf(xx):从后往前找当前字符串中 xx,即如果有返回最后一次出现的下标,要是没有返回-1。
- int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。
- String substring(int beginIndex) :返回一个新的字符串,它是此字符串的从 beginIndex 开始截取到最后的一个子字符串。
- String substring(int beginIndex, int endIndex) :返回一个新字符串,它是此字符串从 beginIndex开始截取到 endIndex(不包含)的一个子字符串。
- char charAt(index):返回[index]位置的字符。
- char[] toCharArray(): 将此字符串转换为一个新的字符数组返回 。
- static String valueOf(char[] data) :返回指定数组中表示该字符序列的 String。
- static String valueOf(char[] data, int offset, int count) : 返回指定数组中表示该字符序列的 String。
- static String copyValueOf(char[] data): 返回指定数组中表示该字符序列的 String。
- static String copyValueOf(char[] data, int offset, int count):返回指定数组中表示该字符序列的 String。
- boolean startsWith(xx):测试此字符串是否以指定的前缀开始。
- boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始。
- boolean endsWith(xx):测试此字符串是否以指定的后缀结束。
- 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 替换此字符串匹配给定的正则表达式的第一个子字符串。
package p145;
import org.junit.Test;
public class StringTest {
@Test
public void test1(){
String str = "abcdefg";
String str1 = reverse(str, 2, 5);
System.out.println(str1);
}
public String reverse(String str,int l,int r){
char[] arr = str.toCharArray();
for (int i = l,j = r; i < j; i++,j--) {
char temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
return new String(arr);
}
public String reverse1(String str,int l,int r){
String finalStr = str.substring(0, l);
for (int i = r; i >= l; i--) {
finalStr += str.charAt(i);
}
finalStr += str.substring(r+1);
return finalStr;
}
}
public int findStr(String str1, String str2) {
int count = 0;
if (str1.length() >= str2.length()) {
int index = str1.indexOf(str2);
while (index >= 0) {
count++;
index = str1.indexOf(str2, index + str2.length());
}
}
return count;
}
1.2 StringBuffer和StringBuilder类
因为 String 对象是不可变对象,虽然可以共享常量对象,但是对于频繁字符串的修改和拼接操作,效率极低,空间消耗也比较高。因此,JDK 又在 java.lang包提供了可变字符序列 StringBuffer 和 StringBuilder 类型。
- java.lang.StringBuffer 代表可变的字符序列,JDK1.0 中声明,可以对字符串内容进行增删,此时不会产生新的对象。
- StringBuilder 和 StringBuffer 非常类似,均代表可变的字符序列,而且提供相关功能的方法也一样。
1.2.1 String、StringBuilder、StringBuffer的对比
- String:不可变的字符序列; 底层使用 char[]数组存储(JDK8.0 中)。
- StringBuffer:可变的字符序列;线程安全(方法有 synchronized 修饰),效率低;底层使用 char[]数组存储 (JDK8.0 中)。
- StringBuilder:可变的字符序列; jdk1.5 引入,线程不安全的,效率高;底层使用 char[]数组存储(JDK8.0 中)。
1.2.2 常用方法
- StringBuffer append(xx):提供了很多的 append()方法,用于进行字符串追加的方式拼接。
- StringBuffer delete(int start, int end):删除[start,end)之间字符。
- StringBuffer deleteCharAt(int index):删除[index]位置字符。
- StringBuffer replace(int start, int end, String str):替换[start,end)范围的字符序列为 str。
- void setCharAt(int index, char c):替换[index]位置字符。
- char charAt(int index):查找指定 index 位置上的字符。
- StringBuffer insert(int index, xx):在[index]位置插入 xx。
- int length():返回存储的字符数据的长度。
- StringBuffer reverse():反转。
- 当 append 和 insert 时,如果原来 value 数组长度不够,可扩容。
- 如上(1)(2)(3)(4)(9)这些方法支持方法链操作。
1.3 日期时间API(JDK8之前)
1.3.1 java.lang.System 类的方法
System 类提供的 public static long currentTimeMillis():用来返回当前时间与 1970 年
1 月 1 日 0 时 0 分 0 秒之间以毫秒为单位的时间差。
1.3.2 java.util.Date
- 构造器:
- Date():使用无参构造器创建的对象可以获取本地当前时间。
- Date(long 毫秒数):把该毫秒值换算成日期时间对象。
- 常用方法:
- 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 是时间标准。
1.3.3 java.text.SimpleDateFormat
java.text.SimpleDateFormat 类是一个不与语言环境有关的方式来格式化和解析日期的具体类。可以进行格式化(日期转为文本),可以进行解析(文本转为日期)。
- 构造器:
- SimpleDateFormat() :默认的模式和语言环境创建对象。
- public SimpleDateFormat(String pattern):该构造方法可以用参数 pattern指定的格式创建一个对象。
- 格式化:
- public String format(Date date):方法格式化时间对象 date。
- 解析:
- public Date parse(String source):从给定字符串的开始解析文本,以生成一个日期。
![Day11_第1张图片](http://img.e-com-net.com/image/info8/22fe35c58a3340e2b8f752dabb027407.jpg)
1.3.4 java.util.Calendar(日历)
Calendar 类是一个抽象类,主用用于完成日期字段之间相互操作的功能。获取 Calendar 实例的方法:使用Calendar.getInstance()方法。
一个 Calendar 的实例是系统时间的抽象表示,可以修改或获取 YEAR、MONTH、DAYOFWEEK、HOUROFDAY 、MINUTE、SECOND 等 日历字段对应的时间值。
- public int get(int field):返回给定日历字段的值。
- public void set(int field,int value) :将给定的日历字段设置为指定的值。
- public void add(int field,int amount):根据日历的规则,为给定的日历字段添加或者减去指定的时间量。
- public final Date getTime():将 Calendar 转成 Date 对象。
- public final void setTime(Date date):使用指定的 Date 对象重置 Calendar的时间。
public class Exer1 {
@Test
public void test1(){
Date date = new Date();
java.sql.Date date1 = new java.sql.Date(date.getTime());
}
}
1.4 日期时间API(JDK8中新增)
之前JDK8之前的日期时间API存在缺点:
- 可变性:日期时间类应该不可变。
- 偏移性:Date中的年份都是从1900开始,而月份都从0开始。
- 格式化:格式化只适用于Date,不适用于Calendar。
- 它们都不是线程安全的,不能处理闰秒等。
1.4.1 LocalDate、LocalTime、LocalDateTime
- 构造器:
- now()/now(ZoneId zone) 静态方法,根据当前时间创建对象/指定时区的对象。
- of(xx,xx,xx,xx,xx,xxx) 静态方法,根据指定日期/时间创建对象,不用考虑偏移量。
- 方法:
- getDayOfMonth()/getDayOfYear() 获得月份天数(1-31) /获得年份天数(1-366)。
- getDayOfWeek() 获得星期几(返回一个 DayOfWeek 枚举值)。
- getMonth() 获得月份, 返回一个 Month 枚举值。
- getMonthValue() / getYear() 获得月份(1-12) /获得年份。
- getHours()/getMinute()/getSecond() 获得当前对象对应的小时、分钟、秒。
- withDayOfMonth()/withDayOfYear()/withMonth()/withYear()将月份天数、年份天数、月份、年份修改为指定的值并返回新的对象。
- with(TemporalAdjuster t) 将当前日期时间设置为校对器指定的日期时间。
- plusDays(), plusWeeks(), plusMonths(), plusYears(),plusHours()向当前对象添加几天、几周、几个月、几年、几小时。
- minusMonths() / minusWeeks()/minusDays()/minusYears()/minusHours()从当前对象减去几月、几周、几天、几年、几小时。
- plus(TemporalAmount t)/minus(TemporalAmount t)添加或减少一个 Duration 或 Period。
- isBefore()/isAfter() 比较两个 LocalDate。
- isLeapYear() 判断是否是闰年(在 LocalDate 类中声明)。
- format(DateTimeFormatter t) 格式化本地日期、时间,返回一个字符串。
- parse(Charsequence text) 将指定格式的字符串解析为日期、时间。
1.4.2 瞬时Instant
Instant:时间线上的一个瞬时点。 这可能被用来记录应用程序中的事件时间戳。时间戳是指格林威治时间 1970 年 01 月 01 日 00 时 00 分 00 秒(北京时间1970 年 01 月 01 日 08 时 00 分 00 秒)起至现在的总秒数。
- 构造器:
- now() 静态方法,返回默认 UTC 时区的 Instant 类的对象。
- 方法:
- ofEpochMilli(long epochMilli)静态0.方法,返回在 1970-01-01 00:00:00 基础上加上指定毫秒数之后的 Instant 类的对象。
- atOffset(ZoneOffset offset)结合即时的偏移来创建一个 OffsetDateTime。
- toEpochMilli() 返回 1970-01-01 00:00:00 到当前时间的毫秒数,即为时间戳。
1.5 Java比较器
实现对象的排序,可以考虑两种方法:自然排序(Comparable)、定制排序(Comparator)。
1.5.1 自然排序(Comparable)
实现步骤:
- 具体的类A实现Comparable接口。
- 重写Comparable接口中的compareTo(Object obj)方法,在此方法中指明比较类A的对象的大小的标准。
- 创建类A的多个实例,进行大小的比较或排序。
1.5.2 定制排序(Comparator)
java.util.Comparator 接口。强行对多个对象进行整体排序的比较。
实现步骤:
- 创建一个实现了Comparator接口的实现类A。
- 实现类A要求重写Comparator接口中的抽象方法compare(Object o1,Object o2),在此方法中指明要比较大小的对象的大小关系。(比如,String类、Product类)。
- 创建此实现类A的对象,并将此对象传入相关方法的参数位置即可。(比如Arrays.sort(…,类A的实例))。
1.5.3 自然排序和定制排序的对比
- 角度一:
- 自然排序:单一的,唯一的。
- 定制排序:灵活的,多样的。
- 角度二:
- 角度三:
- 自然排序:对应的接口是Comparable,对应的抽象方法compareTo(Object obj)。
- 定制排序:对应的接口是Comparator,对应的抽象方法compare(Object obj1,Object obj2)。
1.6 System类
属性有out(标准输出流)、in(键盘输入)、error(错误输出流)。
- native long currentTimeMillis(): 该方法的作用是返回当前的计算机时间,时间的表达格式为当前计算机时间和 GMT 时间(格林威治时间)1970 年 1 月 1 号 0 时 0 分 0 秒所差的毫秒数。
- void exit(int status): 该方法的作用是退出程序。其中 status 的值为 0 代表正常退出,非零代表异常退出。使用该方法可以在图形界面编程中实现程序的退出功能等。
- void gc(): 该方法的作用是请求系统进行垃圾回收。至于系统是否立刻回收,则取决于系统中垃圾回收算法的实现以及系统执行时的情况。
- String getProperty(String key): 该方法的作用是获得系统中属性名为 key 的属性对应的值。系统中常见的属性名以及属性的作用如下表所示:
![Day11_第2张图片](http://img.e-com-net.com/image/info8/75cc173f2f5d4b2ea6685165bcb8eb4e.jpg)
1.7 Runtime类
- public static Runtime getRuntime(): 返回与当前 Java 应用程序相关的运行时对象。应用程序不能创建自己的 Runtime 类实例。
- public long totalMemory():返回 Java 虚拟机中初始化时的内存总量。此方法返回的值可能随时间的推移而变化,这取决于主机环境。默认为物理电脑内存的 1/64。
- public long maxMemory():返回 Java 虚拟机中最大程度能使用的内存总量。默认为物理电脑内存的 1/4。
- public long freeMemory():回 Java 虚拟机中的空闲内存量。调用 gc 方法可能导致 freeMemory 返回值的增加。
1.8 Math类
java.lang.Math 类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。类似这样的工具类,其所有方法均为静态方法,并且不会创建对象,调用起来非常简单。
1.9 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。
1.10 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):divisor 是除数,scale 指明保留几位小数roundingMode指明舍入模式(ROUNDUP :向上加 1、ROUNDDOWN :直接舍去、ROUNDHALFUP:四舍五入)。
1.11 Random类
用于产生随机数。
- boolean nextBoolean():返回下一个伪随机数,它是取自此随机数生成器序列的均匀分布的 boolean 值。
- void nextBytes(byte[] bytes):生成随机字节并将其置于用户提供的 byte 数组中。
- double nextDouble():返回下一个伪随机数,它是取自此随机数生成器序列的、在0.0 和 1.0 之间均匀分布的 double 值。
- float nextFloat():返回下一个伪随机数,它是取自此随机数生成器序列的、在0.0 和 1.0 之间均匀分布的 float 值。
- double nextGaussian():返回下一个伪随机数,它是取自此随机数生成器序列的、呈高斯(“正态”)分布的 double 值,其平均值是 0.0,标准差是 1.0。
- int nextInt():返回下一个伪随机数,它是此随机数生成器的序列中均匀分布的int 值。
- int nextInt(int n):返回一个伪随机数,它是取自此随机数生成器序列的、在 0(包括)和指定值(不包括)之间均匀分布的 int 值。
- long nextLong():返回下一个伪随机数,它是取自此随机数生成器序列的均匀分布的 long 值。