474讲(重要)StringBuffer类、StringBuilder类、math方法、Arrays、BigInteger\BigDecimal、Date&Calender
StringBuffer类
- 老韩解读
- StringBuffer 的直接父类是 AbstractStringBuilder
- StringBuffer 实现了Serializable 接口,即StringBuffer 的对象可以串行化
- 在父类中 AbstractStringBuilder 有属性 char[] value,不是final类型
该 value 数组存放字符串内容。因此是存放在堆中。
- StringBuffer 是一个final 类,不能被继承
- 因为StringBuffer 字符内容是存在 char[] value,所以在变化(增加/删除),
不用每次都更换地址(即不是每次都创建新对象),所以效率高于String。
-
StringBuffer的构造器
-
String 和 StringBuffer相互转换。
- StringBuffer 常用方法(必须掌握)
StringBuffer练习题
- 题1.
- StringBuffer sb = new StringBuffer( null );//会报错,抛出空指针异常。(看下方源码)
- 题2
package com.dearl;
public class Test02 {
public static void main(String[] args) {
String price = "367446461456439.88";
StringBuffer priceSB = new StringBuffer();
priceSB = priceSB.append(price);
int search = priceSB.indexOf(".");
while(search > 3){
int cycle = 0;
priceSB.insert(search - (3 + cycle*3),",");
cycle++;
search -= 3;
}
System.out.println(priceSB);
}
}
StringBuilder类
- 老韩解读
- StringBuilder 继承了AbstractStringBuilder 类
- 实现了 Serializable ,说明StringBuilder 对象是可以串行化(对象可以网络传输,对可以保存到文件)
- StringBuilder 是final 类,不能被继承。
- StringBuilder 对象的字符序列仍然是存放在其父类 AbstractStringBuilder 的Char [] value;
因此,字符序列是在堆中。
- StringBuilder 方法,没有做互斥处理,即没有synchronized 关键字修饰,因此在单线程的情况下使用StringBuilder。
- StringBuilder常用方法
-
String回顾。上一节( 自己整理的。)
package com.dearl; public class Test { public static void main(String[] args) { Test1 ex = new Test1(); ex.change(ex.str,ex.ch);//str 指向java直接指向常量池//这里暂时没有接收。所以str指向堆中的地址不变。 String str2 = "java";//这里str2 直接指向常量池。 System.out.println(ex.str == str2);//false!!!! /* 如果: 1.上面代码ex.str = ex.change(ex.str,ex.ch); 用str接收了。那么str就会直接指向java 2.然后System.out.println(ex.str == str2); */ System.out.print(ex.str + " and "); System.out.println(ex.ch); } } class Test1 { String str = new String("java"); //这里str指向堆 final char[] ch = {'j','a','v','a'}; public String change(String str,char ch[]){ str = "java"; ch[0] = 'h'; return str; } }
StringBuffer 和StringBuilder 类和String 类对比
- 效率测试
- 结论
MATH方法
Math常用方法(基本都是static静态方法,用类名.方法调用)
公式 int num = (int)(a + Math.random()*(b - a + 1)); (背下来!!)
package com.dearl;
//这个是我自己写的。效率很低。不建议。太麻烦。
public class Test {
public static void main(String[] args) {
System.out.println(new Test().getRandom());
}
int getRandom() {
int x;
for (;;) {
x = (int)(Math.random()*10);
if(x >= 2 && x <= 7){
return x;
}
}
}
}
Arrays类
- Arrays类常用方法。
- Array.sort( ); 排序 --> 定制排序
- 自己写自定义排序。(利于理解。)
public class ArraysSortCustom {
public static void main(String[] args) {
Integer[] arr = {11 , 18,60,3,2,33,22,66,256};
System.out.println("================");
new test2().BubbleCustom(arr, new Comparator() {//这里用匿名内部类
@Override
public int compare(Object o1,Object o2){//重写Comparator的compare方法。传入下面test2的if() 中。
Integer i1 = (Integer) o1;
Integer i2 = (Integer) o2;
return i2 - i1;
}
});
}
}
class test2 {
public Integer[] BubbleCustom(Integer[] arr,Comparator c){
for (int i = 0; i < arr.length; i++) {
int temp = 0;
for (int j = 0; j < arr.length - i - 1; j++) {
//这里动态绑定机制,用的匿名内部类的compare();
if (c.compare(arr[j],arr[j + 1]) > 0){
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
}
- Arrays类常见方法
- 二分法搜索进行查找
有个有意思的现象。如果查找的是不存在的元素:就return -(low + 1);这里的low代表元素该存在的位置
- copyOf() 数组拷贝
-
如果拷贝长度小于0,就抛出异常NagativeArraySizeException
-
拷贝长度小于arr.length。就按照需求拷贝相应的长度的数组
-
从arr 数组中,拷贝元素到新数组中。!!!!!!!!
特殊对比情况
此处int[] 类型的数组拷贝超过长度的,默认给的0;//老韩是Integer包装类的数组,给的是null
- fill( ); 填充元素。Arrays.fill(num, 99); 使用99区填充num数组,可以理解为替换原来的元素
- equals(); 比较两个数组元素内容是否完全一致
- 如果arr 和 arr2 数组元素完全一样,则返回true;
- 如果不完全一样,则返回false
-
asList(); 讲一组值,转换成list
老韩解读:
-
asList(); 方法,会将如图的(2,3,4,5,6,1)数据转换成一个list集合
-
返回 asList 编译类型 List(接口)
-
asList 运行类型 java.util.Arrays#ArrayList ,
是Arrays类的静态内部类 private static class ArrayList
extends AbstractList
-
Arrays类课堂练习
//下面代码return (int)(i1 - i2);//会存在精度损失。排序有小数点会出问题(仅供参考)
编程思想:有时候不能直接返回int。可以用if-else 判断返回int类型
//改进
@Override
public int compare(Object o1, Object o2) {
double i1 = (double)o1;
double i2 = (double)o2;
// return (int)(i1 - i2);//会存在精度损失。万一为0.几就会出事。
if((i1 - i2)>0){
return 1;
}else if((i1 - i2)<0){
return -1;
}
return 0;
}
package com.dearl.Arrays_;
import java.util.Arrays;
import java.util.Comparator;
public class ArrayExercise {
/*
* 自定义Book类,里面包含name和price,按照price排序(从大到校)。要求使用两种排序方式,
* 有一个Book[] books = 4本书对象。
* */
//使用前面学过的传递 实现Comparator接口匿名内部类,也称为定制排序
public static void main(String[] args) {
Book[] books = new Book[4];
books[0] = new Book("红楼梦", 100);
books[1] = new Book("西游记", 90);
books[2] = new Book("青年文摘", 5);
books[3] = new Book("java从入门到单身狗", 300);
books[0].getArray(books, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
double i1 = (double)o1;
double i2 = (double)o2;
// return (int)(i1 - i2);//会存在精度损失。万一为0.几就会出事。
if((i1 - i2)>0){
return 1;
}else if((i1 - i2)<0){
return -1;
}
return 0;
}
});
for(Book book : books){
System.out.println(book.getName());
}
// System.out.println(Arrays.toString(books));
}
}
class Book {
private String name;
private double price;
public Book(){}
public Book(String name, double price) {
setName(name);
setPrice(price);
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
private void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public Book[] getArray(Book[] books,Comparator c){
for (int i = 0; i < books.length - 1; i++) {
for (int j = 0; j < books.length - i - 1; j++) {
Book temp;
if(c.compare(books[j].getPrice(),books[j + 1].getPrice()) > 0){
temp = books[j];
books[j] = books[j + 1];
books[j + 1] = temp;
}
}
}
return books;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
// @Override 写错了
// public String toString(){
// return new Book().getName() + "," + new Book().getPrice();
// }
}
-
老韩方法。用的如下以老韩为标准。因为他要是更改排序方法。直接在main方法调用get 方法获取属性,更简洁。这就是这里匿名内部类的精髓。
@Override public int compare(Object o1, Object o2) { Book i1 = (Book)o1; Book i2 = (Book)o2; // return (int)(i1 - i2);//这里精度损失不能这么干!!!!! if((i1.getPrice() - i2.getPrice())>0){ return 1; }else if((i1.getPrice() - i2.getPrice())<0){ return -1; } return 0; } }); //用这个要注意。在 public Book[] getArray(Book[] books,Comparator c){ for (int i = 0; i < books.length - 1; i++) { for (int j = 0; j < books.length - i - 1; j++) { Book temp; if(c.compare(books[j],books[j + 1]) > 0){//这里返回的必须是对象。 //不能是books[j].getPrice(),books[j + 1].getPrice() !!!! temp = books[j]; books[j] = books[j + 1]; books[j + 1] = temp; } } } return books; }
System类
- exit(); 方法
老韩解读
- exit(0); 表示程序退出
- 0 表示一个状态,正常的状态
- arraycopy(); 方法
一般像下面这样写就行了...一般用Arrays.copyOf(); 这个方法。。
- currentTimeMillis();
BigInteger和BigDecimal类
- BigInteger类 不能直接加减乘除。。而是要用其相应的方法 add(); substract(); multiply(); divide();
要创建一个需要操作的BigInteger的数。然后再用 加减乘除对应的方法。!!!
- BigDecimal类
加减乘除和上方BigInteger相似。注意!!! BigDecimal类的除法可能会抛出异常!!!
日期类
- 第一代日期类
//格式使用的字母是规定好的,不能乱写。
-
第二代日期类。java.util.Calendar
注意:Calendar类构造器是private 的,私有的,不能直接获取实例,需要调用getInstance(); 方法获取。
- 第三代日期类。
- 第三代日期类常见方法
这哥们实现了这么多接口。。。
- 第三代日期类格式化
public class Test {
public static void main(String[] args) {
// Instant instant = Instant.now();
LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt.getHour());
LocalDateTime ldt2 = ldt.plusDays(890);
System.out.println("890天后的时间= " + ldt2);
}
}