目录
String、StringBuffer 和 StringBuilder 的比较
String、StringBuffer 和 StringBuilder 的效率测试
currentTimeMillens,返回当前时间距离1970-1-1 的毫秒数
String 类的常见方法
重复的开辟空间,创建对象,效率低。
但是某些情况下开始非常实用的,比如做一些配置文件,用String做一些常量的值都是非常实用的,所以我们也要学String,下面我们介绍一些String的常用的方法。
第一部分
1.equals区分大小写的内容相等
public class StringMethod01 { public static void main(String[] args) { //1. equals 前面已经讲过了. 比较内容是否相同,区分大小写 String str1 = "hello"; String str2 = "Hello"; System.out.println(str1.equals(str2));// } }
2.equalsTgnoreCase忽略大小写的内容相等
public class StringMethod01 { public static void main(String[] args) { // 2.equalsIgnoreCase 忽略大小写的判断内容是否相等 String username = "johN"; if ("john".equalsIgnoreCase(username)) { System.out.println("Success!"); } else { System.out.println("Failure!"); } } }
3.length 获取字符的个数,字符串的长度
public class StringMethod01 { public static void main(String[] args) { // 3.length 获取字符的个数,字符串的长度 System.out.println("杰克".length()); } }
4.indexOf 获取字符第一次出现的索引
indexOf 获取字符在字符串对象中第一次出现的索引,索引从0开始,如果找不到,返回-1
public class StringMethod01 { public static void main(String[] args) { // 4.indexOf 获取字符在字符串对象中第一次出现的索引,索引从0开始,如果找不到,返回-1 String s1 = "wer@terwe@g"; int index = s1.indexOf('@'); System.out.println(index);// 3 System.out.println("weIndex=" + s1.indexOf("we"));//0 } }
5.lastIndexOf 获取字符最后一次出现的索引
lastIndexOf 获取字符在字符串中最后一次出现的索引,索引从0开始,如果找不到,返回-1
public class StringMethod01 { public static void main(String[] args) { // 5.lastIndexOf 获取字符在字符串中最后一次出现的索引,索引从0开始,如果找不到,返回-1 String s1 = "we@ter@g@"; int index = s1.lastIndexOf('@'); System.out.println(index);//11 System.out.println("ter的位置=" + s1.lastIndexOf("ter")); } }
6.substring 截取指定范围的子串
public class StringMethod01 { public static void main(String[] args) { // 6.substring 截取指定范围的子串 String name = "hello,张三"; //下面name.substring(6) 从索引6开始截取后面所有的内容 System.out.println(name.substring(6));//截取后面的字符 //name.substring(0,5)表示从索引0开始截取,截取到索引 5-1=4位置 System.out.println(name.substring(2,5));//llo } }
第二部分
1.toUpperCase转换成大写
public class StringMethod02 { public static void main(String[] args) { // 1.toUpperCase转换成大写 String s = "heLLo"; System.out.println(s.toUpperCase());//HELLO } }
2.toLowerCase转换成小写
public class StringMethod02 { public static void main(String[] args) { // 2.toLowerCase String s = "heLLo"; System.out.println(s.toLowerCase());//hello } }
3.concat拼接字符串
public class StringMethod02 { public static void main(String[] args) { // 3.concat拼接字符串 String s1 = "宝玉"; s1 = s1.concat("林黛玉").concat("薛宝钗").concat("together"); System.out.println(s1);//宝玉林黛玉薛宝钗together } }
4.replace 替换字符串中的字符
public class StringMethod02 { public static void main(String[] args) { // 4.replace 替换字符串中的字符 String s1 = "宝玉 and 林黛玉 林黛玉 林黛玉"; // 解读: s1.replace() 方法执行后,返回的结果才是替换过的. // 注意对 s1没有任何影响 String s2 = s1.replace("宝玉", "jack"); System.out.println(s1);//宝玉 and 林黛玉 林黛玉 林黛玉 System.out.println(s2);//jack and 林黛玉 林黛玉 林黛玉 } }
5.split 分割字符串,
对于某些分割字符,我们需要 转义比如 | \\等
public class StringMethod02 { public static void main(String[] args) { // 5.split 分割字符串, 对于某些分割字符,我们需要 转义比如 | \\等 String poem = "锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦"; // 1. 以 , 为标准对 poem 进行分割 , 返回一个数组 String[] split = poem.split(","); System.out.println("==分割后内容==="); for (int i = 0; i < split.length; i++) { System.out.println(split[i]); } } }
public class StringMethod02 { public static void main(String[] args) { // 5.split 分割字符串, 对于某些分割字符,我们需要 转义比如 | \\等 //老韩解读: // 1. 以 , 为标准对 poem 进行分割 , 返回一个数组 // 2. 在对字符串进行分割时,如果有特殊字符,需要加入 转义符\ String poem = "E:|aaa|bbb"; String[] split = poem.split("\\|"); System.out.println("==分割后内容==="); for (int i = 0; i < split.length; i++) { System.out.println(split[i]); } } }
public class StringMethod02 { public static void main(String[] args) { // 5.split 分割字符串, 对于某些分割字符,我们需要 转义比如 | \\等 //老韩解读: // 1. 以 , 为标准对 poem 进行分割 , 返回一个数组 // 2. 在对字符串进行分割时,如果有特殊字符,需要加入 转义符\ String poem = "E:||aaa||bbb"; String[] split = poem.split("\\|\\|"); System.out.println("==分割后内容==="); for (int i = 0; i < split.length; i++) { System.out.println(split[i]); } } }
public class StringMethod02 { public static void main(String[] args) { // 5.split 分割字符串, 对于某些分割字符,我们需要 转义比如 | \\等 //老韩解读: // 1. 以 , 为标准对 poem 进行分割 , 返回一个数组 // 2. 在对字符串进行分割时,如果有特殊字符,需要加入 转义符\ String poem = "E:\\aaa\\bbb"; String[] split = poem.split("\\\\"); System.out.println("==分割后内容==="); for (int i = 0; i < split.length; i++) { System.out.println(split[i]); } } }
6.toCharArray 转换成字符数组
public class StringMethod02 { public static void main(String[] args) { // 6.toCharArray 转换成字符数组 String s = "happy"; char[] chs = s.toCharArray(); for (int i = 0; i < chs.length; i++) { System.out.print(chs[i]); } } }
7.compareTo 比较两个字符串的大小
如果前者大, 则返回正数,后者大,则返回负数,如果相等,返回0。
看看方法它怎么来的(了解一下)
我们先看compareTo()方法的源码。
public int compareTo(String anotherString) { int len1 = value.length; int len2 = anotherString.value.length; int lim = Math.min(len1, len2); char v1[] = value; char v2[] = anotherString.value; int k = 0; while (k < lim) { char c1 = v1[k]; char c2 = v2[k]; if (c1 != c2) { return c1 - c2; } k++; } return len1 - len2; }
源码分析:先得到两个字符串的长度,然后选字符串的长度数为循环次数,比较两个字符串的每一位字符,如果相同就比较下一个字符,如果不同就返回,返回值是它们俩ASCII码的差值。如果比到最后所有的字符都比完了,还是没有比出来就返回两个字符串长度的差。
下面看代码:
public class StringMethod02 { public static void main(String[] args) { // 7.compareTo 比较两个字符串的大小,如果前者大, // 则返回正数,后者大,则返回负数,如果相等,返回0 // 解读 // (1) 如果长度相同,并且每个字符也相同,就返回 0 // (2) 在逐一字符进行比较时,可以区分大小, // 就返回ASCII码的差值 if (c1 != c2) { // return c1 - c2; // } // (3) 如果前面的部分都相同,就返回字符串长度的差值 str1.len - str2.len String a = "7aaaa55"; String b = "7aa"; //返回字符串长度的差值 String n = "adk"; String m = "aattk"; //第一位字符相同,返回的第二位字符是ACSSI码值的差值 System.out.println(a.compareTo(b)); // 返回值是 '7' - '3' = 4的值 System.out.println(n.compareTo(m));// 返回值是 'd' - 'a' = 3的值 } }
8.format 格式字符串
String name = "john"; int age = 10; double score = 56.857; char gender = '男'; //将所有的信息都拼接在一个字符串. String info = "我的姓名是" + name + "年龄是" + age + ",成绩是" + score + "性别是" + gender + "。希望大家喜欢我!"; System.out.println(info);
这样写比较笨拙。我们下面用format:
public class StringMethod02 { public static void main(String[] args) { // 8.format 格式字符串 String name = "john"; int age = 10; double score = 95.575; char gender = '男'; //解读 //1. %s , %d , %.2f %c 称为占位符 //2. 这些占位符由后面变量来替换 //3. %s 表示后面由 字符串来替换 //4. %d 是整数来替换 //5. %.2f 表示使用小数来替换,替换后,只会保留小数点两位, 并且进行四舍五入的处理 //6. %c 使用char 类型来替换 String formatStr = "我的姓名是%s 年龄是%d,成绩是%.2f 性别是%c.希望大家喜欢我!"; String info = String.format(formatStr, name, age, score, gender); System.out.println(info); } }
1. %s , %d , %.2f %c 称为占位符
2. 这些占位符由后面变量来替换
3. %s 表示后面由 字符串来替换
4. %d 是整数来替换
5. %.2f 表示使用小数来替换,替换后,只会保留小数点两位, 并且进行四舍五入的处理
6. %c 使用char 类型来替换
StringBuffer 类
1. StringBuffer 的直接父类 是 AbstractStringBuilder。
2. StringBuffer 实现了 Serializable, 即StringBuffer的对象可以串行化。
3. 在StringBuffer的父类AbstractStringBuilder中有属性 char[] value,不是final,该 value 数组存放字符串内容,value 数组存放在堆中的。
4. StringBuffer 是一个 final类,不能被继承。String 和 StringBuffer对比
String是在堆里面有个地址,也是value[],value[]指向的是常量池,比如指向的是常量池中的hello。一旦修改String的内容,比如说在hello后面加了一个i,在常量池里面可不是直接在hello后面加了一个i,而是重新创建了一个helloi,原来的hello不变化,然后让value[]重新指向的是常量池中的helloi。
代码表示就是:
String string = "hello"; string ="helloi";
这样就很复杂,string频繁修改内容,常量池也重新产生一个值,让value[]重新指向常量池的值。 StringBuffer 有缓冲机制或者扩容机制,不需要每次更新。效率高很多。
怎么去理解不用每次更新地址?
首先我们的value[ ]数组的值是放在堆里的,value[ ]数组指向堆里一块空间,比如里面存放的是hello,如果你想存helloi,那么它就在hello后面给你加i,当这个内存空间满了,会给分配一个更大的内存空间,然后拿然后的内容复制进去,然后value[]数组再指向这个大的内存空间。
就是在内容在增加或删除时,不用每次都更换地址(即不是每次都创建新对象), 所以效率高于 String。
StringBuffer的构造器
1. 上面第一个StringBuffer()构造方法的字符串缓冲区的初始容量为16。
下面我们用代码调试追踪的方法去证明:
2.第二个构造器用的不多,我们演示第三个构造器
还是用代码调试追踪一下:
3.
还是用代码调试追踪一下,看一下这种构造器给我们怎么样分配内存的:
String 和 StringBuffer 相互转换
String----->StringBuffer
方式1 使用StringBuffer提供的构造器
public class StringAndStringBuffer { public static void main(String[] args) { String str = "hello tom"; //方式1 使用构造器 //注意: 返回的才是StringBuffer对象,对str 本身没有影响 StringBuffer stringBuffer = new StringBuffer(str); } }
方式2 使用的是StringBuffer提供的 append方法
public class StringAndStringBuffer { public static void main(String[] args) { String str = "hello tom"; //方式2 使用的是append方法 StringBuffer stringBuffer1 = new StringBuffer(); stringBuffer1= stringBuffer1.append(str); } }
StringBuffer ----->String
方式1 使用StringBuffer提供的 toString方法
public class StringAndStringBuffer { public static void main(String[] args) { StringBuffer stringBuffer3 = new StringBuffer("hello tom"); //方式1 使用StringBuffer提供的 toString方法 String s = stringBuffer3.toString(); } }
方式2: 使用String的构造器来搞定
public class StringAndStringBuffer { public static void main(String[] args) { StringBuffer stringBuffer3 = new StringBuffer("hello tom"); //方式2: 使用构造器来搞定 String s1 = new String(stringBuffer3); } }
StringBuffer 类常见方法
1.增加
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" } }
看一下append方法的源码
append有很多重载的方法,方法名都叫append,但是形参的类型不一样。
最后输出System.out.println(s);本质是调用的是s.toString(),
下面看一下它的toString方法是怎么样的:
@Override public synchronized String toString() { if (toStringCache == null) { toStringCache = Arrays.copyOfRange(value, 0, count); } return new String(toStringCache, true); }
就是把value数组里面的值拷贝的toStringCache数组里面,然后返回的时候再new 一个String返回给我们。
2.删除
public class StringBufferMethod { public static void main(String[] args) { StringBuffer s = new StringBuffer("hello,张三丰赵敏100true10.5"); //删 /* * 删除索引为>=start && <end 处的字符 * 解读: 删除 11~14的字符 [11, 14) */ s.delete(11, 14); System.out.println(s);//"hello,张三丰赵敏true10.5" } }
3.修改
public class StringBufferMethod { public static void main(String[] args) { StringBuffer s = new StringBuffer("hello,张三丰赵敏100true10.5"); //改 //老韩解读,使用 周芷若 替换 索引9-11的字符 [9,11) s.replace(9, 11, "周芷若"); System.out.println(s);//"hello,张三丰周芷若100true10.5" } }
4.查询
public class StringBufferMethod { public static void main(String[] args) { StringBuffer s = new StringBuffer("hello,张三丰周芷若100true10.5"); //查找指定的子串在字符串第一次出现的索引,如果找不到返回-1 int indexOf = s.indexOf("张三丰"); System.out.println(indexOf);//6 } }
5.插入
public class StringBufferMethod { public static void main(String[] args) { StringBuffer s = new StringBuffer("hello,张三丰周芷若100true10.5"); //插 //老韩解读,在索引为9的位置插入 "赵敏",原来索引为9的内容自动后移 s.insert(9, "赵敏"); System.out.println(s);//"hello,张三丰赵敏周芷若100true10.5" } }
6.获取长度
public class StringBufferMethod { public static void main(String[] args) { StringBuffer s = new StringBuffer("hello,张三丰周芷若100true10.5"); //长度 System.out.println(s.length());//22 System.out.println(s); } }
练习题
第一题
public class StringBufferExercise01 { public static void main(String[] args) { String str = null;// ok StringBuffer sb = new StringBuffer(); //ok sb.append(str);//需要看源码 , 底层调用的是 AbstractStringBuilder 的 appendNull System.out.println(sb.length());//4 System.out.println(sb);//null //下面的构造器,会抛出NullpointerException StringBuffer sb1 = new StringBuffer(str);//看底层源码 super(str.length() + 16); System.out.println(sb1); } }
按照代码尽量去进入源码去看看,这里就不浪费时间了。sb.append(str);
为什么这句代码没有抛异常
System.out.println(sb)没有抛异常也是因为上面null转换进了字符数组,所有直接输出null。
为什么下面会空指针异常,因为在源码执行到
super(str.length() + 16);
因为str是null,会报空指针异常,就像我们执行下面代码一样会报空指针异常
System.out.println(str.length());
第二题
public class StringBufferExercise02 { public static void main(String[] args) { //new Scanner(System.in) String price = "8123564.59"; StringBuffer sb = new StringBuffer(price); // sb.lastIndexOf(".");//找到小数点的索引 // sb.insert(i - 3, ",");//然后在该位置的前3位,插入,即可 //上面的两步需要做一个循环处理,才是正确的 for (int i = sb.lastIndexOf(".") - 3; i > 0; i -= 3) { sb = sb.insert(i, ","); } System.out.println(sb);//8,123,564.59 } }
StringBuilder 类
解读:
StringBuffer有的方法,我StringBuilder也都有(所以我们StringBuilder这里不讲解它的方法了,上面讲了StringBuffer了,它们都一样的)。
StringBuffer一般用在多线程的,StringBuilder一般用在单线程的。
1. StringBuilder 继承 AbstractStringBuilder 类。
2. 实现了 Serializable ,说明StringBuilder对象是可以串行化(对象可以网络传输,可以保存到文件)。
3. StringBuilder 是final类, 不能被继承。
4. StringBuilder 对象字符序列仍然是存放在其父类 AbstractStringBuilder的 char[] value;
因此,字符序列也是堆中。
5. StringBuilder 的方法,没有做互斥的处理,即没有synchronized 关键字(StringBuffer有),在多线程的情况下使用是有线程风险的,因此在单线程的情况下使用StringBuilder。String、StringBuffer 和 StringBuilder 的比较
总结:针对第二点的复用率,就是我在常量池创建了一个对象jack,所有String都可以指向它。所以String的复用率高,即不需要在常量池创建重复的jack对象了,直接使用常量池已有的。
怎么去选择呢?
string的效率最低,但是复用率高。
如果想要效率高,就选StringBuffer和StringBuilder。
如果是单线程,选StringBuilder,因为它是这里面效率最高的。
如果是多线程,为了线程安全,应该选StringBuffer,效率在这里面中等。
String、StringBuffer 和 StringBuilder 的效率测试
public class StringVsStringBufferVsStringBuilder { public static void main(String[] args) { long startTime = 0L; long endTime = 0L; //StringBuffer 拼接 80000次 StringBuffer buffer = new StringBuffer(""); startTime = System.currentTimeMillis(); for (int i = 0; i < 80000; i++) { buffer.append(String.valueOf(i)); } endTime = System.currentTimeMillis(); System.out.println("StringBuffer的执行时间:" + (endTime - startTime)); //StringBuilder 拼接 80000次 StringBuilder builder = new StringBuilder(""); startTime = System.currentTimeMillis(); for (int i = 0; i < 80000; i++) { builder.append(String.valueOf(i)); } endTime = System.currentTimeMillis(); System.out.println("StringBuilder的执行时间:" + (endTime - startTime)); //String 拼接 80000 String text = ""; startTime = System.currentTimeMillis(); for (int i = 0; i < 80000; i++) { text = text + i; } endTime = System.currentTimeMillis(); System.out.println("String的执行时间:" + (endTime - startTime)); } }
从数字0开始拼接,拼接80000次,然后计算一共花费的时间,从而得出它们三者的效率。
比如配置数据库的账号密码就用String。
Math 类
public class MathMethod { public static void main(String[] args) { //看看Math常用的方法(静态方法) //1.abs 绝对值 int abs = Math.abs(-9); System.out.println(abs);//9 //2.pow 求幂 double pow = Math.pow(2, 4);//2的4次方 System.out.println(pow);//16 //3.ceil 向上取整,返回>=该参数的最小整数(转成double); double ceil = Math.ceil(3.9); System.out.println(ceil);//4.0 //4.floor 向下取整,返回<=该参数的最大整数(转成double) double floor = Math.floor(4.001); System.out.println(floor);//4.0 //5.round 四舍五入 相当于Math.floor(该参数+0.5) long round = Math.round(5.51); System.out.println(round);//6 //6.sqrt 求开方 double sqrt = Math.sqrt(9.0); System.out.println(sqrt);//3.0 } }
前置知识:random 返回的是 0 <= x < 1 之间的一个随机小数,包括0,不包括1。
double 强制转换int是取整的,5.1 还是5.9都转为5,-5.1 还是-5.9都转为-5。
思考:请写出获取 a-b之间的一个随机整数,a,b均为整数 ,比如 a = 2, b=7,即返回一个数 x ,2 <= x <= 7。这个公式是 (int)(a + Math.random() * (b-a +1) )
解读: Math.random() * (b-a) 返回的就是 0<= 数 < b-a
使用具体的数给小伙伴代入 a = 2 ,b = 7。(int)( 2 + Math.random()*6)
其中: Math.random()*6 返回的是 0 <= x < 6 的小数 加上2, 2 + Math.random()*6 返回的就是 2<= x < 8的小数
强制转换就是 (int)(2 + Math.random()*6) = 2 <= x <= 7
所以公式就是是正确的: (int)(a + Math.random() * (b-a +1) )public class MathMethod { public static void main(String[] args) { //看看Math常用的方法(静态方法) //7.random 求随机数 // random 返回的是 0 <= x < 1 之间的一个随机小数 for(int i = 0; i < 5; i++) { System.out.println((int)(2 + Math.random() * (7 - 2 + 1))); } }
public class MathMethod { public static void main(String[] args) { //看看Math常用的方法(静态方法) //max , min 返回最大值和最小值 int min = Math.min(1, 9); int max = Math.max(45, 90); System.out.println("min=" + min); System.out.println("max=" + max); } }
Arrays 类
Arrays.toString方法
toString源码
public static String toString(Object[] a) { if (a == null) return "null"; int iMax = a.length - 1; if (iMax == -1) return "[]"; StringBuilder b = new StringBuilder(); b.append('['); for (int i = 0; ; i++) { b.append(String.valueOf(a[i])); if (i == iMax) return b.append(']').toString(); b.append(", "); } }
解读:如果数组为null,返回null。
如果数组里没有元素,返回[ ]。
否则就把 [ 、] 都放进StringBuilder里面,数组里面的元素转为String,然后拼接到StringBuilder,最后返回的形式为[元素1,元素2,元素3]。
public class ArraysMethod01 { public static void main(String[] args) { Integer[] integers = {1, 20, 90}; //遍历数组 for(int i = 0; i < integers.length; i++) { System.out.println(integers[i]); } //直接使用Arrays.toString方法,显示数组 System.out.println(Arrays.toString(integers));// } }
sort排序:
public class ArraysMethod01 { public static void main(String[] args) { //1. 可以直接使用冒泡排序 , 也可以直接使用Arrays提供的sort方法排序 //2. 因为数组是引用类型,所以通过sort排序后,会直接影响到 实参 arr //演示 sort方法的使用 Integer arr[] = {1, -1, 7, 0, 89}; Arrays.sort(arr); System.out.println(Arrays.toString(arr)); } }
Arrays.sort并不是单一的排序,而是插入排序,快速排序,归并排序三种排序的组合。
定制排序
public class ArraysMethod01 { public static void main(String[] args) { Integer arr[] = {1, -1, 7, 0, 89}; //定制排序 Arrays.sort(arr, new Comparator() { @Override public int compare(Object o1, Object o2) { Integer i1 = (Integer) o1; Integer i2 = (Integer) o2; return i2 - i1;//如果需要从小到大排序就返回 i1 - i2 } }); System.out.println("===排序后==="); System.out.println(Arrays.toString(arr)); } }
public class ArraysMethod01 { public static void main(String[] args) { Integer arr[] = {1, -1, 7, 0, 89}; //定制排序 Arrays.sort(arr, new Comparator() { @Override public int compare(Object o1, Object o2) { Integer i1 = (Integer) o1; Integer i2 = (Integer) o2; return i2 - i1;//如果需要从小到大排序就返回 i1 - i2 } }); System.out.println("===排序后==="); System.out.println(Arrays.toString(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); // 默认排序方法 } }
0481_韩顺平Java_Arrays排序源码解读_哔哩哔哩_bilibili
public class ArraysSortCustom { 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; } } } } }
0482_韩顺平Java_Arrays模拟排序_哔哩哔哩_bilibili
public class ArraysMethod02 { public static void main(String[] args) { Integer[] arr = {1, 2, 90, 123, 567}; // binarySearch 通过二分搜索法进行查找,要求必须排好 // 老韩解读 //1. 使用 binarySearch 二叉查找 //2. 要求该数组是有序的. 如果该数组是无序的,不能使用binarySearch //3. 如果数组中不存在该元素,就返回 return -(low + 1); // key not found. int index = Arrays.binarySearch(arr, 567); System.out.println("index=" + index); //copyOf 数组元素的复制 // 老韩解读 //1. 从 arr 数组中,拷贝 arr.length个元素到 newArr数组中 //2. 如果拷贝的长度 > arr.length 就在新数组的后面 增加 null //3. 如果拷贝长度 < 0 就抛出异常NegativeArraySizeException //4. 该方法的底层使用的是 System.arraycopy() Integer[] newArr = Arrays.copyOf(arr, arr.length); System.out.println("==拷贝执行完毕后=="); System.out.println(Arrays.toString(newArr)); //ill 数组元素的填充 Integer[] num = new Integer[]{9,3,2}; //老韩解读 //1. 使用 99 去填充 num数组,可以理解成是替换原理的元素 Arrays.fill(num, 99); System.out.println("==num数组填充后=="); System.out.println(Arrays.toString(num)); //equals 比较两个数组元素内容是否完全一致 Integer[] arr2 = {1, 2, 90, 123}; //老韩解读 //1. 如果arr 和 arr2 数组的元素一样,则方法true; //2. 如果不是完全一样,就返回 false boolean equals = Arrays.equals(arr, arr2); System.out.println("equals=" + 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()); } }
0483_韩顺平Java_Arrays其他方法_哔哩哔哩_bilibili
System 类
exit 退出当前程序
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 ,复制数组元素
我们一般不使用arraycopy,一般使用Arrays.copyOf完成复制数组,其实Arrays.copyOf底层用的也是arraycopy,所以现在我们来学习一下arraycopy。
public class System_ { public static void main(String[] args) { //arraycopy :复制数组元素,比较适合底层调用, // 一般使用Arrays.copyOf完成复制数组 int[] src={13,2,22}; int[] dest = new int[3];// dest 当前是 {0,0,0} System.arraycopy(src, 0, dest, 0, src.length); System.out.println("dest=" + Arrays.toString(dest));//[1, 2, 3] } }
1. 主要是搞清楚这五个参数的含义
src 源数组
srcPos: 从源数组的哪个索引位置开始拷贝
dest : 目标数组,即把源数组的数据拷贝到哪个数组
destPos: 把源数组的数据拷贝到 目标数组的哪个索引
length: 从源数组拷贝多少个数据到目标数组
看源码:
再改变一下
结果:
currentTimeMillens,返回当前时间距离1970-1-1 的毫秒数
public class System_ { public static void main(String[] args) { //currentTimeMillens:返回当前时间距离1970-1-1 的毫秒数 System.out.println(System.currentTimeMillis()); } }
第四个在这个视频里面