(易忘篇)java基础编程高级阶段2
本博客随笔主要记录本人学习过程中的知识,欢迎大家一同学习,有不对的地方很高兴读者能详细指出,感激不尽!
Java常用类
1、String类
String的不可变性
- 当对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的value进行赋值。
- 当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值。
- 当调用String的replace()方法修改指定字符或字符串时,也需要重新指定内存区域赋值。
String实例化的不同方式
- 代码举例
//通过字面量定义的方式:此时的s1和s2的数据javaEE声明在方法区中的字符串常量池中。
String s1 = "javaEE";
String s2 = "javaEE";
//通过new + 构造器的方式:此时的s3和s4保存的地址值,是数据在堆空间中开辟空间以后对应的地址值。
String s3 = new String("javaEE");
String s4 = new String("javaEE");
System.out.println(s1 == s2);//true
System.out.println(s1 == s3);//false
System.out.println(s1 == s4);//false
System.out.println(s3 == s4);//false
问题:
String s = new String("javaEE");方式创建对象,在内存中创建了几个对象?
两个:一个是堆空间中new结构,另一个是char[]对应的常量池中的数据:"javaEE"。
- 实例化过程的内存解析
常用方法
-
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):返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个子字符串;
-
String substring(int beginIndex, int endIndex):返回一个新字符串,它是此字符串从beginIndex开始截取到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与其它结构的转换
-
与基本数据类型、包装类之间的转换
String-->基本数据类型、包装类:调用包装类的静态方法parseXxx(str);
基本数据类型、包装类-->String:调用String重载的valueOf(xxx)。 -
与字符数组之间的转换
String-->char[]:调用String的toCharArray();
char[]-->String:调用String的构造器。 -
与字节数组之间的转换
编码:String --> byte[]:调用String的getBytes();
解码:byte[] --> String:调用String的构造器。
编码:字符串 -->字节 (看得懂 --->看不懂的二进制数据);
解码:编码的逆过程,字节 --> 字符串 (看不懂的二进制数据 ---> 看得懂。
说明:解码时,要求解码使用的字符集必须与编码时使用的字符集一致,否则会出现乱码。
@Test
public void test3() throws UnsupportedEncodingException {
String str1 = "abc123中国";
byte[] bytes = str1.getBytes();//使用默认的字符集,进行编码。
System.out.println(Arrays.toString(bytes));
byte[] gbks = str1.getBytes("gbk");//使用gbk字符集进行编码。
System.out.println(Arrays.toString(gbks));
System.out.println("******************");
String str2 = new String(bytes);//使用默认的字符集,进行解码。
System.out.println(str2);
String str3 = new String(gbks);
System.out.println(str3);//出现乱码。原因:编码集和解码集不一致!
String str4 = new String(gbks, "gbk");
System.out.println(str4);//没出现乱码。原因:编码集和解码集一致!
}
- 与StringBuffer、StringBuilder之间的转换
String -->StringBuffer、StringBuilder:调用StringBuffer、StringBuilder构造器
StringBuffer、StringBuilder -->String:①调用String构造器;②StringBuffer、StringBuilder的toString()
2、StringBuffer类和StringBuilder类
String、StringBuffer、StringBuilder三者的对比
- String:不可变的字符序列;底层使用char[]存储。
- StringBuffer:可变的字符序列;线程安全的,效率低;底层使用char[]存储。
- StringBuilder:可变的字符序列;线程不安全的,效率高;底层使用char[]存储。
StringBuffer、StringBuilder中的常用方法
- 增: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()
- 遍历:for() + charAt() / toString()
3、JDK 8之前日期时间API
获取系统当前时间:System类中的currentTimeMillis()
long time = System.currentTimeMillis();
//返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差。
//称为时间戳
System.out.println(time);
java.util.Date类与java.sql.Date类
@Test
public void test2(){
//构造器一:Date():创建一个对应当前时间的Date对象
Date date1 = new Date();
System.out.println(date1.toString());//Sat Feb 16 16:35:31 GMT+08:00 2019
System.out.println(date1.getTime());//1550306204104
//构造器二:创建指定毫秒数的Date对象
Date date2 = new Date(155030620410L);
System.out.println(date2.toString());
//创建java.sql.Date对象
java.sql.Date date3 = new java.sql.Date(35235325345L);
System.out.println(date3);//1971-02-13
//如何将java.util.Date对象转换为java.sql.Date对象
//情况一:
// Date date4 = new java.sql.Date(2343243242323L);
// java.sql.Date date5 = (java.sql.Date) date4;
//情况二:
Date date6 = new Date();
java.sql.Date date7 = new java.sql.Date(date6.getTime());
}
java.text.SimpleDataFormat类
-
两个操作:
1.1 格式化:日期 --->字符串
1.2 解析:格式化的逆过程,字符串 ---> 日期 -
SimpleDateFormat的实例化:new + 构造器
Calendar类:日历类、抽象类
//1.实例化
//方式一:创建其子类(GregorianCalendar的对象
//方式二:调用其静态方法getInstance()
Calendar calendar = Calendar.getInstance();
// System.out.println(calendar.getClass());
//2.常用方法
//get()
int days = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days);
System.out.println(calendar.get(Calendar.DAY_OF_YEAR));
//set()
//calendar可变性
calendar.set(Calendar.DAY_OF_MONTH,22);
days = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days);
//add()
calendar.add(Calendar.DAY_OF_MONTH,-3);
days = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days);
//getTime():日历类---> Date
Date date = calendar.getTime();
System.out.println(date);
//setTime():Date ---> 日历类
Date date1 = new Date();
calendar.setTime(date1);
days = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days);
4、JDK8中新日期时间API
本地日期、本地时间、本地日期时间的使用:LocalDate / LocalTime / LocalDateTime
- 说明:
LocalDateTime相较于LocalDate、LocalTime,使用频率要高,类似于Calendar。 - 常用方法:
时间点:Instant
- 说明:时间线上的一个瞬时点。 概念上讲,它只是简单的表示自1970年1月1日0时0分0秒(UTC开始的秒数。),类似于 java.util.Date类。
- 常用方法:
日期时间格式化类:DateTimeFormatter
- 说明:格式化或解析日期、时间,类似于SimpleDateFormat。
- 实例化方式:
- 预定义的标准格式。如:ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
- 本地化相关的格式。如:ofLocalizedDateTime(FormatStyle.LONG)
- 自定义的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)
- 常用方法:
5、Java比较器
- 自然排序:使用Comparable接口
说明:
- 像String、包装类等实现了Comparable接口,重写了compareTo(obj)方法,给出了比较两个对象大小的方式。
- 像String、包装类重写compareTo()方法以后,进行了从小到大的排列。
- 重写compareTo(obj)的规则:
如果当前对象this大于形参对象obj,则返回正整数,
如果当前对象this小于形参对象obj,则返回负整数,
如果当前对象this等于形参对象obj,则返回零。 - 对于自定义类来说,如果需要排序,我们可以让自定义类实现Comparable接口,重写compareTo(obj)方法。在compareTo(obj)方法中指明如何排序。
自定义类代码举例:
public class Goods implements Comparable{
private String name;
private double price;
//指明商品比较大小的方式:照价格从低到高排序,再照产品名称从高到低排序
@Override
public int compareTo(Object o) {
// System.out.println("**************");
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 0;
return -this.name.compareTo(goods.name);
}
//方式二:
// return Double.compare(this.price,goods.price);
}
// return 0;
throw new RuntimeException("传入的数据类型不一致!");
}
// getter、setter、toString()、构造器:省略
}
- 定制排序:使用Comparator接口
说明:
- 当元素的类型没实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用 Comparator 的对象来排序。
- 重写compare(Object o1,Object o2)方法,比较o1和o2的大小:
如果方法返回正整数,则表示o1大于o2;
如果返回0,表示相等;
返回负整数,表示o1小于o2。
代码举例:
Comparator com = 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("输入的数据类型不一致");
}
}
- 两种排序方式对比
- Comparable接口的方式一旦一定,保证Comparable接口实现类的对象在任何位置都可以比较大小。
- Comparator接口属于临时性的比较。