1. Math 类
Math类是Java给的一个类,里面包含多种数学方法,常用的有以下几种
public class Demo01 {
public static void main(String[] args) {
//math常用方法
//1.abs绝对值
int abs = Math.abs(-68);
System.out.println(abs);//68
//2.pow求幂
double pow = Math.pow(2,6);//pow的数据类型默认为double。
System.out.println(pow);//64.0
//3.ceil向上取整,转成double
double ceil = Math.ceil(8.001);
System.out.println(ceil);//9.0
//4.floor向下取整,转成double
double floor = Math.floor(-1.001);
System.out.println(floor);//-2.0
//5.round四舍五入
long round1 = Math.round(5.49);
long round2 = Math.round(5.51);
System.out.println(round1 +"and"+round2);//5 and 6
//6.sqrt 开方
double sqrt = Math.sqrt(9.0);
System.out.println(sqrt);//3.0
//random 随机数,返回时是0~1之间的一个随机小数,不能到达1
//写出一个a-b之间的随机整数,a,b均为整数,a=2,b=7
for (int i = 0; i < 10; i++) {
double num = (int)(2+Math.random()*6);
System.out.println(num);
}
}
}
2.String 类
- String类是一个非常重要的类,它是用来储存字符串的一个类,在底层,String通过
char[]
数组来保存字符串。 char[]
数组是被final
修饰的,因此它指向的是常量池中固定的地址,它的地址不可改变,但它其中的字符的值是可以改变的。String
也是被final
修饰的类,字符串是一个常量,但String对象是一个变量,它不能作为父类。- 字符串的字符使用Unicode编码,一个字符对应一个编码。
- String有很多构造器的重载。
- String实现了Serializable接口,可以在网络上传输,串行化
- String实现了Comparable接口,它的对象可以进行比较
2.1 String的内存分析
这里其实很好理解,主要是直接指向常量池,
还是建立了对象,先指向对象,再由对象指向常量池中的地址的区别。
public class Demo01 {
String s = "n1c4n";
String str = new String("n1c4n");
}
- String的创建包括两种方式:
方式一:直接赋值String s = “n1c4n”;
方式一会先检查常量池是否有”n1c4n“,如果有,直接指向这个空间的地址;如果没有会创建后指向。s最终指向的是常量池的空间地址。
方式二:调用构造器 String str = new String(“n1c4n”);
方式二先在堆中创建空间,保存value属性,然后在常量池中检查是否有"n1c4n",如果有,通过value指向,如果没有,通过创建后通过value指向。
2.2 String常用方法
- String的方法有很多,这里试了一些常用的方法,如果有需要到API手册查询。
public static void main(String[] args) {
String s = "n1c4n";
String str = new String("N1c4n");
//区分大小写,判断内容是否相等 equals
System.out.println(s.equals(str));
//不区分大小写,判断内容是否相等 equalsIgnoreCase
System.out.println(s.equalsIgnoreCase(str));
//获取字符的个数,字符串的长度 length
System.out.println(str.length());
//获取字符在字符串中第一次出现的索引,如找不到,返回-1 indexOf
System.out.println(s.indexOf('1'));
//获取字符在字符串中最后一次出现的索引,如找不到,返回-1 LastIndexOf
System.out.println(s.lastIndexOf('1'));
//截取指定范围的字符串内容
System.out.println(str.substring(0,2));
//去除前后空格 trim
System.out.println(s.trim());
//获取某索引处的字符,不能使用Str[index]这样的索引
System.out.println(str.charAt(0));
//字符串转换成大写 toUpperCase
System.out.println(s.toUpperCase());
//字符串转换成小写 toLowerCase
System.out.println(str.toLowerCase();
//拼接字符串 concat
System.out.println(s.concat("Fight"));
//替换字符串中的字符 raplace
System.out.println(s.replace("1","2"));
//分割字符串 split
System.out.println(str.split("4"));
//比较两个字符串的大小 compareTo
//长度相同,内容相同,返回0
//长度相同,内容不同,返回第一个不向同的字符的Unicode编码的差值
//长度不同,返回前者的长度减后者的长度
System.out.println(s.compareTo(str));
//转换成字符数组 toCharArray
System.out.println(s.toCharArray());
}
}
2.3 StringBuffer
- 1.StringBuffer的直接父类是AbstarctStringBuilder
- 2.实现串行化接口
- 3.在AbstarctStringBuilder中有属性char[] value,不是final类型
value数组存在字符串内容,存放在堆中
这里和String有明显的区别,String是存放在final char[],是常量,每次修改都是修改地址
StringBuffer是存放在变量char[]中,修改可以更新内容,不用更新地址
但char[]数组的空间有限,当空间不足够时,会扩容到新空间,并将原来的字符拷贝到新空间 - 4.它被final修饰,不能被继承
StringBuffer的构造
public class buffer {
public static void main(String[] args) {
//StringBuffer()构造,建立可以容纳16个字符的变量空间
StringBuffer stringBuffer = new StringBuffer();
//new StringBuffer(num) 构造一个指定大小的变量空间,num是int类型
StringBuffer stringBuffer = new StringBuffer(68);
//StringBuff(String)构造一个包含字符串的变量空间,它的大小为字符串+16
//也可以把他看作是String转换为StringBuffer
/StringBuffer stringBuffer = new StringBuffer("n1c4n");
}
}
//String转换为StringBuffer
//利用构造器
//对String本身没有影响,值传递,产生了新的StringBuffer对象
String str = "n1c4n";
StringBuffer sbf = new StringBuffer(str);
//利用append方法
//直接修改了sbf,这就是变量的可修改
StringBuffer sbf = new StringBuffer();
sbf = sbf.append("n1c4n");
//StringBuffer转换为String
//使用toString方法
String str = sbf.toString();
//使用构造器
String s = new String(sbf);
- StringBuffer的常用方法
public class buffer02 {
public static void main(String[] args) {
StringBuffer sbf = new StringBuffer("n1c4n");
//增
//可以任意拼接多个字符或字符串
sbf.append(',');
sbf.append("fight!");
System.out.println(sbf);
//删
//删除任意字符段
sbf.delete(7,9);
System.out.println(sbf);
//改
//改写字符,从起始索引字符到结束索引字符之前替换
sbf.replace(7,9,"ire");
System.out.println(sbf);
//插
//插入字符,插入在指定索引字符后
sbf.insert(6, "just");
System.out.println(sbf);
}
}
2.4 StringBuilder
- StringBuilder是简易版的StringBuffer,它不是线程安全,适用单个线程使用字符串缓冲区,如果可以,优先考虑使用。
- StringBuilder主要操作是append和insert方法,可重载这些方法,以接收任意类型的数据。
- StringBuilder实现的接口和他的父类与StringBuffer一致,它的方法和StringBuffer一致。
- StringBuilder和StringBuffer的区别在于,前者不是线程安全,适用于单线程;后者线程安全,适用于多线程。
public class builder {
public static void main(String[] args) {
StringBuilder stringBuilder = new StringBuilder();
}
}
3. Array 类
3.1 toString 方法
将数组以字符串的形式输出,它有多个重载,将各种类型的值以字符串的形式输出,并在前后加上"["
+"]"
,在底层,依靠StringBuild的方法,实现apend拼接。它的代码会在后面的例子中多次出现,这里不再贴代码了。
3.2 sort 方法
将数组从小到大进行排序。
public class sort {
public static void main(String[] args) {
Integer[] integers = {1,2,7,4,3,9};
//Arrays.toString方法,直接显示数组
System.out.println(Arrays.toString(integers));
//Arrays.sort方法,对数组进行排序
//sort是重载的,可以通过引用接口Comparator进行定制排序
Arrays.sort(integers);
System.out.println(Arrays.toString(integers));
因为数组是引用类型,sort方法会直接影响到实参。
sort方法可以依靠Comparator接口实现定制排序。
//定制排序
//执行到Comparator接口中的compare方法,最终到TimSort类中的binarySort方法
//实际在我的main方法中,没有直接调用匿名内部类的compare方法,而是在sort方法的源码中,如果调用的接口被实现了,会调用binarySort的方法
//binarySort会直接调用我重写的compare方法来进行操作
Arrays.sort(integers, new Comparator() {//匿名内部类,实现了方法compare的重写
@Override
public int compare(Object o1, Object o2) {
Integer integer1 = (Integer) o1;
Integer integer2 = (Integer) o2;
return integer2-integer1;
}
});
System.out.println(Arrays.toString(integers));
}
Comparator接口通过匿名内部类的方式,在内部控制传向sort方法的形参。
底层sort的重载中,如果接口Comparator被实现的话,就会通过else判断调用binarySort的方法,binarySort的方法会调用重写的compare方法对排序方式进行判断。
- 我们通过写一个冒泡排序的方法来重现类似sort方法底层的路径,来理解上面的过程。
import java.util.Arrays;
import java.util.Comparator;
public class binarymaopao {
public static void main(String[] args) {
int[] arr = {-1, -5, 0, 45, 8, 7};
binarymaopao binarymaopao = new binarymaopao();
binarymaopao.bubble(arr, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
int i1 = (Integer) o1;
int i2 = (Integer) o2;
return i2 - i1;//这里compare方法返回的值会影响bubble2方法冒泡的方向,从而控制排序结果
}
});
System.out.println(Arrays.toString(arr));
}
public void bubble(int[] arr, Comparator c) {
for (int i = 0; i < arr.length - 1; i++) {
int temp = 0;
for (int j = 0; j < arr.length - 1 - i; j++) {
if (c.compare(arr[j], arr[j + 1]) > 0) {
temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
}
}
}
这里的bubble
方法就类似sort方法的重载在底层形式,通过将接口作为匿名内部类的形式的形参,在方法体中调用实现接口重写的compare方法,从而使得可以利用重写compare方法的方式,控制排序的方式。
3.3 binarySearch 方法
- binarySearch方法是对有序数组进行查找的方法,又叫做二叉查找法。
import java.util.Arrays;
public class binarySearch {
public static void main(String[] args) {
Integer[] arr = {1,2,5,7,9};
int index = Arrays.binarySearch(arr, 3);
System.out.println("index="+index);
}
}
- binarySearch方法要求必须是有序的数组,且排序必须是从小到大。
- 查找一个不存在的元素,会返回一个负数。
- 分析源码,返回的负数的值是
-(low+1)
。如果这个数存在的话,它所在的位置加1,再取负数。
3.4 fill 方法
- 将一个数组的全部元素填充为某个值。
import java.util.Arrays;
public class fill {
public static void main(String[] args) {
Integer[] arr = {7,5,9};
Arrays.fill(arr,99);//将原来的数组全部填充为99
System.out.println(Arrays.toString(arr));
}
}
3.5 copyOf 方法
- 将一个数组的值拷贝到新数组中的方法。
import java.util.Arrays;
public class copyOf {
public static void main(String[] args) {
Integer[] arr = {5,4,1,6,9};
Integer[] newArr = Arrays.copyOf(arr,7);//从数组arr中,拷贝5个元素到新数组newArr中
System.out.println(Arrays.toString(newArr));
}
}
- 如果拷贝的长度,大于arr的长度,就插入null。
- 底层使用了System.arraycopy()方法。
3.6 equals 方法
- 比较两个数组是否完全一致的方法。
import java.util.Arrays;
public class equals {
public static void main(String[] args) {
Integer[] arr = {4,6,1,30};
Integer[] newArr = Arrays.copyOf(arr, arr.length);
System.out.println(Arrays.equals(arr,newArr));
newArr[0] = 0;
System.out.println(Arrays.equals(arr,newArr));
}
}
- equals比较两个数组是否完全一致,包括值与顺序。
- 返回值是布尔值。
3.7 asList 方法
- 将一个数组的类型转换成List类型的方法。
import java.util.Arrays;
import java.util.List;
public class asList {
public static void main(String[] args) {
List<Integer> asList = Arrays.asList(1,8,6,4,7);
System.out.println(asList);
}
}
- 编译类型为List,List是一个接口。
- 运行类型是java.util.Arrays$ArrayList,是java.Arrays类下的一个内部类ArrayList。
3.8 例子
- 假设有4本书(4个对象),每本书的名字和学习所需要的时间不同,按学习时间和书名长度,对书进行排序。
import java.util.Arrays;
import java.util.Comparator;
import java.util.Objects;
class Book {
private String name;
private int day;
public Book(String name,int day) {
this.name = name;
this.day = day;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", day=" + day +
'}';
}
}
public class test{
public static void main(String[] args) {
Book[] books = new Book[4];
books[0] = new Book("javase",30);
books[1] = new Book("Mysql",5);
books[2] = new Book("js",7);
books[3] = new Book("javaweb",14);
System.out.println(Arrays.toString(books));
//按书名长度排序
Arrays.sort(books, new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
Book book1 = o1;
Book book2 = o2;
int i = book1.getName().length() - book2.getName().length();
return i;
}
});
System.out.println(Arrays.toString(books));
//按学习时间排序
Arrays.sort(books, new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
Book book1 = o1;
Book book2 = o2;
int i = book1.getDay() - book2.getDay();
return i;
}
});
System.out.println(Arrays.toString(books));
}
}
4. Date 类
日期类的方法太多,需要用的时候可以到API手册中查找。
4.1 第一代日期类 Date
- 通过
new()
关键字建立Date对象获取当前的时间。 - SimpleDateFormat类可以将时间按指定形式转换。
- 也可以把指定的字符串通过parse方法转换为Date形式。
public static void main(String[] args) throws ParseException {
Date d1 = new Date();//获取当前的时间
System.out.println(d1);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");
System.out.println(sdf.format(d1));//将时间按指定形式转换。
//可以把一个指定字符串转换为对应的 Date。
String date = "2022年12月24日 05:37:09 星期六";
Date parse = sdf.parse(date);//使用的sdf格式需要和你的String的格式一致,否则会抛出转换异常。
System.out.println(sdf.format(parse));
}
4.2 第二代日期类 Calendar
- Calendar是一个抽象类,它的构造器是protected修饰的。
- Calendat通过getInstance()来获取实例。
- 提供了大量的方法和属性。
- 没有对应的格式化,自由组合。
import java.util.Calendar;
public class Demo01 {
public static void main(String[] args) {
Calendar c = Calendar.getInstance();
System.out.println("年"+c.get(Calendar.YEAR));
System.out.println("月"+(c.get(Calendar.MONTH)+1));
System.out.println("日"+c.get(Calendar.DATE));
System.out.println("时"+c.get(Calendar.HOUR));
System.out.println("分"+c.get(Calendar.MINUTE));
System.out.println("秒"+c.get(Calendar.SECOND));
}
}
4.3 第三代日期类 LocalDate
- 通过
now()
返回当前时间的对象 - 可以通过DateTimeFormatter的ofPattern方法,将时间转换为指定格式。
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
public class Demo01 {
public static void main(String[] args) {
//第三代日期
//now()返回到期时间的对象
LocalDateTime LDT = LocalDateTime.now();
LocalDate date = LocalDate.now();
System.out.println(LDT);
System.out.println("年"+LDT.getYear());
System.out.println("月"+LDT.getMonth());
System.out.println("月"+LDT.getMonthValue());
System.out.println("日"+LDT.getDayOfMonth());
System.out.println("时"+LDT.getHour());
System.out.println("分"+LDT.getMinute());
System.out.println("秒"+LDT.getSecond());
//转换输出格式
DateTimeFormatter d = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒");
d.format(LDT);
System.out.println(d);
}
}
- 时间戳
import java.time.Instant;
import java.util.Date;
public class Demo02 {
public static void main(String[] args) {
//通过静态方法now()获取当前的时间戳的对象
Instant instant = Instant.now();
System.out.println(instant);
//通过from方法可以把Instant对象转成Date
Date date =Date.from(Instant.now());
//通过toInstant方法可以把Date转成Instant对象
Instant i = date.toInstant();
}
}