包装类的引入
Java是一个面向对象的编程语言,但是Java中的八种基本数据类型却是不面向对象的,为了使用方便和解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八种基本数据类型对应的类统称为包装类(Wrapper Class),包装类均位于java.lang包。
包装类的分类
基本数据类型 | 包装类 |
boolean | Boolean |
char | Character |
byte | Byte |
int | Integer |
short | Short |
long | Long |
float | Float |
double | Double |
包装类和基本数据的转换
在jdk1.5之前,使用手动装箱和手动拆箱
在jdk1.5之后,使用自动装箱 和自动拆箱(自动装箱底层调用的是ValuesOf方法)
举例interger (其他包装类类似)
public class Integer01 {
public static void main(String[] args) {
//演示 int <--> Integer 的装箱和拆箱
//jdk5 前是手动装箱和拆箱
//手动装箱 int->Integer
int n1 = 100;
Integer integer = new Integer(n1);
Integer integer1 = Integer.valueOf(n1);
//手动拆箱
//Integer -> int
int i = integer.intValue();
//jdk5 后,就可以自动装箱和自动拆箱
int n2 = 200;
//自动装箱 int->Integer
Integer integer2 = n2; //底层使用的是 Integer.valueOf(n2)
//自动拆箱 Integer->int
int n3 = integer2; //底层仍然使用的是 intValue()方法
}
}
valueOf方法的底层
public class WrapperVSString {
public static void main(String[] args) {
//包装类(Integer)->String
Integer i = 100;//自动装箱
//方式 1
String str1 = i + "";
//方式 2
String str2 = i.toString();
//方式 3
String str3 = String.valueOf(i);
//String -> 包装类(Integer)
String str4 = "12345";
Integer i2 = Integer.parseInt(str4);//使用到自动装箱
Integer i3 = new Integer(str4);//构造器
System.out.println("ok~~");
}
}
package 包装类;
public class Intege {
public static void main(String[] args) {
//面试题
Object obj1 = true ? new Integer(1):new Double(2.0);
System.out.println(obj1);//1.0
//考察三元运算符,若obj1为真,应该输出1.0,而不是1
//例题一
Integer i1 = new Integer(127);
Integer i2 = new Integer(127);
System.out.println(i1 == i2); //F
//例题二
Integer i3 = new Integer(128);
Integer i4 = new Integer(128);
System.out.println(i3 == i4);//F
//例题三
Integer i5=127;
Integer i6 =127;
System.out.println(i5 == i6); //T
//例题四
Integer i7 =128;
Integer i8 =127;
System.out.println(i7 == i8); //F
//例题五
Integer i9 = 128;
Integer i10 = new Integer(127);
System.out.println(i9 == i10);//F
//例题六
Integer i11 =127;
int i12 = 127;
System.out.println(i11 == i12);//T
//例题七
Integer i13 = 128;
int i14 = 128;
System.out.println(i13 ==i14);//T
//Integer例题
Integer m=1; Integer n1 =1;
System.out.println(m == n1); //T
Integer m2 =128; Integer n2 =2;
System.out.println(m2 == n2); //F
//如果n在(-128 ---127)之间,直接从数组中返回
//如果不在这个范围内,就直接new integer(n)判断地址
}
}
String类
理解:String对象用于保存字符串,也就是一组字符序列
字符串常量对象是用双引号括起来的字符序列
字符串的字符使用Unicode字符编码,一个字符占两个字节
String类较常用构造器
1)String s1 = new String();
2)String s2 = new String(String original);
3)String s3 = new String(char[] a);
4)String s4 = new String(char[],int startdex,int count)
5)String 类实现了接口 Serializable【String 可以串行化:可以在网络传输】
接口 Comparable [String 对象可以比较大小]
6) String 是 final 类,不能被其他的类继承
7) String 有属性 private final char value[]; 用于存放字符串内容
8) 一定要注意:value 是一个 final 类型, 不可以修改(需要功力):即 value 不能指向
新的地址,但是单个字符内容是可以变化
public class String01 {
public static void main(String[] args) {
// 创建一个内容为字符数组的字符串
char[] charArray = new char[]{'D', 'E', 'F'};
String str3 = new String(charArray);
String C ="'D'"+"'E'"+"'F'";
System.out.println(C);
}
}
创建StrIng对象的两种方式
1)方式一:直接赋值 String s ="lla"
理解:先从常量池查看是否有lla数据空间,如果有直接指向,如果没有重现创建,然后指向。s 最终指向的是常量池的空间地址。
2)方式二: 调用构造器 String s2 =new String("lla");
理解:先在堆中创建空间,里面维护了value属性,指向常量池的lla,若干常量池没有lla,重新创建,如果有,直接通过value指向。最终指向的是堆中的空间地址
了解了上面的图 现在来做一下下面的题,看是否能做对呢?
equals和 == 的区别(重要)
package 包装类;
public class equals {
public static void main(String[] args) {
Integer integer1 = new Integer(1000);
Integer integer2 = new Integer(1000);
System.out.println(integer1 == integer2);//F
System.out.println(integer1.equals(integer2));//T
String a = "lla";
String b = new String("lla");
String c = new String("lla");
System.out.println(b == c);//F
System.out.println(b.equals(c));//T
System.out.println(a.equals(b));//T
System.out.println(a == b);//F
System.out.println(a == b.intern());//T
System.out.println(b == b.intern());//F
//知识点:调用Intern方法时,如果池中已经包含一个等于此String对象的字符串
//则返回池中的字符串,否则,将String对象加载到池中,并返回String对象的引用
//理解: b.intern()方法最终返回的是常量池的地址(对象)
}
}
我们再来看两道面试题
package 包装类;
public class String面试题 {
public static void main(String[] args) {
//1.下题创建几个对象? //一个
String x = "hello"+"abc";
//编译器做一个优化,判断创建的常量池对象,是否有引用指向
//String x ="hello" + "abc"; ===>String x ="helloabc";
//2.问下题创建了几个对象? //三个
String a ="hello";
String b ="abc";
String c = a + b;
//底层为:
//StringBuilder sb = new StringBuilder();
//sb.append(a);
//sb.append(b);
//sb是在堆中,并且append是在原来的字符串的基础上追加的
String d = "helloabc";
System.out.println(c == d);//真还是假? 是false
String e = "hello" + "abc";//直接看池, e指向常量池
System.out.println(d == e);//真还是假? 是true
//3.比较内容
Person p1= new Person();
p1.name ="lla";
Person p2 = new Person();
p2.name ="lla";
System.out.println(p1.name.equals(p2.name));//T 内容是否相同
System.out.println(p1.name == p1.name);//T 都在常量池中指向一个lla
System.out.println(p1.name == "lla");//T
String s1 =new String("abcd");
String s2 =new String("abcd");
System.out.println(s1 == s2);//F 比较的是s1和s2堆中的地址是否相同
}
看看老韩分析的这一道题 ,比较难
上图解析:
首先列出框架 栈 堆 和常量池
1)在实例化对象的时候,有两个属性 栈中的ex实例化对象指向堆中的str,str的value值指向常量池中的hsp 第二个属性是栈中的ex实例化对象指向堆中的ch数组,ch数组在堆中开辟新的空间存放java。
2)当调用ex.change的时候,栈先创建一个新栈,指向堆中的str,str的value值还是指向常量池中的hsp。 还指向堆中的ch数组,指向堆中存放的数组
3)当使用str =“java"时,因为不是this.str,所以新栈断开了与堆中的str,直接在常量池中创建了”java“常量 。 当使用ch[0] = 'h'时,堆中数组的第一个元素变为h
4)当调用方法完成时,ex指向的还是原先堆中的str,对应常量池里的值还是hsp,但是指向数组从java改成了hava。
5)因此 ,本题输出的是hsp and hava
String方法
1.equals 方法:比较字符串大小 2.equalsIgnoreCase 忽略大小写 判断内容是否相等 3. length 返回此字符串s1的长度 4. indexOf 返回指定字符ch在字符串中第一次出现位置的索引 5. 返回指定字符ch在字符串中最后一次出现位置的索引 6.substring 截取制定范围的子串 7.toUpperCase 转换大写 8.toLowerCase 转换为小写 9.concat 拼接字符串 10.replace 替换字符串中的字符 11.split分割字符串 对于某些分割字符,我们需要转义字符 \\ |等 12.toCharArray 转成字符数组 13.compareTo比较两个字符串的大小。前者大返回正数 后者大返回负数 14.format 格式字符串
package StringMethod;
public class StringMethod01 {
public static void main(String[] args) {
//1.equals 方法:比较字符串大小
String str1 = "hello";
String str2 = "Hello";
System.out.println(str2.equals(str1));
//2.equalsIgnoreCase 忽略大小写 判断内容是否相等
String username = "john";
if ("john".equalsIgnoreCase(username)) {
System.out.println("Success");
} else {
System.out.println("fuilure");
}
//3. length 返回此字符串s1的长度
String s1 = "hello";
int c = s1.length();
System.out.println(c);
//4. indexOf 返回指定字符ch在字符串中第一次出现位置的索引
int A = s1.indexOf("l");
System.out.println(A);
//5. 返回指定字符ch在字符串中最后一次出现位置的索引
int B = s1.lastIndexOf("l");
System.out.println(B);
//6.substring 截取制定范围的子串
String name ="hello li";
System.out.println(name.substring(3));//截取后面的字符
System.out.println(name.substring(2,5));//llo
// char a=s1.charAt(0);//返回字符串中index位置上的字符,其中index的取值范围是0~(字符串长度是-1)
// System.out.println(a);
// Boolean b= s1.endsWith("o");//判断此字符串是否以指定的字符串结尾
// System.out.println(b);
//7.toUpperCase 转换大写
String s = "hello";
System.out.println(s.toUpperCase());//HELLO
//8.toLowerCase 转换为小写
System.out.println(s.toLowerCase());
//9.concat 拼接字符串
String s1 = "宝玉和";
s1 = s1.concat("林黛玉").concat("在一起");
System.out.println(s1);
//10.replace 替换字符串中的字符
s1 = "宝玉和黛玉,黛玉和宝玉";
s1 = s1.replace("黛玉", "宝钗");//若用s2接收s1.replace 那么s1不变
System.out.println(s1);
//11.split分割字符串 对于某些分割字符,我们需要转义字符 \\ |等
String poem = "离离原上草,一岁一枯荣,野火烧不尽,春风吹又生";
String[] split = poem.split(",");//,为分隔符
poem = "E:\\aaa\\bbb";
split = poem.split("\\\\");//用\\转义\\,并进行分割
System.out.println("====这首诗的内容是=====");
for (int i = 0; i < split.length; i++) {
System.out.println(split[i]);
}
//12.toCharArray 转成字符数组
String x = "happy";
char[] chs = x.toCharArray();
for (int i = 0; i < chs.length; i++) {
System.out.println(chs[i]);
}
//13.compareTo比较两个字符串的大小。前者大返回正数 后者大返回负数
String a = "john";
String b = "jonn";
System.out.println(a.compareTo(b));
//14.format 格式字符串
/*占位符有:
* %s 字符串 %从字符 %d 整形 %.2f 浮点型
*%s %d %.2f 成为占位符
*/
String name = "john";
int age = 10;
double score = 98.3 / 3;
String info = "我的姓名是" + name + ",成绩是" + score
+ "希望大家喜欢我";
String info2 = String.format("我的姓名是%s 年龄是%d 成绩是%.2f ,希望大家喜欢",name,age,score);
System.out.println(info);
System.out.println(info2);
}
}
StringBuffer类
StringBuffer引入
StringBuffer是一个字符串缓冲区,可以理解为字符串的容器
java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删
很多方法与String相同,但StringBuffer是可变长度的
理解StringBuffer
1)StringBuffer的直接父类是AbstractStringBuilder
2)StringBuffer实现了Serializable,即StringBuffer的对象可以串行化。
3)在父类中AbstractStringBuilder有属性char[ ]value,不是final 该value数组存放字符串内容,
字符序列在堆中
4)StringBuffer是一个final 类,不能被继承
5)因为StringBuffer字符内容是存在char[]value 所有在变化(增加、删除,修改)不用每次 都更改地址,所以效率远高String
String VS StringBuffer
1)String 保存的是字符串常量,里面的值不能更改。
每次String类的更新实际上就是更改地址,效率较低
2)StringBuffer保存的是字符串变量,里面的值可以更改,
每次StringBuffer的更新实际上可以更新内容,不用每次更新地址,效率高
String和StringBuffer相互转换
public class StringAndStringBuffer {
public static void main(String[] args) {
//String——>StringBuffer
String str = "hello tom";
//方式1 使用构造器
//注意: 返回的才是StringBuffer对象,对str 本身没有影响
StringBuffer stringBuffer = new StringBuffer(str);
//方式2 使用的是append方法
StringBuffer stringBuffer1 = new StringBuffer();
stringBuffer1 = stringBuffer1.append(str);
//StringBuffer ->String
StringBuffer stringBuffer3 = new StringBuffer("xr");
//方式1 使用StringBuffer提供的 toString方法
String s = stringBuffer3.toString();
//方式2: 使用构造器来搞定
String s1 = new String(stringBuffer3);
}
}
StrringBuffer类常见方法
public class StringBufferMethod {
public static void main(String[] args) {
StringBuffer s = new StringBuffer("hello");
//增
s.append(',');// "hello,"
s.append("张三丰");//"hello,张三丰"
s.append("赵敏").append(100).append(true).append(10.5);//"hello,张三丰赵敏100true10.5"
System.out.println(s);//"hello,张三丰赵敏100true10.5"
//删
/*
* 删除索引为>=start && <end 处的字符
* 解读: 删除 11~14的字符 [11, 14)
*/
s.delete(11, 14);
System.out.println(s);//"hello,张三丰赵敏true10.5"
//改
//使用 周芷若 替换 索引9-11的字符 [9,11)
s.replace(9, 11, "周芷若");
System.out.println(s);//"hello,张三丰周芷若true10.5"
//查找指定的子串在字符串第一次出现的索引,如果找不到返回-1
int indexOf = s.indexOf("张三丰");
System.out.println(indexOf);//6
//插
//老韩解读,在索引为9的位置插入 "赵敏",原来索引为9的内容自动后移
s.insert(9, "赵敏");
System.out.println(s);//"hello,张三丰赵敏周芷若true10.5"
//长度
System.out.println(s.length());//22
System.out.println(s);
}
}
例题:价格的小数点前面每三位用逗号隔开,在输出
package StringMethod;
/**
* 希望使用StringBuffer的insert,需要将String 转成StringBuffer
* 然后使用相关方法进行字符串处理
*/
public class StringBufferExample02 {
public static void main(String[] args) {
String price ="1234443.59";
StringBuffer sb =new StringBuffer(price);
//先完成一个最简单的实现1234443.59
//找到小数点位置的前三位插入,即可
// int i = sb.indexOf(".");
// sb=sb.insert(i-3,",");
//上面两部需要做一个循环
for (int i = sb.lastIndexOf(".") ; i >3; i-= 3) {
sb= sb.insert(i-3,",");
}
System.out.println(sb);
}
}
StringBuilder类
1)一个可变字符序列,此类提供一个与StringBuffer兼容的API,但不保证同步(StringBuilder不是线程安全)。该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的使用。如果可能,建议优先采用该类因为在大多数现实中,他比StringBuffer快
2)在StringBuilder上主要操作是append和insert方法,可以重载这些方法,以接收任何类型的数据
理解
1)StringBuilder的直接父类是AbstractStringBuilder
2)StringBuilderr实现了Serializable,即StringBuilder的对象可以串行化。
3)在父类中AbstractStringBuilder有属性char[ ]value,不是final 该value数组存放字符串内容,
字符序列存放在堆中
4)StringBuilder是一个final 类,不能被继承
5)StringBuilder的方法,没有互斥的处理,即没有synchronized关键字,因此在单线程的情 况下使用StringBuilder
6)StringBuilder方法类似于StringBuffer
String VS StringBuffer VS StringBuilder
1)String:不可变字符序列,效率低,但是复用效率高
2)StringBuffer:可变字符序列,效率高,线程安全
3)StringBuilder:可变字符序列,效率高,线程不安全
如果单线程,字符串存在大量修改操作,使用StringBuilder
如果多线程,字符串存在大量修改操作,使用StringBuffer
如果字符串很少修改,被多个对象引用,使用String,比如配置信息等
Math类
常见方法
1)abs绝对值
2)pow 求幂
3)ceil向上取整
4)floor向下取整
5)round四舍五入
6)sqrt求开方
7)random 求随机数
8)max求两个数的最大值
9)min求两个数的最小值
package MathMethod;
public class MathTest {
public static void main(String[] args) {
int a=5;
double b =6.4;
double c=-5.9;
System.out.println(Math.abs(c));//该方法用于计算绝对值
System.out.println(Math.max(5,9));//该方法用于计算两个数的较大值
System.out.println(Math.min(5,9));//该方法用于计算两个数的较小值
System.out.println(Math.round(b));//该方法用于计算小数进行四舍五入后的结果
System.out.println(Math.random());//该方法用于生成一个大于0.0小于1.0的随机值
System.out.println(Math.sqrt(4));//该方法用于计算方根
System.out.println(Math.pow(2,5));//该方法用于计算指数函数的值,b是幂
System.out.println(Math.ceil(b));//该方法用于计算大于参数的最小整数
System.out.println(Math.floor(b));//该方法用于计算小于参数的最小整数
//扩展
/*
* random返回的是0<=x<1之间的一个随机小数
* 思考:请获取一个 a-b 之间的一个随机数
* 即返回一个x 2<=x<=7
* */
//返回a-b之间一个整数的公式是 (int)(a+ Math.random()*(b-a+1))
//int a <=x <= ()int (a+ Math.random() * (b-a+1))
//Math.random()*6 返回的是2<=x<6的数
//+2 返回的是2<=x<8的数
//最后有一个小数取整因为7.多取整为7 即为2<=x<=7
for(int i =0; i<10; i++){
System.out.println(2+Math.random()*(7-2+1));
}
}
}
Arrays类
常用方法
1)toString 返回数组的字符串形式
2)sort排序
3)binarySearch通过二分搜索法进行查找,要求必须排序
4)copyOf数组元素复制
5)fill数组元素的填充
6)equals比较两个数组元素内容是否完全一致
7)asList 将一组值,转换成list
sort方法例题(较难)
package 包装类.Arrays;
import java.util.Arrays;
import java.util.Comparator;
public class sort方法 {
public static void main(String[] args) {
Integer[] integers = {1, 20, 90};
//遍历数组
for(int i = 0; i < integers.length; i++) {
System.out.print(integers[i]+"\t");
}
System.out.println("\n");
//直接使用Arrays.toString方法,显示数组
System.out.println(Arrays.toString(integers));
//演示 sort方法的使用
Integer arr[] = {1, -1, 7, 0, 89};
//进行排序
//老韩解读
//1. 可以直接使用冒泡排序 , 也可以直接使用Arrays提供的sort方法排序
//2. 因为数组是引用类型,所以通过sort排序后,会直接影响到 实参 arr
//3. sort重载的,也可以通过传入一个接口 Comparator 实现定制排序
//4. 调用 定制排序 时,传入两个参数 (1) 排序的数组 arr
// (2) 实现了Comparator接口的匿名内部类 , 要求实现 compare方法
//5. 先演示效果,再解释
//6. 这里体现了接口编程的方式 , 看看源码,就明白
// 源码分析
//(1) Arrays.sort(arr, new Comparator()
//(2) 最终到 TimSort类的 private static <T> void binarySort(T[] a, int lo, int hi, int start,
// Comparator<? super T> c)()
//(3) 执行到 binarySort方法的代码, 会根据动态绑定机制 c.compare()执行我们传入的
// 匿名内部类的 compare ()
// while (left < right) {
// int mid = (left + right) >>> 1;
// if (c.compare(pivot, a[mid]) < 0)
// right = mid;
// else
// left = mid + 1;
// }
//(4) new Comparator() {
// @Override
// public int compare(Object o1, Object o2) {
// Integer i1 = (Integer) o1;
// Integer i2 = (Integer) o2;
// return i2 - i1;
// }
// }
//(5) public int compare(Object o1, Object o2) 返回的值>0 还是 <0
// 会影响整个排序结果, 这就充分体现了 接口编程+动态绑定+匿名内部类的综合使用
// 将来的底层框架和源码的使用方式,会非常常见
//Arrays.sort(arr); // 默认排序方法
//定制排序
Arrays.sort(arr, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
Integer i1 = (Integer) o1;
Integer i2 = (Integer) o2;
return i2 - i1;
}
});
System.out.println("===排序后===");
System.out.println(Arrays.toString(arr));//
}
}
冒泡排序
package 包装类.Arrays;
import java.util.Arrays;
import java.util.Comparator;
public class bubble {
public static void main(String[] args) {
int[] arr = {1, -1, 8, 0, 20};
//bubble01(arr);
bubble02(arr, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
int i1 = (Integer) o1;
int i2 = (Integer) o2;
return i2 - i1;// return i2 - i1;
}
});
System.out.println("==定制排序后的情况==");
System.out.println(Arrays.toString(arr));
}
//使用冒泡完成排序
public static void bubble01(int[] arr) {
int temp = 0;
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
//从小到大
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
//结合冒泡 + 定制
public static void bubble02(int[] arr, Comparator c) {
int temp = 0;
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
//数组排序由 c.compare(arr[j], arr[j + 1])返回的值决定
if (c.compare(arr[j], arr[j + 1]) > 0) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
}
其他的方法
package ArragsMethod;
import java.util.Arrays;
import java.util.List;
public class ArrayMethod2 {
public static void main(String[] args) {
//使用二分查找 binarySearch
Integer arr[]={1,55,88,798,5462,85246};
int index = Arrays.binarySearch(arr,55);
System.out.println("index = "+index);
//查找不存在的数字 会index = -1
//不可以使用在没有排序好的数组中 index = 负数
//实现数组元素拷贝 copyOf
Integer[] arr2 = Arrays.copyOf(arr, arr.length);
System.out.println("复制完成啦" + "哈哈哈");
System.out.println(Arrays.toString(arr2));
//实现数组的填充
Integer[] num =new Integer[]{1,5 ,9};
Arrays.fill(num,99);
System.out.println(Arrays.toString(num));
//数组的比较
boolean equals =Arrays.equals(arr,arr2);
System.out.println(equals);
//asList 将一组值,转换成list
//1. asList方法,会将 (2,3,4,5,6,1)数据转成一个List集合
//2. 返回的 asList 编译类型 List(接口)
//3. asList 运行类型 java.util.Arrays#ArrayList, 是Arrays类的
// 静态内部类 private static class ArrayList<E> extends AbstractList<E>
// implements RandomAccess, java.io.Serializable
List asList = Arrays.asList(2,3,4,5,6,1);
System.out.println("asList=" + asList);
System.out.println("asList的运行类型" + asList.getClass());
}
}
import java.util.Arrays;
import java.util.Comparator;
public class ArrayExercise {
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("青年文摘20年", 5);
books[3] = new Book("java从入门到放弃~", 300);
//(1)price从大到小
// Arrays.sort(books, new Comparator() {
// //这里是对Book数组排序,因此 o1 和 o2 就是Book对象
// @Override
// public int compare(Object o1, Object o2) {
// Book book1 = (Book) o1;
// Book book2 = (Book) o2;
// double priceVal = book2.getPrice() - book1.getPrice();
// //这里老师进行了一个转换
// //如果发现返回结果和我们输出的不一致,就修改一下返回的 1 和 -1
// if(priceVal > 0) {
// return 1;
// } else if(priceVal < 0) {
// return -1;
// } else {
// return 0;
// }
// }
// });
//(2)price从小到大
// Arrays.sort(books, new Comparator() {
// //这里是对Book数组排序,因此 o1 和 o2 就是Book对象
// @Override
// public int compare(Object o1, Object o2) {
// Book book1 = (Book) o1;
// Book book2 = (Book) o2;
// double priceVal = book2.getPrice() - book1.getPrice();
// //这里老师进行了一个转换
// //如果发现返回结果和我们输出的不一致,就修改一下返回的 1 和 -1
// if(priceVal > 0) {
// return -1;
// } else if(priceVal < 0) {
// return 1;
// } else {
// return 0;
// }
// }
// });
//(3)按照书名长度从大到小
Arrays.sort(books, new Comparator() {
//这里是对Book数组排序,因此 o1 和 o2 就是Book对象
@Override
public int compare(Object o1, Object o2) {
Book book1 = (Book) o1;
Book book2 = (Book) o2;
//要求按照书名的长度来进行排序
return book2.getName().length() - book1.getName().length();
}
});
System.out.println(Arrays.toString(books));
}
}
class Book {
private String name;
private double price;
public Book(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 "Book{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
}
System类
常见方法
1)exit:退出当前程序
2)arraycopy:复制数组元素,比较适合底层调用,一般使用Arrays.copyOf完成复制数组
3)currentTimeMillens:返回当前时间距离1970 - 1-1的毫秒数
4)gc:运行垃圾回收机制System.gc();
例题
import java.util.Arrays;
public class System_ {
public static void main(String[] args) {
//exit 退出当前程序
// System.out.println("ok1");
// //理解
// //1. exit(0) 表示程序退出
// //2. 0 表示一个状态 , 正常的状态
// System.exit(0);//
// System.out.println("ok2");
//arraycopy :复制数组元素,比较适合底层调用,
// 一般使用Arrays.copyOf完成复制数组
int[] src={1,2,3};
int[] dest = new int[3];// dest 当前是 {0,0,0}
理解:
//1. 主要是搞清楚这五个参数的含义
//2.
// 1)源数组
// * @param src the source array.
// 2)srcPos: 从源数组的哪个索引位置开始拷贝
// * @param srcPos starting position in the source array.
// 3)dest : 目标数组,即把源数组的数据拷贝到哪个数组
// * @param dest the destination array.
// 4)destPos: 把源数组的数据拷贝到 目标数组的哪个索引
// * @param destPos starting position in the destination data.
// 5)length: 从源数组拷贝多少个数据到目标数组
// * @param length the number of array elements to be copied.
System.arraycopy(src, 0, dest, 0, src.length);
// int[] src={1,2,3};
System.out.println("dest=" + Arrays.toString(dest));//[1, 2, 3]
//currentTimeMillens:返回当前时间距离1970-1-1 的毫秒数
System.out.println(System.currentTimeMillis());
}
}
BigInteger和BigDecimal类
理解:
BigInteger:适合保存比较大的整型
BigDecimal适合保存精度更高的浮点数
常见方法:
1)add 加
2)subtract 减
3)multiply 乘
4)divide 除
例题
保存一个精度很高的数
package bignum;
import java.math.BigDecimal;
public class BigDecimal_ {
public static void main(String[] args) {
//当我们需要保存一个精度很高的数时,double 不够用
//可以是 BigDecimal
double d = 1999.11111111111999999999999977788d;
System.out.println(d);
BigDecimal bigDecimal = new BigDecimal("1999.11");
BigDecimal bigDecimal2 = new BigDecimal("3");
System.out.println(bigDecimal);
//1. 如果对 BigDecimal进行运算,比如加减乘除,需要使用对应的方法
//2. 创建一个需要操作的 BigDecimal 然后调用相应的方法即可
System.out.println(bigDecimal.add(bigDecimal2));
System.out.println(bigDecimal.subtract(bigDecimal2));
System.out.println(bigDecimal.multiply(bigDecimal2));
//System.out.println(bigDecimal.divide(bigDecimal2));//可能抛出异常ArithmeticException
//在调用divide 方法时,指定精度即可. BigDecimal.ROUND_CEILING
//如果有无限循环小数,就会保留 分子 的精度
System.out.println(bigDecimal.divide(bigDecimal2, BigDecimal.ROUND_CEILING));
}
}
保存一个很大的整数
package bignum;
import java.math.BigInteger;
public class BigInteger_ {
public static void main(String[] args) {
//当我们编程中,需要处理很大的整数,long 不够用
//可以使用BigInteger的类来搞定
// long l = 23788888899999999999999999999l;
// System.out.println("l=" + l);
BigInteger bigInteger = new BigInteger("23788888899999999999999999999");
BigInteger bigInteger2 = new BigInteger("10099999999999999999999999999999999999999999999999999999999999999999999999999999999");
System.out.println(bigInteger);
//1. 在对 BigInteger 进行加减乘除的时候,需要使用对应的方法,不能直接进行 + - * /
//2. 可以创建一个 要操作的 BigInteger 然后进行相应操作
BigInteger add = bigInteger.add(bigInteger2);
System.out.println(add);//
BigInteger subtract = bigInteger.subtract(bigInteger2);
System.out.println(subtract);//减
BigInteger multiply = bigInteger.multiply(bigInteger2);
System.out.println(multiply);//乘
BigInteger divide = bigInteger.divide(bigInteger2);
System.out.println(divide);//除
}
}
日期类
第一代日期类
1) Date:精确到毫秒,代表特定的瞬间
2)SimpleDateFormat:格式和解析日期的类
SimpleDateFormat:格式和解析日期的类
package DateMethod;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 第一代日期表示方法
*/
public class date_ {
public static void main(String[] args) throws ParseException {
Date date = new Date();
System.out.println(date);
//Date的空构造器输出的是当前时间
//这里的Date类是java.util包
//默认输出的日期格式是国外方式
//通过以下方法来改为国内时间
//1。创建SimpleDateFormat对象,可以指定相应格式
SimpleDateFormat sim = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");
//将日期装换成指定格式的字符串
String format =sim.format(date);
System.out.println(format);
//可以把一个格式化的String 转换成时间
String a ="1332年09n月04日 15:08:36 星期三";
Date parse =sim.parse(a);
System.out.println("parse= "+sim.format(parse));
}
}
第二代日期类
package DateMethod;
import java.util.Calendar;
/**
* 第二代日期表示方法
* 不足:存在线程安全问题 不能格式化 月份是从零开始 日期和时间应该是可变的类
*/
public class Calendar_ {
public static void main(String[] args) {
//1.Calendar是一个抽象类 构造器是私有的
//2.通过getInstance来获取实例
//3.月从零开始编号所以需要加一
//4.如果需要二十四小时的进制方法 可以把 c.get(Calendar.HOUR)改为c.get(Calendar.HOUR_OF_DAY)
Calendar c =Calendar.getInstance();
System.out.println(c);
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.HOUR));
System.out.println("分钟"+c.get(Calendar.MINUTE));
System.out.println("秒"+c.get(Calendar.SECOND));
//Calendar没有提供专门的格式化方法 需要程序员自己组合
System.out.println(c.get(Calendar.YEAR)+"年"+(c.get(Calendar.MONTH)+1)+"月"+
c.get(Calendar.DAY_OF_MONTH)+"日");
}
}
第三类日期类
1)LocalDate(日期、年月日),LocalTime(时间、时分秒),LocalDateTime(日期时间/年月日时分秒)在jdk8加入
2)DateTimeFormatter格式日期类
3)Instant时间戳
4)第三类也有很多方法(见例题二)
package DateMethod;
import java.time.Instant;
import java.util.Date;
/**
* 时间戳
*/
public class InstantTest {
public static void main(String[] args) {
//从系统时钟获取时间戳对象
Instant now= Instant.now();
System.out.println(now);
//2.通过from可以把Instanct转成Date
Date date = Date.from(now);//返回的是usa的时
System.out.println(date);
//3.通过date的toInstant()可以把date 转成Instant对象
Instant instant = date.toInstant();
System.out.println(instant);
// //计算机原年加上
System.out.println(Instant.ofEpochSecond(5));//5秒
//在当前时间加上
Instant instant1 = now.plusMillis(60000);//60000毫秒
System.out.println(instant1);
//2007-12-15T10:35:12Z到现在时间的秒数
System.out.println(Instant.parse("2007-12-15T10:35:12.44Z").getEpochSecond());
//
}
}
package DateMethod;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
/**
* 第三代日期类
* localdate (日期) localTime(时间) localDateTime(时间和日期都包含)
*/
public class LocalDateTEST {
public static void main(String[] args) {
LocalDateTime date = LocalDateTime.now();//创建日期类
System.out.println(date);
System.out.println(date.getYear()); //获取当前的年份
LocalTime now =LocalTime.now();//创建时间类
System.out.println(now);
//使用DateTimeFormatter对象进行格式化
//1.创建一个格式化对象
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 hh:mm:ss E");
String format = date.format(formatter);
System.out.println(format);
LocalDateTime date1 = LocalDateTime.of(2020, 10, 12,23,56);
System.out.println(date1);
System.out.println(date.getDayOfMonth());//获取当月第几天字段
System.out.println(date.getDayOfYear());//获取当年第几天字段
System.out.println(date.isAfter(date1));//检查此日期是否在指定日期之后。
System.out.println(date.plusDays(3));//增加指定日数
System.out.println(date.getMonthValue());//将月份字段从1到12
}
}
课后习题
课后习题一
package Homework_;
public class Homework01 {
public static void main(String[] args) {
/*
* 反转字符串
* 编写方法 public static String reverse(String str,int start,int end)搞定
* 1.先把方法确定
* 2.把String 转换成char数组 因为char数组里面的元素可以交换
* 3.代码实现
* */
String str ="4816364632";
System.out.println("==========交换前=======");
System.out.println(str);
try {
str= reverse(str,0,9);
} catch (Exception e) {
System.out.println(e.getMessage());
return;
}
System.out.println("=========交换后========");
System.out.println(str);
}
public static String reverse(String str, int start,int end){
if(!(str!=null && start>=0 && end>start && end<str.length())){
throw new RuntimeException("参数不正确");
}
char[]arr =str.toCharArray();
char temp =' ';
for (int i = start ,j=end; i < j; i++,j--) {
temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
return new String(arr);
}
}
课后习题二
package Homework_;
/**
* 输入用户名,密码,邮箱,如果信息正确,则注册成功,否则失败
* 要求:
* 1.用户者长度为2,或3或者4
* 2.密码长度为6,并且都为数字
* 3.邮箱中包含@和。 并且@在。之前
*
*
*/
public class Homework02 {
public static void main(String[] args) {
/*
* 思路分析
* 先编写方法userReginster(String name ,String pwd,String email){}
* 如果发现问题抛出异常 并给出提示
* 单独写一个方法 判断字符串里是否都是数字
* */
String name ="jack";
String pwd ="124348 ";
String email ="jack@shouhu.com";
try {
userReginster(name,pwd,email);
System.out.println("恭喜你 注册成功");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public static void userReginster(String name, String pwd, String email) {
//第一关 长度
int username = name.length();
if (!(name.length() >= 2 && name.length() <= 4)) {
throw new RuntimeException("用户名长度不对");
}
//第二关
if (!(pwd.length()==6 && isDigital(pwd))) {
throw new RuntimeException("密码长度为6,并且都为数字");
}
//第三关
int i =email.indexOf('@');
int j =email.indexOf('.');
if (!(i>0 && i<j)){
throw new RuntimeException("邮箱格式错误");
}
}
public static boolean isDigital (String str){
char[] chars = str.toCharArray();
for (int i = 0; i < chars.length; i++) {
if (chars[i] < '0' || chars[i] > '9') {
return false;
}
}return true;
}
}
课后习题三
package Homework_;
/**
* 特定的顺序规则
* Tai ku La 输出为 La Tai K
*/
public class Homework03 {
public static void main(String[] args) {
String arr="Tai ku La";
print(arr);
}
public static void print(String str){
if(str == null){
System.out.println("str 不能为空");
}
String names[]=str.split(" ");
if (names.length!= 3){
System.out.println("输入格式错误");
return;
}
String format =String.format("%s %s %c",names[2],names[0],names[1].toUpperCase().charAt(0));
System.out.println(format);
}
}
课后习题四
package Homework_;
/**
* 判断字符串中 有多少个大写字母 小写字母 多少个数字
*/
public class Homework04 {
public static void main(String[] args) {
String str ="4548dfgsdihbIOFDSHGOIS";
countStr(str);
}
public static void countStr(String str){
if(str ==null){
System.out.println("输入不为空");
return;
}
int numCount=0;
int lowerCount=0;
int upperCount=0;
for (int i = 0; i < str.length(); i++) {
if(str.charAt(i)>='0'&&str.charAt(i)<='9'){
numCount++;
} else if (str.charAt(i)>='a'&&str.charAt(i)<='z') {
lowerCount++;
}else if(str.charAt(i)>='A'&&str.charAt(i)<='Z'){
upperCount++;
}
}
System.out.println("数字有"+numCount);
System.out.println("小写字母有"+lowerCount);
System.out.println("大写字母有"+upperCount);
}
}