一、包的概念
当前情况下:所有的类都是直接写在src中的
1、 存在的问题:
1、在src中有很多的类,不利于查找
2、团队开发中如果不同功能模块存在同名的类,则不能在同一个目录中共存
(即在同一个目录中不能存在同名的文件)
1、包的作用
(1)解决命名冲突问题,在指定一个类的类名的同时,指定一个包名
语法:
package 包名;
注意:
A.package语句一定要放在类声明的第一句话
B.package语句在一个类中只能有一个(因为包本质其实就是文件目录,所以对于一个文件而言,它只能属于一个目录,因此不能出现多条package语句)
(2)可以将功能相似或相近的类放在一个包中,方便组织和维护
(3)包可以具有层次结构,可以将类的划分的尺度更细,按照功能、模块等可以将类组织在不同的包中
(4)限定了包级别的访问权限
2、包的命名规范
回顾:
一切命名都不要用拼音
A.变量:见名知意、驼峰命名法
B.方法:见名知意、驼峰命名法、使用动词或动词词组、参数不宜超过4个
C.类名:见名知意、首字母大写,其余遵循驼峰命名法
D.static final常量:
/**
* 常量类:
* 常量:固定的值,无法修改的值
*/
public class AppConstant {
/**静态常量的命名中,所有字母全部大写**/
/**
* 如果常量名由多个单词构成,每个单词之间使用_隔开,即蛇形命名法
**/
public static final String ACCESS_TOKEN = "12345678";
public static final String[] strs = new String[2];
public static void main(String[] args) {
//静态常量体现了static的特性,即可以通过类名直接访问
System.out.println(AppConstant.ACCESS_TOKEN);
//静态常量也体现了final的特性,即不能就行修改
//AppConstant.token = "123";
System.out.println(AppConstant.ACCESS_TOKEN);
//strs[0]="Hello"修改的是数组在堆内存中下标为0的元素对应的值
//strs=new String[3];相当于将原来的strs的地址进行了改变,而strs是以final修饰的,所以无法改变
strs[0] = "Hello";
// strs=new String[3];
}
public void method() {
/**
* 对于一些变化不大的定值,如果直接写在代码中,不利于维护,称为“魔鬼数字”,简称“魔数”
* 可以将这些值直接定义为常量,调用过程中如果值发生了变化,只需要修改常量的直就行了
*/
System.out.println("token:" + ACCESS_TOKEN);
System.out.println("token:" + ACCESS_TOKEN);
}
public void method1() {
System.out.println("token:" + ACCESS_TOKEN);
System.out.println("token:" + ACCESS_TOKEN);
}
}
包的命名规范:
(1)包可以有层次结构,通过点儿去分割包的名字来形成包的层次结构
(2)包中的所有字母全部小写,不能出现关键字和保留字
(3)包的命名通常包含:域名反写+项目名+模块
3、包的导入
(1)为什么要导入
因为在一个类中,要使用另外一个包中提供的类,此时就要导入这个包
(2)语法:
import 包名+类名;
注意:
a.import语句出现在包声明之后,类声明之前
b.所有java.lang包下的类是自动导入的,无需手动导入
c.也可以通过全局限定名(包名+类名)来导入类,可以省略import语句,但是太麻烦。
java.util.Scanner sc = new java.util.Scanner(System.in);
//java.util.Date
Date date1 = new Date();
//java.sql.Date
//如果要使用不同包下的同名类,则应该指定全局限定名
java.sql.Date date2 = new java.sql.Date(123);
d.不要通过*导入一个包下所有的类,例如
import java.util.*;
要用什么类就导入什么类
二、常用类
1.math 类
对于Math类而言,其构造方法是私有的,所以不能通过new进行实例化操作
math的常用方法
System.out.println(Math.PI);
System.out.println(Math.E);
//方法:和数学相关的方法
System.out.println("取绝对值:");
System.out.println(Math.abs(-1));
System.out.println(Math.abs(1));
System.out.println(Math.abs(0));
System.out.println("求最大值:");
System.out.println(Math.max(2, 5));
System.out.println(Math.max(4, 3));
System.out.println(Math.max(Math.max(4, 3), 6));
System.out.println("求最小值:");
System.out.println(Math.min(2, 5));
System.out.println(Math.min(4, 3));
System.out.println("向下取整:");
System.out.println(Math.floor(3.1));
System.out.println(Math.floor(3.9));
System.out.println(Math.floor(-4.5));
System.out.println(Math.floor(0));
System.out.println("向上取整:");
System.out.println(Math.ceil(3.1));
System.out.println(Math.ceil(3.9));
System.out.println(Math.ceil(-4.5));
System.out.println(Math.ceil(0));
System.out.println("四舍五入,相当于Math.floor(X+0.5)");
System.out.println(Math.round(3.1));
System.out.println(Math.round(3.5));
//面试题:floor、ceil、round三者的区别?
System.out.println("乘方运算,第一个参数是底数,第二个参数是指数,都是double类型的参数:");
System.out.println(Math.pow(2, 3));
System.out.println(Math.pow(5, 2));
System.out.println("算数平方根:");
System.out.println(Math.sqrt(25));
//思考:如何求27的立方根?
System.out.println(Math.pow(27, 1.0 / 3));
System.out.println("生成0-1之间的随机小数:");
System.out.println(Math.random());
2.random类
Random r = new Random();
//返回一个随机的布尔值
System.out.println(r.nextBoolean());
//返回0-1之间的随机小数
System.out.println(r.nextDouble());
//返回long数据类型范围中的一个随机整数
System.out.println(r.nextLong());
//返回int数据类型范围中的一个随机整数
System.out.println(r.nextInt());
for (int i = 1; i <= 100; i++) {
//返回[0,N-1]中的一个随机值
System.out.print(r.nextInt(5) + "\t");
if (i % 10 == 0) {
System.out.println();
}
}
3、String
String类型:用来在Java中描述任意一段文本
//String类型对象的创建
//1.字面量创建方式
//String是Java中为数不多可以通过等号直接赋值的数据类型
String str1 = "Hello";
//2.通过new来进行创建
String str2 = new String("Hello");
System.out.println(str1);
System.out.println(str2);
// //面试题:==比较和equals比较的区别?
// int a=1;
// int b=1;
// System.out.println(a==b);
//==比较的其实是栈内存中的值,对于基本类型而言比较的就是当前变量的值
//但是对于引用类型而言,比较的是两个对象在内存中的地址是否相同
System.out.println(str1 == str2);
//String类型中的equals方法比较的其实是两个字符串对应的字符数组中每一个字符
//是否都对应相等,如果有某一个字符不相等,则两个字符串就不相等
System.out.println(str1.equals(str2));
Emp e1 = new Emp("Tom");
Emp e2 = new Emp("Tom");
//两个Emp对象都是new出来的对象,所以栈内存中存储的地址一定不相同
System.out.println(e1 == e2);
//Emp中没有定义equals方法,但是可以访问equals方法
//原因:因为Java中存在一个名为Object的类,该类是所有引用类型的顶级父类
//因此可以在任意引用类型中访问equals方法。
//String中对equals方法进行了重写,所以字符串的比较其实调用的是String中
//对父类equals进行重写后的版本
//子类如果没有重写equals方法,则默认调用Object类中的equals方法,
//而Object类中equals的比较逻辑就是根据==进行比较的
//如果在自定义类型中需要制定equals比较的逻辑,可以通过工具自动生成
System.out.println(e1.equals(e2));
class Emp {
private String ename;
public Emp(String ename) {
this.ename = ename;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Emp emp = (Emp) o;
return Objects.equals(ename, emp.ename);
}
}
==比较和equals比较
常量池原理
池:用来减少对象创建的次数,提高运行效率
String中的常量池:
当我们以字面量的方式直接创建字符串对象时,如果常量池中没有这个字符串对象,则会在常量池中新建这个字符串对象,如果下一次又写出了和前面一样的字面量,则该次操作不会创建新的字符串对象,而是直接从常量池中将已有的字符串对象取出来进行使用。如果String对象是通过new进行构建的,则该对象直接存储在堆内存中常量池以外的区域里,所以new出来的对象一定是新的对象。
注意:双方若不都是字面量或常量,则拼接出来的结果也不在常量池中
- 关于引用类型打印出来的内容:
引用类型变量在打印的过程中,其打印出来的内容格式,由类中的toString()方法来决定,而toString()方法是Object类中的方法,如果一个类中没有重写toString()方法,则默认以Object类中提供的打印方式进行打印,即打印出对象的“完整类名@十六进制的内存地址“,所以为了在打印对象的过程中能够看清对象的内容,因此通常情况下可以重写类的toString()方法。
int length()
// Java字符串在内存中使用unicode编码方式,任何一个字符(无论中文还是英文)对应两个字节的定长编码,算1个字符长度。
//注意:数组长度是length属性,字符串长度是length方法
String str = "I can because I can";
System.out.println(str.length());
//int indexOf(String str)
//在字符串中检索str,返回其第一次出现的位置,如果找不到则返回-1,(位置从0开始数)
System.out.println(str.indexOf("can"));
//可以通过返回值来判断字符串中是否包含给定子字符串,如果没有则返回-1
System.out.println(str.indexOf("CAN"));
//int indexOf(String str,int fromIndex)
//从字符串str的fromIndex开始检索,返回该位置起str第一次出现的位置,找不到返回-1
System.out.println(str.indexOf("can", 6));
System.out.println(str.indexOf("CAN", 6));
//int lastIndexOf(String str)
//str在字符串中多次出现时,返回最后一个出现的位置, 如果找不到,则返回-1
System.out.println(str.lastIndexOf("can"));
//char charAt(int index)
//用于返回字符串指定位置的字符,参数index表示指定位置(index从0开始)
char c = str.charAt(3);
System.out.println(c);
//最大下标为length()-1,超过下标出现越界异常
// c=str.charAt(100);
// System.out.println(c);
//String subString(int beginIndex,int endIndex)
//返回字符串从下标beginIndex(包括)开始到endIndex(不包括)结束的子字符串
//endIndex-beginIndex=截取到的字符串长度
System.out.println(str.substring(3, 7));
//String subString(int beginIndex)
//返回字符串从下标beginIndex(包括)开始到字符串结尾的子字符串
System.out.println(str.substring(7));
//String concat(String str)
//与+一样,都可以连接字符串,区别在于+相当于String 类对+运算符进行了重载,+前后可以是任何类型的值,但是concat只能是字 符串之间进行连接
//注意:该方法不会改变原来字符串的内容!
//面试题:+连接和concat连接的区别
//+可以连接任何数据类型
//concat只能连接String类型
String str1 = "hello";
String str2 = str1.concat(" world");
System.out.println(str2);
//String trim()
//去除字符串首尾的空字符(换行符和制表符都是空字符)
//注意:只能去除首位的空字符
System.out.println(" 123 4567 89 \t\n".trim());
System.out.println("11111");
//boolean equalsIgnoreCase(String anotherString)
//忽略大小写进行字符串的比较
System.out.println("HeLLo".equalsIgnoreCase("HEllo"));
str = "Today is sunny day";
//boolean startsWith(String str)
//判断字符串是否以str打头
System.out.println(str.startsWith("Today"));
//boolean endsWith(String str)
//判断字符串是否以str结尾
System.out.println(str.endsWith("ay"));
//String toUpperCase(String str)
//将字符串转换为全大写
System.out.println("heLlO worLd".toUpperCase());
// String toLowerCase(String str)
// 将字符串转换为全小写
System.out.println("heLlO worLd".toLowerCase());
//String valueOf();
//String类的静态方法,可以直接String.valueOf();可以将其他类型(基本类型)转换为字符串类型
//+:(1)算数运算(2)拼接字符串
//System.out.println(1+2+3+"1"+5+6);
//通过加空字符串使其他类型变成字符串类型
// int a = 1;
// String aStr = a + "";
//通过String.valueOf方法也可以将其他类型转换为字符串类型
System.out.println(String.valueOf(2.0));
//对于基本数据类型而言,参数的传递方式为值传递
//此处局部变量的a在栈内存中占据一块空间
int a = 1;
System.out.println("a=" + a);
//方法调用时,形式参数a也会占据一块栈内存空间
//随着方法调用结束,参数对应的空间会被释放,方法内对a的修改其实修改的是形式参数a中的值,并非局部变量a对应的值
method01(a);
System.out.println("a=" + a);
System.out.println("=========================");
String str = "Hello";
System.out.println("str=" + str);
method02(str);
System.out.println("str=" + str);
System.out.println("=========================");
//对于数组类型而言,由于是引用类型,所以使用的是引用传递
int[] arr = {1, 3, 4};
System.out.println("arr[2]=" + arr[2]);
//当调用方法时,其实传递的是局部变量数组的引用地址,
//形式参数接收到这个引用后,方法内部其实进行操作的这个数组的引用即局部变量对应的这个数组引用
method03(arr);
System.out.println("arr[2]=" + arr[2]);
}
public static void method01(int a) {
a = 3;
}
/**
* 由于String的内容不可改变,一旦改变以后就会产生新的对象,根据引用传递的特性
* 方法的形式参数尽管可以得到原来局部变量的引用,但是如果在方法中对字符串的值进行修改,此时就会产生新的str对象
* 所以方法中的 str = "world";和局部变量中的str="Hello";不是同一个对象,因此没有影响
*
* @param str
*/
public static void method02(String str) {
//得到的是一个和局部变量不同的新对象
str = "world";
}
public static void method03(int[] arr) {
arr[2] = 1;
}
}
**
* 当我们以字面量的方式直接创建字符串对象时,如果常量池中没有这个字符串对象,
* 则会在常量池中新建这个字符串对象,如果下一次又写出了和前面一样的字面量,
* 则该次操作不会创建新的字符串对象,而是直接从常量池中将已有的字符串对象取出来进行使用。
* 如果String对象是通过new进行构建的,则该对象直接存储在堆内存中常量池以外的区域里,
* 所以new出来的对象一定是新的对象。
* 注意:双方若不都是字面量或常量,则拼接出来的结果也不在常量池中
*/
public class Demo04 {
private static String str = "Hello";
private static String str1 = "Hel";
private static String str2 = "lo";
private static final String str3 = "Hello";
private static final String str4 = "Hel";
private static final String str5 = "lo";
public static void main(String[] args) {
String s1 = "Hel";
String s2 = "lo";
System.out.println("Hello" == "Hel" + "lo");//true,两个字面量拼接
System.out.println("Hello" == str);//true
System.out.println("Hello" == str3);//true
System.out.println("Hello" == str4 + str5);//true,常量+常量
System.out.println("Hello" == s1 + s2);//false,变量+变量
System.out.println("Hello" == str1 + str2);//false,静态变量+静态变量
System.out.println("Hello" == "Hel" + s2);//false,字面量+变量
System.out.println("Hello" == "Hel" + str5);//true,字面量+常量
System.out.println("Hello" == new String("Hel") + "lo");//false,堆内存中的对象+字面量!=常量池
System.out.println("Hello" == str4 + s2);//false,常量+变量
System.out.println("Hello" == str1 + str5);//false,静态变量+常量
}
}
4、StringBuilder 和 StringBuffer
package com.sy.apidemo.stringbuilder;
/**
* StringBuilder和StringBuffer
* 由于JDK中的String类型是不可变的,所以当字符串中内容
* 发生变化的时候,会产生大量的字符串对象,对内存造成一定
* 的压力,而StringBuilder和StringBuffer采用了在底层封装
* 可变字符串的对象,可以在对字符串内容修改的同时保证
* 不会产生大量的字符串对象
* <p>
* 因为StringBuilder用的较多,所以以StringBuilder为例,
* 两者的用法几乎一样
*/
public class Demo01 {
public static void main(String[] args) {
//1.StringBuilder对象的创建
//创建一个空的可变字符串对象,里面没有内容
StringBuilder sb = new StringBuilder();
//创建一个带有默认内容的可变字符串对象
//StringBuilder sb1=new StringBuilder("Hello");
//append(String str)
//用于追加字符串
sb.append("Hello");
sb.append(" World");
System.out.println(sb);
//insert(int dstOffset,String s);
//插入字符串,dstOffset索引之前插入s
sb.insert(2, "Java");
System.out.println(sb);
//delete(int start,int end);
//删除字符串,删除从start(包含)开始到end(不包含)结束的字符串
sb.delete(2, 6);
System.out.println(sb);
//replace(int start,int end,String str);
//替换字符串,替换从start(包含)开始到end(不包含)结束的字符串为s
sb.replace(0, 5, "Hi");
System.out.println(sb);
//reverse();
//反转字符串
sb.reverse();
System.out.println(sb);
//char charAt(int index);
//返回指定位置上的字符
char c = sb.charAt(2);
System.out.println(c);
//void setCharAt(int index,char c);
//将指定索引上的字符设置为字符c
sb.setCharAt(3, 'O');
System.out.println(sb);
/**
* 引用类型变量在打印的过程中,其打印出来的内容格式,
* 由类中的toString()方法来决定,而toString()方法是Object类中的方法,
* 如果一个类中没有重写toString()方法,则默认以Object类中提供的打印
* 方式进行打印,即打印出对象的“完整类名@十六进制的内存地址“,
* 所以为了在打印对象的过程中能够看清对象的内容,因此通常情况下可以
* 重写类的toString()方法。
*/
// Employee e1 = new Employee();
// e1.setName("Tom");
// System.out.println(e1);
}
}
class Employee {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
'}';
}
}
package com.sy.apidemo.stringbuilder;
/**
* StringBuilder的使用技巧
*/
public class Demo02 {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
//链式调用,因为StringBuilder中几乎所有方法都返回this
//即当前对象本身
//sb.append("hello").append("world").delete().reverse();
//StringBuilder转String类型
System.out.println(sb.toString());
//StringBuilder中的大量方法都进行了重载,支持不同数据类型
//String/StringBuilder/StringBuffer三者的区别?
//String是不可变字符串对象,StringBuilder/StringBuffer是可变字符串对象
//其中StringBuilder线程不安全,但是效率高,StringBuffer线程安全,但是效率低
//由于多线程同时修改字符串的情况比较少,所以可以使用StringBuilder来提高性能
}
}
5、Arrays
注意数组拷贝方法使用
import java.util.Arrays;
/**
* Arrays类是一个工具类,封装了很多和数组操作相关的方法
*/
public class Demo01 {
public static void main(String[] args) {
int[] a = {1, 2, 3, 4, 5, 6, 7};
//String Arrays.toString(T[] a)
//将数组转换成字符串形式
String arrStr = Arrays.toString(a);
System.out.println(arrStr);
//int Arrays.binarySearch(T[] a, key)
//二分查找key在数组a中的下标位置,找不到返回负数
//注意:数组元素必须是有序的!
int[] b = {1, 2, 2, 3, 4, 5, 6};
System.out.println(Arrays.binarySearch(b, 1));
System.out.println(Arrays.binarySearch(b, 5));
//如果不存在则返回-1
System.out.println(Arrays.binarySearch(b, 11));
//如果存在重复元素,则返回第一个元素出现的位置
System.out.println(Arrays.binarySearch(b, 2));
//T[] copyOf(T[] original, int newLength)
//original--原始数组
//newLength--数组的新的长度
//用于数组扩容,返回扩容后的数组对象
int[] c = {1, 2, 3};
c = Arrays.copyOf(c, c.length + 1);
c[c.length - 1] = 4;
System.out.println(Arrays.toString(c));
//T[] copyOfRange(T[] original, int from, int to)
//拷贝数组中指定索引范围的元素到新的数组,返回新的数组,索引含头不含尾
//可以用来对数组进行截取
c = Arrays.copyOfRange(c, 2, 4);
System.out.println(Arrays.toString(c));
//void fill(T[] a, T val)
//用指定的val值填充数组a中的元素
int[] d = {1, 2, 3, 4, 5};
Arrays.fill(d, -1);
System.out.println(Arrays.toString(d));
//void fill(T[] a, int fromIndex, int toIndex, T val)
//用指定的val值填充数组a中从下标fromIndex到下标toIndex的元素,索引含头不含尾
Arrays.fill(d, 1, 4, 100);
System.out.println(Arrays.toString(d));
//Arrays.sort(T[] a);
//数组排序,默认升序
int[] e = {321, 3, 12, 4, 125, 12, 5, 1};
Arrays.sort(e);
System.out.println(Arrays.toString(e));
//思考:如何进行降序排列?
//逆序后的数组
int[] f = new int[e.length];
for (int i = e.length - 1; i >= 0; i--) {
//TODO:
//0-> length-1
//1-> length-2
//2-> length-3
//……
//新length-1 -> ?
//i->length-(i+1)
f[i]=e[e.length-i-1];
}
System.out.println(Arrays.toString(f));
}
}
6、System类
注意exit方法特点
import com.sun.deploy.util.Property;
import java.util.Arrays;
import java.util.Properties;
import java.util.Scanner;
/**
* System:和操作系统相关的类,可以用于获取操作系统系统相关的属性
* 以及一些操作系统级别功能的调用
*/
public class Demo01 {
public static void main(String[] args) {
//此处让客户提出以待优化!钱
// Thread.sleep(5000);
//currentTimeMillis()
//返回1970年1月1日0时到此刻的毫秒数
System.out.println(System.currentTimeMillis());
//思考:如何计算一段代码执行消耗的时间?
// long startTime = System.currentTimeMillis();
// Scanner sc = new Scanner(System.in);
// sc.nextLine();
// long endTime = System.currentTimeMillis();
// System.out.println("耗时:" + (endTime - startTime) + "ms");
//getProperties()
//取得当前系统的全部属性
Properties props = System.getProperties();
System.out.println(props);
//getProperty(String key)
//根据键值取得属性的具体内容
System.out.println(System.getProperty("os.name"));
//exit()
//系统退出
for (int i = 1; i <= 10; i++) {
if (i == 5) {
//break;
//exit是直接退出当前程序
//System.exit(0);
}
}
System.out.println("循环后面的代码...");
//arraycopy(Object src, int srcPos,Object dest, int destPos,int length);
//数组扩容
int[] a = {1, 2, 3, 4, 5, 6};
//将3-5拷贝到新数组第4个元素开始的地方
int[] b = new int[10];
System.arraycopy(a, 2, b, 3, 3);
System.out.println(Arrays.toString(b));
}
}
7、Date类
import java.util.Date;
/**
* Date:Java中使用Date类型来表示时间(其实就是通过一个固定的毫秒数来表示当前时间)
* Java中有java.util.Date以及java.sql.Date,此处谈java.util.Date
*/
public class Demo01 {
public static void main(String[] args) {
//Date对象的创建
//默认创建的是当前的时刻对应的日期对象
Date d = new Date();
System.out.println(d);
//getTime()
//1970年1月1日零时距离此刻的毫秒数
System.out.println(d.getTime());
//setTime(long time);
//设置时间,参数是1970年1月1日零时开始的毫秒数
d.setTime(150000000000L);
System.out.println(d);
//思考:如何获取明天此刻的时间?
d.setTime(System.currentTimeMillis() + 24 * 60 * 60 * 1000);
System.out.println(d);
//Date中提供了很多和时间分量操作相关的方法
//但是这些方法均已过时,应该使用Calendar类型中的方法来进行替代
// System.out.println(d.getDate());
// System.out.println(d.getYear());
// System.out.println(d.getMonth());
//2000-01-02
//2000/01/02
//2000-01-02 11:12:13
}
}
8、SimpleDateFormat
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* SimpleDateFormat:日期格式化类,可以实现从String到Date的转换
* 也可以实现从Date到String的转换
*/
public class Demo01 {
public static void main(String[] args) throws ParseException {
//SimpleDateFormat对象的创建
//参数是一个模式匹配字符串
//模式匹配字符串:用于告诉SimpleDateFormat要讲Date转换成何种格式的字符串
//或者何种格式的字符串需要被转换为Date类型
//模式匹配字符串严格区分大小写
//模式匹配字符串中如果包含特定字符以外的字符,则按照愿意输出
Date date = new Date();
//xxxx年xx月xx日 xx:xx:xx
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
//Date->String:调用format方法
System.out.println(sdf.format(date));
//String->Date:调用parse方法
//parse方法调用时一定要保证被转换的字符串和模式匹配字符串的格式是一致的
//如果格式不同,会导致转换失败!
sdf = new SimpleDateFormat("yyyy-MM-dd");
String dateStr = "2018-11-13";
Date d2 = sdf.parse(dateStr);
System.out.println(d2);
}
}
9、Calender类
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
public class Demo01 {
public static void main(String[] args) {
//构建太阳历对象
//Calendar c=new GregorianCalendar();
//可以根据实际的区域来获取相应的日历对象
Calendar c = Calendar.getInstance();
System.out.println(c);
//getTime()
//返回对应的Date对象
Date d = c.getTime();
System.out.println(d);
//setTime()
//用Date类型来设置Calendar表示的日期
//修改date再setTime()会导致Calendar中表示的日期发生变化
d.setTime(System.currentTimeMillis() + 24 * 60 * 60 * 1000);
c.setTime(d);
System.out.println(c);
System.out.println("==========================");
//set(Calendar.日期分量, 值)
//设置日期及时间分量
//第一个参数:指定要修改的时间分量是哪个
//第二个参数:指定要更新进去的值
c.set(Calendar.YEAR, 2020);
//注意:月份从0算起
//c.set(Calendar.MONTH, 11);
c.set(Calendar.MONTH, Calendar.JUNE);
//时间分量会自动进位
c.set(Calendar.DAY_OF_MONTH, 31);
c.set(Calendar.HOUR_OF_DAY, 17);
c.set(Calendar.MINUTE, 50);
c.set(Calendar.SECOND, 30);
//打印出xxxx年xx月xx日 时:分:秒
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
System.out.println(sdf.format(c.getTime()));
//get(Calendar.日期分量)
//获取日期及时间分量
System.out.println(c.get(Calendar.YEAR));
System.out.println(c.get(Calendar.MONTH) + 1);
System.out.println(c.get(Calendar.DAY_OF_MONTH));
System.out.println(c.get(Calendar.DAY_OF_YEAR));
System.out.println(c.get(Calendar.DAY_OF_WEEK));
System.out.println(c.get(Calendar.HOUR_OF_DAY));
System.out.println(c.get(Calendar.MINUTE));
System.out.println(c.get(Calendar.SECOND));
//getActualMaximum(Calendar.日期分量)/getActualMinimum(Calendar.日期分量)
//返回指定的日历字段可能拥有的最大(小)值
//例如:获取当前日历指定日期的月份中天数的最大值
System.out.println(c.getActualMaximum(Calendar.DAY_OF_MONTH));
System.out.println(c.getActualMinimum(Calendar.DAY_OF_MONTH));
System.out.println(c.getActualMaximum(Calendar.DAY_OF_YEAR));
//add(Calendar.日期分量,值)
//为给定的时间分量的值加上给定的值,若给定的值为负数则是减去给定的值(值会自动进位)
c.add(Calendar.DAY_OF_MONTH,15);
c.add(Calendar.DAY_OF_MONTH,200);
System.out.println(sdf.format(c.getTime()));
c.add(Calendar.DAY_OF_MONTH,-100);
System.out.println(sdf.format(c.getTime()));
}
}
10、java8新增日期的表示方法
import java.time.LocalDate;
import java.time.Month;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
/**
* LocalDate对象
*/
public class Demo01 {
public static void main(String[] args) {
//String->LocalDate
//String的默认格式是yyyy-MM-dd
LocalDate date = LocalDate.parse("2018-12-10");
System.out.println(date);
//格式错误
// date=LocalDate.parse("2018/12/10");
// System.out.println(date);
//可以指定格式化对象DateTimeFormatter来传递yyyy-MM-dd以外格式的时间字符串
date = LocalDate.parse("2018/12/10", DateTimeFormatter.ofPattern("yyyy/MM/dd"));
System.out.println(date);
//可以通过年月日对LocalDate进行初始化
//月份从1算起
date = LocalDate.of(2018, 3, 21);
System.out.println(date);
date = LocalDate.of(2018, Month.JULY, 21);
System.out.println(date);
//获取当前时间
date = LocalDate.now();
System.out.println(date);
//LocalDate->String
String dateStr = date.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"));
System.out.println(dateStr);
//获取时间分量
System.out.println(date.getYear());
//月份的英文
System.out.println(date.getMonth());
//月份的数字
System.out.println(date.getMonthValue());
System.out.println(date.getDayOfYear());
System.out.println(date.getDayOfWeek());
System.out.println(date.getDayOfMonth());
//时间分量的增减
//plus方法不会改变原来的日期对象
date = date.plusYears(3);
System.out.println(date);
date = date.plusYears(-3);
System.out.println(date);
//minus方法不会改变原来的日期对象
date = date.minusDays(3);
System.out.println(date);
date = date.minusYears(-10);
System.out.println(date);
//with方法直接设置时间分量
date = date.withMonth(4);
System.out.println(date);
// 比较时间的前后
// d1.isAfter(other)
// d1.isBefore(other)
LocalDate d1 = LocalDate.parse("1992-06-12");
LocalDate d2 = LocalDate.now();
System.out.println(d1.isAfter(d2));
System.out.println(d1.isBefore(d2));
//获取时间差
//1.Period:相对时差
Period period = Period.between(d1, d2);
System.out.println(period.getYears());
System.out.println(period.getMonths());
System.out.println(period.getDays());
//2.ChronoUnit:绝对时差
long years = ChronoUnit.YEARS.between(d1, d2);
System.out.println(years);
long months = ChronoUnit.MONTHS.between(d1, d2);
System.out.println(months);
long days = ChronoUnit.DAYS.between(d1, d2);
System.out.println(days);
//LocalDateTime的时间分量比LocalDate更多,常用操作几乎同LocalDate
//LocalDateTime time=LocalDateTime.of
//System.out.println(LocalDateTime.now())
}
}
11.BigInteger、BigDecimal、DecimalFormat
import java.math.BigInteger;
import java.util.Arrays;
/**
* BigInteger:完成比long型还要大的整数的运算
*/
public class Demo01 {
public static void main(String[] args) {
BigInteger b1 = new BigInteger("99999999999999999999999999999999999999999999");
BigInteger b2 = new BigInteger("99999999999999999999999999999999999999999996");
//加
System.out.println(b1.add(b2));
//减
System.out.println(b1.subtract(b2));
//乘
System.out.println(b1.multiply(b2));
//除
System.out.println(b1.divide(b2));
//保留余数的除法
BigInteger[] result=b1.divideAndRemainder(b2);
System.out.println("商:"+result[0]+",余数:"+result[1]);
}
}
import java.math.BigDecimal;
import java.security.interfaces.RSAKey;
/**
* BigDecimal:所有的精确计算,应该使用BigDecimal来完成(金钱、医学中的剂量……)
*/
public class Demo01 {
public static void main(String[] args) {
//0.1=1/10
//1/3=0.3333333333……
//浮点数在运算过程中有些结果在二进制系统中是无法精确表达的,因此可能出现精度问题
// System.out.println(3.0-2.9);
//构造BigDecimal对象
BigDecimal b1 = new BigDecimal("3.0");
BigDecimal b2 = new BigDecimal("2.9");
//调用BigDecimal中的方法完成运算
//减
BigDecimal result = b1.subtract(b2);
//BigDecimal
System.out.println(result);
//BigDecimal->double
System.out.println(result.doubleValue());
//加
result = b1.add(b2);
System.out.println(result.doubleValue());
//乘法
result = b1.multiply(b2);
System.out.println(result.doubleValue());
//除
b1 = new BigDecimal("5.0");
b2 = new BigDecimal("3.0");
//divide方法中,如果结果除不净,默认会出现错误
// result=b1.divide(b2);
// System.out.println(result.doubleValue());
//如果除不净,需要指定保留的小数点的位数以及保留的策略
result = b1.divide(b2, 2, BigDecimal.ROUND_DOWN);
System.out.println(result);
}
}
import java.text.DecimalFormat;
/**
* DecimalFormat:用来转化十进制数字,常用于对浮点数进行格式化操作
*/
public class Demo01 {
public static void main(String[] args) {
// System.out.println(13.14);
// System.out.println(14.50);
// System.out.println(15.00);
//构建DecimalFormat对象
//参数用来指定数字要被格式化为何种格式
double price = 15.10;
System.out.println(price);
DecimalFormat format = new DecimalFormat("000.00");
String result = format.format(price);
System.out.println(result);
}
}
12、正则表达式
(1)正则表达式的作用:
正则表达式的概念源自数学,是一种逻辑公式,该公式可以用来描述同一类具有相同规则的字符串,只有当这些字符串都符合这个公式的定义时,那么这个逻辑公式就是一个可以用来实现某种特定规则字符串的查找、替换、校验等功能的公式,即正则表达式。
/**
* 验证字符串是否和正则表达式匹配
*/
public class Demo01 {
public static void main(String[] args) {
String zipCode = "215000";
// String regex = "\\d\\d\\d\\d\\d\\d";
String regex="\\d{6}";
//
System.out.println(zipCode.matches(regex));
//匹配3到5个数字和字母(a-k)的集合
//[……]:取[]中指定集合中的某一个元素
String str="123ab";
regex="[a-k0-9]{3,5}";
System.out.println(str.matches(regex));
str="123az";
System.out.println(str.matches(regex));
str="123";
System.out.println(str.matches(regex));
str="abcde";
System.out.println(str.matches(regex));
str="a1";
System.out.println(str.matches(regex));
}
}
/**
* 匹配手机号,手机号前可以有+86 或0086两种区号。区号和手机号之间可以有任意多个空格。
*/
public class Demo02 {
public static void main(String[] args){
//如果正则中出现的字符是特殊字符,而此时需要让它表示其原来的含义,需要进行转义
//在正则中可以使用|表示或
String regex="(\\+86|0086)?\\s*\\d{11}";
String str="+8618862202591";
System.out.println(str.matches(regex));
str="18862202591";
System.out.println(str.matches(regex));
str="008618862202591";
System.out.println(str.matches(regex));
str="0086 18862202591";
System.out.println(str.matches(regex));
str="0086 18862202591";
System.out.println(str.matches(regex));
str="+86 18862202591";
System.out.println(str.matches(regex));
str="+86 18862202591";
System.out.println(str.matches(regex));
str="+8618862202591";
System.out.println(str.matches(regex));
}
}
/**
* String[] split(String regex)
* 以指定的正则表达式为分隔符,将字符串拆分成一个字符串数组
*/
public class Demo03 {
public static void main(String[] args) {
String str = "123,456, 789, 1112+ 789";
//提取其中的4个数字
//该方法中的参数是一个正则表达式
String[] strs = str.split("(,|\\+){1}\\s*");
for (String s : strs) {
System.out.println(s);
}
}
}
/**
* String replace(CharSequence target, CharSequence replacement)
* 用于替换字符串中指定的字符和字符串
*/
public class Demo04 {
public static void main(String[] args){
String str="123abc156efg";
//方法中的参数都是普通的字符串或字符
str=str.replace("1","一");
System.out.println(str);
}
}
/**
* String replacereplaceAll(String regex, String replacement)
* 用于替换字符串中指定的字符和字符串,不过这里是基于正则匹配来进行替换的
*/
public class Demo05 {
public static void main(String[] args){
String str="123abc456def789sss";
//将字符串中的每一段数字替换为中文的“数字”
//数字abc数字def数字sss
//第一个参数是要被替换的字符串对应的正则表达式
str= str.replaceAll("\\d+","数字");
System.out.println(str);
}
}