JAVA常用类
一、String
String:字符串,使用一对""引起来表示。
1.String声明为final的,不可被继承
2.String实现了Serializable接口:表示字符串是支持序列化的。
实现了Comparable接口:表示String可以比较大小
3.String内部定义了final char[] value用于存储字符串数据
4.String:代表不可变的字符序列。简称:不可变性。
体现:1.当对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的value进行赋值。
2. 当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值。
3. 当调用String的replace()方法修改指定字符或字符串时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值。
5.通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串值声明在字符串常量池中。
6.字符串常量池中是不会存储相同内容的字符串的。
String的实例化方式:
方式一:通过字面量定义的方式
方式二:通过new + 构造器的方式
面试题:String s = new String("abc");方式创建对象,在内存中创建了几个对象?
两个:一个是堆空间中new结构,另一个是char[]对应的常量池中的数据:"abc"
结论:
1.常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量。
2.只要其中有一个是变量,结果就在堆中。
3.如果拼接的结果调用intern()方法,返回值就在常量池中
String常见算法题目
1.模拟一个trim方法,去除字符串两端的空格。
public static String myTrim ( String str) {
int start = 0 ;
int end = str. length ( ) - 1 ;
while ( start < end && str. charAt ( start) == ' ' ) {
start++ ;
}
while ( start < end && str. charAt ( end) == ' ' ) {
end-- ;
}
if ( start == end) {
return "" ;
}
return str. substring ( start, end + 1 ) ;
}
2.将一个字符串进行反转。将字符串中指定部分进行反转。 比如:将abcdefg 反转为 abfedcg
方式一
public static String reverseString ( String str, int start, int end) {
char [ ] c = str. toCharArray ( ) ;
for ( int i = start, j = end; i < j; i++ , j-- ) {
char temp = c[ i] ;
c[ i] = c[ j] ;
c[ j] = temp;
}
return new String ( c) ;
}
方式二
public static String reverseString1 ( String str, int start, int end) {
String str1 = str. substring ( 0 , start) ;
for ( int i = end; i >= start; i-- ) {
char c = str. charAt ( i) ;
str1 += c;
}
str1 += str. substring ( end + 1 ) ;
return str1;
}
方式三(使用StringBuilder)
public static String reverseString3 ( String str, int start, int end) {
StringBuilder builder = new StringBuilder ( str. length ( ) ) ;
builder. append ( str. substring ( 0 , start) ) ;
for ( int i = end; i >= start; i-- ) {
builder. append ( str. charAt ( i) ) ;
}
builder. append ( str. substring ( end + 1 ) ) ;
return builder. toString ( ) ;
}
3.获取一个字符串在另一个字符串中出现的次数。 比如:获取“ab在abkkcadkabkebfkabkskab”中出现的次数
方式一
public static int getTime ( String str1, String str2) {
int count = 0 ;
int len;
while ( ( len = str1. indexOf ( str2) ) != - 1 ) {
count++ ;
str1 = str1. substring ( len + str2. length ( ) ) ;
}
return count;
}
方式二
public static int getTime2 ( String str1, String str2) {
int count = 0 ;
int i = 0 ;
while ( ( i = str1. indexOf ( str2, i) ) != - 1 ) {
count++ ;
i+= str2. length ( ) ;
}
return count;
}
4.获取两个字符串中最大相同子串。 比如:str1 = “abcwerthelloyuiodef”; str2 = “cvhellobnm”; 提示:将短的那个串进行长度依次递减的子串与较长的串比较。
提示:将短的那个串进行长度依次递减的子串与较长的串比较。
import java. util. *;
public static List< String> getMaxSubString ( String str1, String str2) {
String maxStr = ( str1. length ( ) > str2. length ( ) ) ? str1 : str2;
String minStr = ( str1. length ( ) < str2. length ( ) ) ? str1 : str2;
int len = minStr. length ( ) ;
List< String> list = new ArrayList < > ( ) ;
for ( int i = 0 ; i < len; i++ ) {
for ( int x = 0 , y = len - i; y <= len; x++ , y++ ) {
String str = minStr. substring ( x, y) ;
if ( maxStr. contains ( str) ) {
list. add ( str) ;
}
}
if ( list. size ( ) != 0 ) {
return list;
}
}
return null;
}
5.对字符串中字符进行自然顺序排序。
提示:
1.字符串变成字符数组。
2.对数组排序,选择,冒泡 Arrays.sort
3.将排序后的数组变成字符串。
import java. util. *;
public static String sort ( String str) {
char [ ] c = str. toCharArray ( ) ;
Arrays. sort ( c) ;
return new String ( c) ;
}
二、StringBuffer和StringBuilder
String、StringBuffer、StringBuilder三者的异同?
String:不可变的字符序列;底层使用char[]存储
StringBuffer:可变的字符序列;线程安全的,效率低;底层使用char[]存储
StringBuilder:可变的字符序列;jdk5.0新增的,线程不安全的,效率高;底层使用char[]存储
源码分析:
String str = new String();//char[] value = new char[0];
String str1 = new String("abc");//char[] value = new char[]{'a','b','c'};
StringBuffer sb1 = new StringBuffer();//char[] value = new char[16];底层创建了一个长度是16的数组。
System.out.println(sb1.length());//
sb1.append('a');//value[0] = 'a';
sb1.append('b');//value[1] = 'b';
StringBuffer sb2 = new StringBuffer("abc");//char[] value = new char["abc".length() + 16];
//问题1. System.out.println(sb2.length());//3
//问题2. 扩容问题:如果要添加的数据底层数组盛不下了,那就需要扩容底层的数组。
默认情况下,扩容为原来容量的2倍 + 2,同时将原有数组中的元素复制到新的数组中。
指导意义:开发中建议大家使用:StringBuffer(int capacity) 或 StringBuilder(int capacity)
对比String、StringBuffer、StringBuilder三者的效率:
从高到低排列:StringBuilder > StringBuffer > String
三、日期与时间
练习一:字符串"2020-09-08"转换为java.sql.Date
@Test
public void testExer ( ) throws ParseException {
String birth = "2020-09-08" ;
SimpleDateFormat sdf1 = new SimpleDateFormat ( "yyyy-MM-dd" ) ;
Date date = sdf1. parse ( birth) ;
java. sql. Date birthDate = new java. sql. Date ( date. getTime ( ) ) ;
System. out. println ( birthDate) ;
}
练习二:“三天打渔两天晒网”
public static String Test ( String startDate, String endDate) throws ParseException {
SimpleDateFormat startSDF = new SimpleDateFormat ( "yyyy-MM-dd" ) ;
SimpleDateFormat endSDF = new SimpleDateFormat ( "yyyy-MM-dd" ) ;
Date date1 = startSDF. parse ( startDate) ;
Date date2 = endSDF. parse ( endDate) ;
long time1 = date1. getTime ( ) ;
long time2 = date2. getTime ( ) ;
int day = ( int ) ( ( ( ( time2 - time1) / 1000 ) / 60 ) / 60 ) / 24 + 1 ;
int i = day % 5 ;
if ( i == 1 || i == 2 || i == 3 ) {
return "打渔" ;
} else if ( i == 4 || i == 0 ) {
return "晒网" ;
}
return null;
}
四、Calendar日历类(抽象类)
@Test
public void testCalendar ( ) {
Calendar calendar = Calendar. getInstance ( ) ;
int days = calendar. get ( Calendar. DAY_OF_MONTH) ;
System. out. println ( days) ;
System. out. println ( calendar. get ( Calendar. DAY_OF_YEAR) ) ;
calendar. set ( Calendar. DAY_OF_MONTH, 22 ) ;
days = calendar. get ( Calendar. DAY_OF_MONTH) ;
System. out. println ( days) ;
calendar. add ( Calendar. DAY_OF_MONTH, - 3 ) ;
days = calendar. get ( Calendar. DAY_OF_MONTH) ;
System. out. println ( days) ;
Date date = calendar. getTime ( ) ;
System. out. println ( date) ;
Date date1 = new Date ( ) ;
calendar. setTime ( date1) ;
days = calendar. get ( Calendar. DAY_OF_MONTH) ;
System. out. println ( days) ;
}
五、JDK8中的日期时间API
Calendar 并不比 Date 好多少,它们面临的问题是:
可变性:像日期和时间这样的类应该是不可变的。
偏移性:Date中的年份是从 1900 开始的,而月份都从0开始。
格式化:格式化只对Date有用,Calendar则不行。
此外,它们也不是线程安全的;不能处理闰秒等。
LocalDate、LocalTime、LocalDateTime 的使用
说明:
1.LocalDateTime相较于LocalDate、LocalTime,使用频率要高
2.类似于Calendar
@Test
public void JDK8DateTimeTest ( ) {
LocalDate localDate = LocalDate. now ( ) ;
LocalTime localTime = LocalTime. now ( ) ;
LocalDateTime localDateTime = LocalDateTime. now ( ) ;
System. out. println ( localDate) ;
System. out. println ( localTime) ;
System. out. println ( localDateTime) ;
LocalDateTime localDateTime1 = LocalDateTime. of ( 2020 , 10 , 6 , 13 , 23 , 43 ) ;
System. out. println ( localDateTime1) ;
System. out. println ( localDateTime. getDayOfMonth ( ) ) ;
System. out. println ( localDateTime. getDayOfWeek ( ) ) ;
System. out. println ( localDateTime. getMonth ( ) ) ;
System. out. println ( localDateTime. getMonthValue ( ) ) ;
System. out. println ( localDateTime. getMinute ( ) ) ;
LocalDate localDate1 = localDate. withDayOfMonth ( 22 ) ;
System. out. println ( localDate) ;
System. out. println ( localDate1) ;
LocalDateTime localDateTime2 = localDateTime. withHour ( 4 ) ;
System. out. println ( localDateTime) ;
System. out. println ( localDateTime2) ;
LocalDateTime localDateTime3 = localDateTime. plusMonths ( 3 ) ;
System. out. println ( localDateTime) ;
System. out. println ( localDateTime3) ;
LocalDateTime localDateTime4 = localDateTime. minusDays ( 6 ) ;
System. out. println ( localDateTime) ;
System. out. println ( localDateTime4) ;
}
瞬时:Instant
Instant:时间线上的一个瞬时点。这可能被用来记录应用程序中的事件时间戳。
Instant的使用类似于 java.util.Date类
@Test
public void instantTest ( ) {
Instant instant = Instant. now ( ) ;
System. out. println ( instant) ;
OffsetDateTime offsetDateTime = instant. atOffset ( ZoneOffset. ofHours ( 8 ) ) ;
System. out. println ( offsetDateTime) ;
long milli = instant. toEpochMilli ( ) ;
System. out. println ( milli) ;
Instant instant1 = Instant. ofEpochMilli ( 1550475314878 L) ;
System. out. println ( instant1) ;
}
格式化与解析日期或时间:DateTimeFormatter
DateTimeFormatter:格式化或解析日期、时间,类似于SimpleDateFormat
@Test
public void DateTimeFormatterTest ( ) {
DateTimeFormatter formatter = DateTimeFormatter. ISO_LOCAL_DATE_TIME;
LocalDateTime localDateTime = LocalDateTime. now ( ) ;
String str1 = formatter. format ( localDateTime) ;
System. out. println ( localDateTime) ;
System. out. println ( str1) ;
TemporalAccessor parse = formatter. parse ( "2019-02-18T15:42:18.797" ) ;
System. out. println ( parse) ;
DateTimeFormatter formatter1 = DateTimeFormatter. ofLocalizedDateTime ( FormatStyle. SHORT) ;
String str2 = formatter1. format ( localDateTime) ;
System. out. println ( str2) ;
DateTimeFormatter formatter2 = DateTimeFormatter. ofLocalizedDate ( FormatStyle. FULL) ;
String str3 = formatter2. format ( LocalDate. now ( ) ) ;
System. out. println ( str3) ;
DateTimeFormatter formatter3 = DateTimeFormatter. ofPattern ( "yyyy-MM-dd hh:mm:ss" ) ;
String str4 = formatter3. format ( LocalDateTime. now ( ) ) ;
System. out. println ( str4) ;
TemporalAccessor accessor = formatter3. parse ( "2019-02-18 03:52:09" ) ;
System. out. println ( accessor) ;
}
六、Java比较器
一、说明:Java中的对象,正常情况下,只能进行比较:== 或 != 。不能使用 > 或 < 的
但是在开发场景中,我们需要对多个对象进行排序,言外之意,就需要比较对象的大小。
如何实现?使用两个接口中的任何一个:Comparable 或 Comparator
二、Comparable接口与Comparator的使用的对比:
Comparable接口的方式一旦一定,保证Comparable接口实现类的对象在任何位置都可以比较大小。
Comparator接口属于临时性的比较。
方式一:自然排序:java.lang.Comparable
Comparable接口的使用举例:自然排序
1.像String、包装类等实现了Comparable接口,重写了compareTo(obj)方法,给出了比较两个对象大小的方式。
2.像String、包装类重写compareTo()方法以后,进行了从小到大的排列
3.重写compareTo(obj)的规则:
如果当前对象this大于形参对象obj,则返回正整数,
如果当前对象this小于形参对象obj,则返回负整数,
如果当前对象this等于形参对象obj,则返回零。
4. 对于自定义类来说,如果需要排序,我们可以让自定义类实现Comparable接口,重写compareTo(obj)方法。
在compareTo(obj)方法中指明如何排序
@Test
public void test1 ( ) {
String[ ] arr = new String [ ] { "AA" , "CC" , "KK" , "MM" , "GG" , "JJ" , "DD" } ;
Arrays. sort ( arr) ;
System. out. println ( Arrays. toString ( arr) ) ;
}
Goods.java
public class Goods implements Comparable {
private String name;
private double price;
public Goods ( ) {
}
public Goods ( String name, double price) {
this . name = name;
this . price = price;
}
public String getName ( ) {
return name;
}
public void setName ( String name) {
this . name = name;
}
public double getPrice ( ) {
return price;
}
public void setPrice ( double price) {
this . price = price;
}
@Override
public String toString ( ) {
return "Goods{" + "name='" + name + '\'' + ", price=" + price + '}' ;
}
@Override
public 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 {
return - this . name. compareTo ( goods. name) ;
}
}
throw new RuntimeException ( "传入的数据类型不一致!" ) ;
}
}
@Test
public void test2 ( ) {
Goods[ ] arr = new Goods [ 5 ] ;
arr[ 0 ] = new Goods ( "lenovoMouse" , 34 ) ;
arr[ 1 ] = new Goods ( "dellMouse" , 43 ) ;
arr[ 2 ] = new Goods ( "xiaomiMouse" , 12 ) ;
arr[ 3 ] = new Goods ( "huaweiMouse" , 65 ) ;
arr[ 4 ] = new Goods ( "microsoftMouse" , 43 ) ;
Arrays. sort ( arr) ;
System. out. println ( Arrays. toString ( arr) ) ;
}
方式二:定制排序:java.util.Comparator
Comparator接口的使用:定制排序
1.背景:
当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,
或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,
那么可以考虑使用 Comparator 的对象来排序
2.重写compare(Object o1,Object o2)方法,比较o1和o2的大小:
如果方法返回正整数,则表示o1大于o2;
如果返回0,表示相等;
返回负整数,表示o1小于o2。
@Test
public void test3 ( ) {
String[ ] arr = new String [ ] { "AA" , "CC" , "KK" , "MM" , "GG" , "JJ" , "DD" } ;
Arrays. sort ( arr, new Comparator ( ) {
@Override
public int compare ( Object o1, Object o2) {
if ( o1 instanceof String && o2 instanceof String ) {
String s1 = ( String) o1;
String s2 = ( String) o2;
return - s1. compareTo ( s2) ;
}
throw new RuntimeException ( "输入的数据类型不一致" ) ;
}
} ) ;
System. out. println ( Arrays. toString ( arr) ) ;
}
@Test
public void test4 ( ) {
Goods[ ] arr = new Goods [ 6 ] ;
arr[ 0 ] = new Goods ( "lenovoMouse" , 34 ) ;
arr[ 1 ] = new Goods ( "dellMouse" , 43 ) ;
arr[ 2 ] = new Goods ( "xiaomiMouse" , 12 ) ;
arr[ 3 ] = new Goods ( "huaweiMouse" , 65 ) ;
arr[ 4 ] = new Goods ( "huaweiMouse" , 224 ) ;
arr[ 5 ] = new Goods ( "microsoftMouse" , 43 ) ;
Arrays. sort ( arr, new Comparator ( ) {
@Override
public int compare ( Object o1, Object o2) {
if ( o1 instanceof Goods && o2 instanceof Goods ) {
Goods g1 = ( Goods) o1;
Goods g2 = ( Goods) o2;
if ( g1. getName ( ) . equals ( g2. getName ( ) ) ) {
return - Double. compare ( g1. getPrice ( ) , g2. getPrice ( ) ) ;
} else {
return g1. getName ( ) . compareTo ( g2. getName ( ) ) ;
}
}
throw new RuntimeException ( "输入的数据类型不一致" ) ;
}
} ) ;
System. out. println ( Arrays. toString ( arr) ) ;
}
七、其他常用类
1.System
2.Math
3.BigInteger 和 BigDecimal