Java常用类
字符串相关的类
String
String类代表字符串。 Java程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。
String是一个final
类,代表不可变的字符序列。不可以被继承。
字符串是常量 ,用双引号引起来表示。它们的值在创建之后不能更改。
String对象的字符内容是存储在一个字符数组value[]
中的。
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[]
/** Cache the hash code for the string */
private int hash ; // Default to 0
代码示例:
public class StringTest {
/**
*常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量 。
*只要其中有一个是变量,结果就在堆中。
*如果拼接的结果调用intern()方法,返回值就在常量池中。
*/
@Test
public void test3(){
String s1 = "javaEE";
String s2 = "hadoop";
String s3 = "javaEEhadoop";
String s4 = "javaEE" + "hadoop";
String s5 = s1 + "hadoop";
String s6 = "javaEE" + s2;
String s7 = s1 + s2;
System.out.println(s3 == s4); //true
System.out.println(s3 == s5); //false
System.out.println(s3 == s6); //false
System.out.println(s3 == s7); //false
System.out.println(s5 == s6); //false
System.out.println(s5 == s7); //false
System.out.println(s6 == s7); //false
String s8 = s5.intern(); //返回值得到的s8使用的常量值中已经存在的"javaEEhadoop"
System.out.println(s3 == s8); //true
}
/**
* String的实例化方式:
* 方式一:通过字面量定义的方法
* 方式二:通过new + 构造器的方式
*
* 面试题:String s = new String("abc");方法创建对象,在内存中创建了几个对象?
* 两个:一个是堆空间中new结构,另一个是char[]对应的常量池中的数据:"abc"
*/
@Test
public void test2(){
//通过字面量定义的方式:此时的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
Person p1 = new Person("Tom", 12);
Person p2 = new Person("Tom", 12);
System.out.println(p1.name.equals(p2.name)); //true
System.out.println(p1.name == p2.name); //true
p1.name = "Jerry";
System.out.println(p2.name); //Tom
}
/**
* String:字符串,使用一对""引起来表示
* 1.String是final的,不可被继承
* 2.String实现了Serializable接口:表示字符串是支持序列化的。
* 实现了Comparable接口:表示String可以比较大小。
* 3.String内部定义了final char[] value 用于存储字符串数据
* 4.String:代表不可变的字符序列。简称:不可变性
* 体现:1.当对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的value进行赋值。
* 2.当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值。
* 3.当调用String的replace()方法修改指定字符或字符串时,也需要重新指定内存区域。
* 5.通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串值声明在字符串常量池中。
* 6.字符串常量池中不会存储相同内容的字符串的。
*
*/
@Test
public void test1(){
String s1 = "abc";
String s2 = "abc";
s1 = "hello";
System.out.println(s1 == s2); //比较s1和s2的地址值
System.out.println(s1);
System.out.println(s2);
System.out.println("*************");
String s3 = "abc";
s3 += "def";
System.out.println(s3); //abcdef
System.out.println(s2); //abc
System.out.println("*************");
String s4 = "abc";
String s5 = s4.replace('a', 'm');
System.out.println(s4); //abc
System.out.println(s5); //mbc
}
}
补充:== 和equals
@Test
public void test3(){
String s1 = "abc";
String s2 = "abc";
System.out.println(s1.equals(s2)); //true
System.out.println(s1 == s2); //true
String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(str1.equals(str2)); //true
System.out.println(str1 == str2); //false
}
一道面试题
public class StringTest {
String str = new String("good");
char[] ch = {'t','e','s','t'};
public void change(String str,char ch[]){
str = "test ok";
ch[0] = 'b';
}
public static void main(String[] args) {
StringTest ex = new StringTest();
ex.change(ex.str,ex.ch);
System.out.println(ex.str); //good
System.out.println(ex.ch); //best
}
}
String常用的方法
public class StringMethodTest {
/**
* 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个,如果超过了,剩下的全部都放到最后一个元素中。
*
*/
@Test
public void test4(){
String str1 = "啦啦啦啊啊啊";
String str2 = str1.replace("啦", "略");
System.out.println(str1);
System.out.println(str2);
String str3 = str1.replace("啊啊", "嘿嘿");
System.out.println(str3);
String str = "12hello34world5java7891mysql456";
//将字符串中的数字替换成,,如果结果中开头和结构有,的话去掉。
String string = str.replaceAll("\\d+", ",").replaceAll("^,|,$","");
System.out.println(string);
str = "12345";
boolean matches = str.matches("\\d+");
System.out.println(matches);
String tel = "0571-565169676";
boolean result = tel.matches("0571-\\d{6,8}");
System.out.println(result);
System.out.println("**************");
str = "hello|world|java";
String[] strs = str.split("\\|");
for (int i = 0; i < strs.length; i++) {
System.out.println(strs[i]);
}
}
/**
* 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
*/
@Test
public void test3(){
String str1 = "helloworld";
boolean b1 = str1.endsWith("ld");
System.out.println(b1);//true
boolean b2 = str1.startsWith("He");
System.out.println(b2); //false
boolean b3 = str1.startsWith("ll", 2);
System.out.println(b3); //true
String str2 = "wo";
System.out.println(str1.contains(str2));
System.out.println(str1.indexOf("ow")); //如果没有返回-1
System.out.println(str1.indexOf("lo",5));//没有则返回-1
String str3 = "hellorworld";
System.out.println(str3.lastIndexOf("or"));
System.out.println(str3.lastIndexOf("or",6));
//什么情况下,indexOf(str)和lastIndexOf(str)返回值相同?
//情况一;存在唯一的一个str,情况二:不存在str
}
/**
* 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(不包含)的一个子字符串
*/
@Test
public void test2(){
String s1 = "HelloWorld";
String s2 = "helloWorld";
System.out.println(s1.equals(s2)); //false
System.out.println(s1.equalsIgnoreCase(s2)); //true
String s3 = "abc";
String s4 = s3.concat("def");
System.out.println(s4); //abcdef
String s5 = "abc";
String s6 = new String("abd");
System.out.println(s5.compareTo(s6)); //-1
String s7 = "啦啦啦嘿嘿嘿";
String s8 = s7.substring(2);
System.out.println(s7);
System.out.println(s8);
String s9 = s7.substring(2, 4); //左边包含,右边不包含
System.out.println(s9);
}
@Test
public void test1(){
String s1 = "HelloWorld";
System.out.println(s1.length()); //10
System.out.println(s1.charAt(0)); //h
System.out.println(s1.charAt(9)); //d
System.out.println(s1.isEmpty()); //false
String s2 = s1.toLowerCase();
System.out.println(s1); //s1是不可变的,仍然为原来的字符串
System.out.println(s2); //改成小写以后的字符串
String s3 = " he ll o world ";
String s4 = s3.trim();
System.out.println("-----" + s3 + "-----");
System.out.println("-----" + s4 + "-----");
}
}
String与基本数据类型转换
public class StringTest1 {
/**
* 复习:
* String与基本数据类型,包装类之间的转换
* String --> 基本数据类型,包装类:调用包装类的静态方法:parseXxx(str)
* 基本数据类型,包装类 --> String:调用String重载的valueOf(xxx)方法
*/
@Test
public void test1(){
String str1 = "123";
int num = Integer.parseInt(str1);
String str2 = String.valueOf(num); //"123"
String str3 = num + ""; //这样也可以将基本数据类型转为String
}
}
String与字符数组转换
package com.lalala.java5;
import org.junit.Test;
public class StringTest1 {
/**
* String与char[]之间的转换
* String --> char[]:调用String的toCharArray()
* char[] --> String:调用String的构造器
*/
@Test
public void test2(){
String str1 = "abc123";
char[] charArray = str1.toCharArray();
for (int i = 0; i < charArray.length; i++) {
System.out.println(charArray[i]);
}
char[] arr = {'h', 'e', 'l', 'l', 'o'};
String str2 = new String(arr);
System.out.println(str2);
}
}
String与字节数组转换
public class StringTest1 {
/**
* String与byte[]之间的转换
* 编码: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));//[97, 98, 99, 49, 50, 51, -28, -72, -83, -27, -101, -67]
byte[] gbks = str1.getBytes("gbk"); //使用gbk字符集,进行转换
System.out.println(Arrays.toString(gbks));
System.out.println("**********");
String str2 = new String(bytes); //使用默认的字符集,进行解码。
System.out.println(str2); //abc123中国
String str3 = new String(gbks);
System.out.println(str3); //出现乱码,原因:编码集和解码集不一致。
String str4 = new String(gbks, "gbk"); //没有出现乱码,原因:编码集和解码集一致。
System.out.println(str4);
}
}
String相关的题目
将一个字符串进行反转,将字符串中指定部分进行反转,比如"abcdefg"反转为"abfedcg"
import org.junit.Test;
public class demo05 {
/**
* 将一个字符串进行反转,将字符串中指定部分进行反转,比如"abcdefg"反转为"abfedcg"
*
* 方式一:转换为char[]
* @param str
* @param startIndex
* @param endIndex
* @return
*/
public String reverse(String str,int startIndex,int endIndex){
if (str != null){
char[] arr = str.toCharArray();
for (int x = startIndex,y = endIndex; x < y;x++,y-- ) {
char temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
return new String(arr);
}
return null;
}
//方式二:使用String的拼接
public String reverse1(String str, int startIndex, int endIndex){
if (str !=null){
String reverseStr = str.substring(0, startIndex);
for (int i = endIndex;i >= startIndex; i--){
reverseStr += str.charAt(i);
}
reverseStr += str.substring(endIndex+1);
return reverseStr;
}
return null;
}
//方式三:使用StringBuffer/StringBuilder替换String
public String reverse2(String str,int startIndex,int endIndex){
if (str != null){
StringBuilder builder = new StringBuilder(str.length());
//第一部分
builder.append(str.substring(0,startIndex));
for (int i = endIndex;i >= startIndex;i--){
builder.append(str.charAt(i));
}
builder.append(str.substring(endIndex+1));
return builder.toString();
}
return null;
}
@Test
public void testReverse(){
String str = "abcdefg";
String reverse = reverse1(str, 2, 5);
System.out.println(reverse);
}
}
获取一个字符串在另一个字符串中出现的次数
public class StringDemo1 {
/**
* 获取一个字符串在另一个字符串中出现的次数
* 比如:获取“ab”在“abkkcadkabkebfkabkskab”中出现的次数
*
* 获取subStr在mainStr中出现的次数
*/
public int getCount(String mainStr,String subStr){
int mainLength = mainStr.length();
int subLength = subStr.length();
int count = 0;
int index = 0;
if (mainLength >= subLength){
//方式一
// while((index = mainStr.indexOf(subStr)) != -1){
// count++;
// mainStr = mainStr.substring(index+subStr.length());
//
// }
//方式二:对方式一的改进
while((index = mainStr.indexOf(subStr,index))!=-1){
count++;
index +=subLength;
}
return count;
}else {
return 0;
}
}
@Test
public void testGetCount(){
String mainStr = "abkkcadkabkebfkabkskab";
String subStr = "ab";
int count = getCount(mainStr, subStr);
System.out.println(count);
}
}
获取两个字符串中最大相同子串
public class StringDemo2 {
/**
* 获取两个字符串中最大相同字串
* 比如:"abcwerthelloyuiodef" = "cvhellobnm"
* 提示:将短的那个串进行长度依次递减的字串与较长的串比较
*/
//前提:两个字符串中只有一个最大相同字串
public String getMaxSameString(String str1,String str2){
if (str1 != null && str2 != null){
String maxStr = (str1.length() >= str2.length()) ? str1 : str2;
String minStr = (str1.length() < str2.length()) ? str1 : str2;
int length = minStr.length();
for (int i = 0; i < length; i++){
for (int x = 0,y = length-i; y<=length; x++,y++){
String subStr = minStr.substring(x,y);
if (maxStr.contains(subStr)){
return subStr;
}
}
}
}
return null;
}
@Test
public void testGetMaxSameString(){
String str1 = "abcwerthelloyuiodef";
String str2 = "cvhellbnm";
String maxSameString = getMaxSameString(str1, str2);
System.out.println(maxSameString);
}
}
StringBuffer小题目
public class IDEADebug {
@Test
public void testStringBuffer(){
String str = null;
StringBuffer sb = new StringBuffer();
sb.append(str);
System.out.println(sb.length()); //4
System.out.println(sb);
StringBuffer sb1 = new StringBuffer(str); //抛异常NullPointerException
System.out.println(sb1);
}
}
StringBuffer和StringBuilder
StringBuffer类不同于String ,其对象必须使用构造器生成。有三个构造器:
- StringBuffer():初始容量为16的字符串缓冲区。
- StringBuffer(int size):构造指定容量的字符串缓冲区。
- StringBuffer(String str):将内容初始化为指定字符串内容
/**
* 关于StringBuffer和StringBuilder的使用
*/
public class StringBufferBuilderTest {
/**
* String,StringBuffer,StringBuilder三者的异同?
* String:不可变的字符序列,底层使用char[]存储
* StringBuffer:可变的字符序列,线程安全的,效率低。底层使用char[]存储
* StringBuilder:可变的字符序列,jdk5.0新增的,线程不安全的,效率高。底层使用char[]存储
*
* 源码分析:
* String str = new String(); //new char[0]
* String str1 = new String("abc"); //new char[]{'a','b','c'}
*
* StringBuffer sb1 = new StringBuffer(); //char[] value = new char[16];底层创建了一个长度是16的数组
* 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)
*/
@Test
public void test1(){
StringBuffer sb1 = new StringBuffer("abc");
sb1.setCharAt(0,'m');
System.out.println(sb1);
StringBuffer sb2 = new StringBuffer();
System.out.println(sb2.length());
}
}
StringBuffer类的常用方法
/**
* 关于StringBuffer和StringBuilder的使用
*/
public class StringBufferBuilderTest {
/**
* StringBuffer的常用方法
* StringBuffer append(xxx):提供了很多的append()方法 用于进行字符串拼接
* StringBuffer delete(int start,int end):删除指定位置的内容
* StringBuffer replace(int start, int end, String str):把 [start,end) 位置替换为str
* StringBuffer insert(int offset, xxx):在指定位置插入xxx
* StringBuffer reverse():把当前字符序列逆转
*
* public int indexOf(String str)
* public String substring(int start,int end):返回一个从start开始到end结束的左闭右开的子字符串。
* public int length()
* public char charAt(int n)
* public void setCharAt(int n ,char ch)
*/
@Test
public void test2(){
StringBuffer s1 = new StringBuffer("abc");
s1.append(1);
s1.append('1');
System.out.println(s1);
//s1.delete(2,4);
System.out.println(s1);
s1.replace(2,4,"hello");
System.out.println(s1);
s1.insert(2,false);
System.out.println(s1);
s1.reverse();
System.out.println(s1);
String s2 = s1.substring(1, 3);
System.out.println(s2);
}
}
日期与时间
JDK8之前日期时间API
(1)java.lang.System类
System类提供的public static long currentTimeMillis():用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差。
(2)java.util.Date类
表示特定的瞬间,精确到毫秒。
构造器:
- Date():使用无参构造器创建的对象可以获取本地当前时间。
- Date(long date)
常用方法:
- getTime():返回自1970年1月1日00:00:00GMT以来此Date对象表示的毫秒数。
- toString():把此Date对象转换为以下形式的String:dow mon dd hh:mm:ss zzz yyyy 其中:dow是一周中的某一天(Sun, Mon, Tue,Wed, Thu, Fri, Sat),zzz是时间标准。
/**
* JDK8之前日期和实际的API测试
*/
public class DateTimeTest {
/**
* java.util.Date类
* |---java.sql.Date类
* 1.两个构造器的使用
* 构造器一:Date():创建一个对应当前时间的Date对象
* 构造器二:创建指定毫秒数的Date对象
*
* 2.两个方法的使用
* toString():显示当前的年,月,日,时,分,秒
* getTime():获取当前Date对象对应的毫秒数。(时间戳)
*
* 3.java.sql.Date对应着数据库中的日期类型的变量。
* 如何实例化
* 如何将java.util.Date对象转换为java.sql.Date对象
*/
@Test
public void test2(){
//构造器一:Date():创建一个对应当前时间的Date对象
Date date1 = new Date();
System.out.println(date1.toString());
System.out.println(date1.getTime());
//构造器二:创建指定毫秒数的Date对象
Date date2 = new Date(1572867665603L);
System.out.println(date2.toString());
//创建java.sql.Date对象
java.sql.Date date3 = new java.sql.Date(1572868411817L);
System.out.println(date3); //2019-11-04
// 如何将java.util.Date对象转换为java.sql.Date对象
Date date6 = new Date();
java.sql.Date date7 = new java.sql.Date(date6.getTime());
}
@Test
public void test1(){
long time = System.currentTimeMillis();
//用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差。
System.out.println(time);
}
}
(3)java.text.SimpleDateFormat类
Date 类的 API 不易于国际化,大部分被废弃了,java.text.SimpleDateFormat类是一个不与语言环境有关的方式来格式化和解析日期的具体类。
它允许进行格式化:日期 --> 文本 、 解析:文本 --> 日期
格式化:
- SimpleDateFormat():默认的模式和语言环境创建对象
- public SimpleDateFormat(String pattern):该构造方法可以用参数 pattern 指定的格式创建一个对象
- public String format(Date date):格式化时间对象date
解析:
- public Date parse(String source) 从给定字符串的开始解析文本,以生成一个日期。
public class DateTimeTest {
/**
* SimpleDateFormat的使用:SimpleDateFormat对日期类的格式化和解析
*
* 1.两个操作:
* 1.1 格式化:日期 --> 字符串
* 1.2 解析:格式化的逆过程 字符串 --> 日期
*
* 2.SimpleDateFormat的实例化
*/
@Test
public void testSimpleDateFormat() throws ParseException {
//实例化SimpleDateFormat:使用默认的构造器
SimpleDateFormat sdf = new SimpleDateFormat();
//格式化:日期 -> 字符串
Date date = new Date();
System.out.println(date); //打印当前的时间:Tue Dec 10 11:17:49 CST 2019
String format = sdf.format(date);
System.out.println(format); //19-12-10 上午11:17
//解析:格式化的逆过程 字符串-> 日期
String str = "19-12-10 上午11:17";
Date date1 = sdf.parse(str);
System.out.println(date1);
//按照指定的方式格式化和解析:调用带参的构造器
System.out.println("********按照指定的方式格式化和解析:调用带参的构造器*********");
// SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyy.MMMMM.dd GGG hh:mm aaa");
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
//格式化
String format1 = sdf1.format(date);//2019-12-10 11:39:22
System.out.println(format1);
//解析:要求字符串必须是符合SimpleDateFormat识别的格式(通过构造器参数体现),否则抛异常
Date date2 = sdf1.parse("2020-12-10 11:39:22");
System.out.println(date2); //Thu Dec 10 11:39:22 CST 2020
}
/**
* 练习一:字符串"2020-12-10" 准换为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);
System.out.println(date); //Tue Sep 08 00:00:00 CST 2020
java.sql.Date birthDate = new java.sql.Date(date.getTime());
System.out.println(birthDate); //2020-09-08
}
}
(4)java.util.Calendar日历类
Calendar 是一个抽象基类,主用用于完成日期字段之间相互操作的功能。
获取 Calendar 实例的方法
- 使用
Calendar.getInstance()
方法。 - 调用它的子类
GregorianCalendar
的构造器。
/**
* Calendar日历类(抽象类)的使用
*/
@Test
public void testCalendar(){
//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.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);//当前的天数加3天,-3相当于减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);
}
JDK8中新日期时间API
新时间日期API:
- java.time:包含值对象的基础包
- java.time.chrono:提供对不同的日历系统的访问
- java.time.temporal:包括底层框架和扩展特性
- java.time.zone:包含时区支持的类
public class JDK8DateTimeTest {
@Test
public void testDate(){
//偏移量
Date date1 = new Date(2020-1900,12-1,10);
System.out.println(date1); //Thu Dec 10 00:00:00 CST 2020
}
/**
* LocalDate,LocalTime,LocalDateTime的使用
* 说明:
* 1.LocalDateTime相较于LocalDate,LocalTime使用频率要高
* 2.类似于Calendar
*/
@Test
public void test1(){
//now():获取当前的日期,时间,日期+时间
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDate);
System.out.println(localTime);
System.out.println(localDateTime);
//of():设置指定的年,月,日,时,分,秒。没有偏移量
LocalDateTime localDateTime1 = LocalDateTime.of(2020, 12, 11, 12, 13, 50);
System.out.println(localDateTime1); //2020-12-11T12:13:50
//getXxx():获取相关的属性
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());
//体现不可变性
//withXxx():设置相关的属性
LocalDateTime localDateTime2 = localDateTime.withDayOfMonth(22);
System.out.println(localDateTime);
System.out.println(localDateTime2);
LocalDateTime localDateTime3 = localDateTime.withHour(4);
System.out.println(localDateTime);
System.out.println(localDateTime3);
//不可变性 plusXxx():增加相关属性
LocalDateTime localDateTime4 = localDateTime.plusMonths(3);
System.out.println(localDateTime);
System.out.println(localDateTime4);
//减少相关属性
LocalDateTime localDateTime5 = localDateTime.minusDays(6);
System.out.println(localDateTime);
System.out.println(localDateTime5);
}
}
Instant
/**
*Instant的使用
* 类似于java.util.Date类
*/
@Test
public void test2(){
//now():获取本初子午线对应的标准时间
Instant instant = Instant.now();
System.out.println(instant); //2019-12-10T06:00:55.821Z
//添加时间的偏移量
OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8));
System.out.println(offsetDateTime);
//获取自1970年1月1日0时0分0秒(UTC)开始的毫秒数
long milli = instant.toEpochMilli();
System.out.println(milli);
//ofEpochMilli():通过给定的毫秒数,获取Instant实例 --> Date(long millis)
Instant instant1 = Instant.ofEpochMilli(1575958401536L);
System.out.println(instant1);
}
格式化与解析日期或时间
/**
* DateTimeFormatter:格式化或解析日期,时间
* 类似于SimpleDateFormat
*/
@Test
public void test3(){
//方式一:预定义的标准格式。如:ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
//格式化:日期->字符串
LocalDateTime localDateTime = LocalDateTime.now();
String str1 = formatter.format(localDateTime);
System.out.println(localDateTime);
System.out.println(str1); //2019-12-10T14:29:19.972
//解析:字符串->日期
TemporalAccessor parse = formatter.parse("2019-12-10T14:29:19.972");
System.out.println(parse);
//方式二:
// 本地化相关的格式。
// 如:ofLocalizedDateTime()
//FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT : 适用于LocalDateTime
DateTimeFormatter formatter1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG);
//格式化
String str2 = formatter1.format(localDateTime);
System.out.println(str2); //2019年12月10日 下午02时35分20秒
//本地化相关的格式。
// 如:ofLocalizedDate()
//FormatStyle.FULL / FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT :适用于LocalDate
DateTimeFormatter formatter2 = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM);
//格式化
String str3 = formatter2.format(LocalDate.now());
System.out.println(str3); //2019-12-10
//方式三:自定义的格式。如: ofPattern("yyyy MM dd hh:mm:ss")
DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("yyyy MM dd hh:mm:ss");
//格式化
String str4 = formatter3.format(LocalDateTime.now());
System.out.println(str4); //2019 12 10 02:51:10
//解析
TemporalAccessor accessor = formatter3.parse("2019 12 10 02:51:10");
System.out.println(accessor);
}
比较器
在 Java 中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比较问题。
Java 实现对象排序的方式有两种:
自然排序: java.lang.Comparable
定制排序: java.util.Comparator
方式一:自然排序:java.lang.Comparable
Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序。
实现Comparable的类必须实现 compareTo(Object obj) 方法,两个对象即通过 compareTo(Object obj) 方法的返回值来比较大小 。 如果当前对象 this 大于形参对象 obj 则返回正整数,如果当前对象 this 小于形参对象 obj 则返回负整数,如果当前对象 this 等于 形参对象 obj 则返回零 。
实现 Comparable 接口的对象列表(和数组)可以通过 Collections.sort 或Arrays.sort进行自动排序。实现此接口的对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器 。
对于类C的每一个e1和e2来说,当且仅当 e1.compareTo(e2) == 0 与 e1.equals(e2) 具有相同的 boolean 值时,类 C 的自然排序才叫做与 equals一致 。 建议(虽然不是必需的)最好使自然排序与 equals 一致 。
/**
* 说明:Java中的对象,正常情况下,只能进行比较:==或 !=。不能使用 > 或 < 的
* 在开发中我们需要对多个对象进行排序,如何实现:使用两个接口中的任何一个:Comparable或Comparator
*
* Comparable接口与Comparator的使用对比:
* Comparable接口的方式一旦指定,保证Comparable接口实现类的对象,在任何位置都可以比较大小
* Comparator接口属于临时性的比较
*/
public class CompareTest {
/**
* Comparable接口的使用举例
* 1.像String,包装类等实现了Comparable接口,重写了compareTo()方法,给出了比较两个对象大小的方式。
* 2.重写compareTo()的规则:
* 如果当前对象this大于形参对象obj,则返回正整数
* 如果当前对象this小于形参对象obj,则返回负整数
* 如果当前对象this等于形参对象obj,则返回零
* 3.对应自定义类如果需要排序,我们可以让自定义类实现Comparable接口,重写compareTo()方法
* 在compareTo()方法中指明如何排序
*
*/
@Test
public void test1(){
String[] arr = new String[]{"AA","CC","KK","MM","GG","JJ","DD"};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
}
@Test
public void test2(){
Goods[] arr = new Goods[4];
arr[0] = new Goods("xiaomiMouse", 34);
arr[1] = new Goods("lenovoMouse", 43);
arr[2] = new Goods("dellMouse", 12);
arr[3] = new Goods("huaweiMouse", 65);
arr[4] = new Goods("microsoftMouse", 43);
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
}
}
商品类:
/**
* 商品类
*/
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("传入的数据类型不一致!");
}
}
方式二:定制排序: java.util.Comparator
当元素的类型没有实现 java.lang.Comparable 接口而又不方便修改代码,或者实现了 java.lang.Comparable 接口的排序规则不适合当前的操作,那么可以考虑使用 Comparator 的对象来排序强行对多个对象进行整体排序的比较。
重写compare(Object o1,Object o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示 o1 大于 o2,如果返回0,表示相等;返回负整数,表示o1小于o2 。
可以将Comparator传递给 sort 方法(如 Collections.sort 或 Arrays.sort)从而允许在排序顺序上实现精确控制。
还可以使用Comparator来控制某些数据结构(如有序set或有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序。
/**
* 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<String>() {
//按照字符串从大到小的顺序排列
@Override
public int compare(String o1, String 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[5];
arr[0] = new Goods("xiaomiMouse", 34);
arr[1] = new Goods("lenovoMouse", 43);
arr[2] = new Goods("dellMouse", 12);
arr[3] = new Goods("huaweiMouse", 65);
arr[4] = 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));
}
System类
System类代表系统,系统级的很多属性和控制方法都放置在该类的内部。该类位于 java.lang 包
由于该类的构造器是 private 的,所以无法创建该类的对象,也就是无法实例化该类。其内部的 成员变量和成员方法都是 static的, 所以也可以很方便的进行调用。
成员变量
System 类内部包含 in 、 out 和 err 三个成员变量,分别代表标准输入流(键盘输入 ),标准输出流(显示器)和标准错误输出流(显示器)。
成员方法
native long currentTimeMillis()
该方法的作用是返回当前的计算机时间,时间的表达格式为当前计算机时间和 GMT 时间(格林威治时间)1970年1月1号0时0分0秒所差的毫秒数。
void exit(int status)
该方法的作用是退出程序。其中status的值为0代表正常退出,非零代表异常退出。使用该方法可以在图形界面编程中实现程序的退出功能等。
void gc()
该方法的作用是请求系统进行垃圾回收。至于系统是否立刻回收,则取决于系统中垃圾回收算法的实现以及系统执行时的情况。
String getProperty(String key)
该方法的作用是获得系统中属性名为 key 的属性对应的值。系统中常见的属性名以及属性的作用如下表所示:
属性名 | 属性说明 |
---|---|
java.version | java运行时环境版本 |
java.home | java安装目录 |
os.name | 操作系统的名称 |
os.version | 操作系统的版本 |
user.name | 用户的账户名称 |
user.home | 用户的主目录 |
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与BigDecimal
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)