目录
1.1、toString(arr)----返回数组的字符串形式。如果数组元素是对象,则会调用对应的对象的toString方法
1.3、binarySearch 通过二分搜索进行查找,要求需要提前排序
1.4、copyOf(arrs,arrs.length) 数组元素的复制
一、包装类
1、基本数据类型
1.1、基本数据类型介绍
- 数据类型:每一种数据都定义了明确的数据类型,在内存中分配了不同大小的内存空间(字节大小)。
- 基本数据类型:byte、short、int、long、float、double、boolean、char
- 整数类型
- byte【1】、short【2】、int【4】、long【8】是用于存放整数值的
整数类型 类型 占用存储空间 范围 byte[字节] 1字节 -128~127 shaort[短整型] 2字节 -32768~32767
int[整型] 4字节 long[长整型] 8字节 整性注意事项
Java各整型有固定范围和字段长度,不受具体操作系统影响,保证Java程序的可移植性;
Java整型常量默认是int型,声明long型常量需要在整数值后加‘l’或‘L’
bit:计算机种最小的存储单位
byte:计算机种最基本的存储单元,1byte = 8 bit;
浮点类型
float【4】、double【8】是用来存储浮点类型的,即小数。 关于浮点数在机器中存放形式的简单说明 , 浮点数=符号位+指数位+尾数位
浮点数类型 类型 占用存储空间 范围 单精度float 4字节 双精度double 8字节 尾数部分可能丢失,造成精度损失 ( 小数都是近似值 ) 。 浮点型注意事项:
与整型类似,Java种浮点型也有固定范围和字段长度,不受操作系统影响 Java的浮点型常量 默认是double ,声明float型常量,须在后 加‘f’或‘F’ 浮点数常量有两种表现形式:
十进制数:5.12 512.0f .512(必须有小数点) 科学计数法形式:5.12e2[5.12*10的2次方] 通常情况下,应该使用double,更精确 浮点数使用陷阱:2.7和8.1/3比较
//浮点数使用陷阱: 2.7 和 8.1 / 3 比较 //看看一段代码 double num11 = 2.7; double num12 = 8.1 / 3; //8.1 / 3; //2.7 System.out.println(num11);//2.7 System.out.println(num12);//接近 2.7 的一个小数,而不是 2.7 System.out.println(num11 == num12); if (num11 == num12) { System.out.println("num11 == num12 相等");//false } if (Math.abs(num11 - num12) < 0.000001) { System.out.println("差值非常小,到我的规定精度,认为相等..."); //得到一个重要的使用点: 当我们对运算结果是小数的进行相等判断是,要小心 //应该是以两个数的差值的绝对值,在某个精度范围类判断 }
- 字符型
- char【2】
- 字符类型可以表示单个字符,字符类型是 char,char 是两个字节(可以存放汉字),多个字符用字符串 String
- 字符型注意事项
- 字符型常量用单引号'',括起来的单个字符char c1 = 'a';
- Java种还允许使用转义字符'\',将其后的字符转变为特殊字符常量。例如:char c = '\n';换行符 '\t'制表符 '\\'一个反斜杠 '\"' 一个双引号
在 java 中, char 的本质是一个整数,在默认输出时,是 unicode 码对应的字符。要输出对应的数字,可以 (int) 字符char c2 = 'a'; //输出'a' 对应的 数字 System.out.println((int)c2);
char 类型是可以进行运算的,相当于一个整数,因为它都对应有 Unicode 码.System.out.println('a' + 10);//107 布尔类型:boolean只允许取值:true或false
1.2、基本数据类型转换
- 自动类型转换
- Java程序进行赋值或者运算时,小容量的类型自动转换为大容量类型
- 数据按照精度容量从小到大排序
- char---->int---->long---->float----->double
- byte---->short---->int---->long---->float---->double
- 即等号 = 右边是小容量,等号左边大容量,可以自动类型转换
- int a = 'c';可以char---->int
- double d = 80;可以int---->double
- 自动类型转换注意事项:
- 有多种类型的数据混合运算时,系统首先自动将所有的数据转换成容量最大的那种类型,然后再进行运算。
- 把容量大的赋值给容量小的会报错----->强制类型转换(向下转型)
- (byte,short)和char之间不会相互自动转换,当byte,short,char三者混合运算,首先转换成int类型的,然后再进行计算。
- boolean不参与转换
- 自动提升原则:表达式结果类型自动提升为操作数种最大容量的那个类型。
- 强制类型转换
自动类型转换的逆过程, 将容量大的数据类型转换为容量小的数据类型 。使用时要加上强制转换符 ( ) ,但可能造成 精度降低或溢出 , 格外要注意。 强制类型转换的注意事项:
当进行数据从 大容量------>小容量,就需要强转 byte和short,char进行运算时,当作int类型来处理char类型可以报错int的常量值,但不能报错变量值,需要强转
char c1 = 100; //ok int m = 100; //ok //char c2 = m; //错误 char c3 = (char)m; //ok
强转符号只针对最近的操作数有效,往往会使用小括号()提升优先级
//int x = (int)10*3.5+6*1.5;//编译错误: double -> int int x = (int)(10*3.5+6*1.5);// (int)44.0 -> 44
- 基本数据类型和 String 类型的转换
- 基本数据类型------>String类型
- 将基本数据类型的值 + ""就可以实现转为String类型了
- String类型------>基本数据类型
- 通过基本数据类型对应的包装类调用其parseXxx()方法即可
int num1 = Integer.parseInt("12"); double num2 = Double.parseDouble("12"); float num3 = Float.parseFloat("12"); long num4 = Long.parseLong("12"); byte num5 = Byte.parseByte("12"); boolean b = Boolean.parseBoolean("true");//true short num6 = Short.parseShort("12"); System.out.println("==================="); System.out.println(num1);//12 System.out.println(num2);//12 System.out.println(num3);//12 System.out.println(num4);//12 System.out.println(num5);//12 System.out.println(num6);//12 System.out.println(b);//true
- 怎么把字符串转成字符 char -> 含义是指 把字符串的第一个字符得到
- "12".charAt(0) 得到 "12"字符串的第一个字符 '1'
2、 包装类
2.2.1、包装类与简单基本类型对比
针对八种基本数据类型相应的引用类型—包装类
2.2.2、自动装箱和自动拆箱
包装类和基本数据的转换装箱:基本数据类型---包装类型拆箱:包装类型---基本数据类型JDK5以后实现类自动的装箱拆箱自动装箱底层调用的是包装类 .valueOf()方法,如Integer.valueOf()注意:Integer.valueOf(int i)方法,把-128到127发到一个常量数组中,因此自动装箱这些数据的时候直接取数据不用new Integer(int i);所以取到的数据是同一个对象,地址相同。Integer i = 34; Integer j = 34; System.out.println(i == j);//true Integer i = 128; Integer j = 128; System.out.println(i == j);//false
//手动装箱 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()方法
//三目运算符要求 表达式2 和 表达式3 类型一致,中间的自动类型提升了,int转doub Object obj = true ? new Integer(2) : new Double(4); System.out.println(obj);//2.0
2.2.3、包装类型和 String 类型的相互转换
包装类 (Integer)->StringString.valueOf(100); Integer.toString();Integer i = 100;//自动装箱 //方式 1 String str1 = i + ""; //方式 2 String str2 = i.toString(); //方式 3 String str3 = String.valueOf(i);
/String -> 包装类 (Integer)自动装箱:Integer.parseInt("123"); 构造器:new Integer("123");String str4 = "12345"; Integer i2 = Integer.parseInt(str4);//使用到自动装箱 Integer i3 = new Integer(str4);//构造器
2.2.4、Integer类常用方法
- Integer.parseInt("数字字符串");
- Integer.parseInt("数字字符串");
- Integer.valueOf("数字字符串");
- Integer.valueOf(100);
- Integer.toString(12);//把12转为字符串
2.2.5、Integer 类面试题
Integer i = 34; Integer j = 34; System.out.println(i == j);//true Integer i = 128; Integer j = 128; System.out.println(i == j);//false
自动装箱时,底层调用valueOf(int i)把int数据的-128-127的数放到一个数组中了,常量池,i是这个区间直接取值不用new新的Integer对象,所有每次的地址是一样的,而超出范围就需要重新new Integer对象,是不同的对象了。如果 i 在 IntegerCache.low(-128)~IntegerCache.high(127),就直接从数组返回,常量池取数。如果不在 -128~127,就直接 new Integer(i),是新的对象。Integer i1 = new Integer(127); Integer i2 = new Integer(127); System.out.println(i1 == i2);//F System.out.println(i1.equals(i2));//true
通过new方式创建的Integer对象,是不同的对象内存空间,因此不是一个对象,仅仅值相等。注意:Integer类中重写了equels()方法,只要数值相等就返回true
2.2.6、Character类常用方法
System.out.println(Character.isDigit('a'));// 判断是不是数字System.out.println(Character.isLetter('a'));// 判断是不是字母System.out.println(Character.isUpperCase('a'));// 判断是不是大写System.out.println(Character.isLowerCase('a'));// 判断是不是小写System.out.println(Character.isWhitespace('a'));// 判断是不是空格System.out.println(Character.toUpperCase('a'));// 转成大写System.out.println(Character.toLowerCase('A'));// 转成小写
二、String类总结
2.1、String类概述
String类是引用数据类型,数字型字符串可以通过数字型包装类的parseXxx("123")方法解析字符串,转为相应类型的数字。各数字型包装类也可以通过各自的toString()方法,将数值型转为字符串,或+""。Integer.toString(12)或者i.toString()其中Integer i = 12;(自动装箱,底层调用Integer.valueOf()方法)
2.1.1、String 类的理解和创建对象
String 对象用于保存字符串,也就是一组字符序列 "jack" 字符串常量 , 双引号括起的字符序列 字符串的字符使用 Unicode 字符编码,一个字符 ( 不区分字母还是汉字 ) 占两个字 String 类有很多构造器,构造器的重载String s1 = new String(); String s2 = new String(String original); String s3 = new String(char[] a); String s4 = new String(char[] a,int startIndex,int count); String s5 = new String(byte[] b)
String 是 final 类,不能被其他的类继承 String 有个属性 private final char value[]; 用于存放字符串内容 一定要注意: value 是一个 final 类型, 不可以修改 ( 需要功力 ) :即 value 不能指向新的地址,但是单个字符内容是可以变化.String对象创建的两种方式:
- 直接赋值 String s = "xiaoming";
- 先从常量池查看是否有"xiaoming"的数据空间,如果有,直接指向;如果没有则重新创建并放在常量池中,然后指向。s最终指向的是常量池的空间地址。
- 调用构造器 String s2 = new String("xiaoming");
- 先在堆内存中创建空间,里面维护了value属性,value指向常量池的"xiaoming"空间。如果常量池中没有"xiaoming",则重新创建,如果有,直接通过value指向常量池中的"xiaoming",而s2指向堆内存中的String对象,对象中的value属性指向常量池中的"xiaoming"。最终指向的是堆内存中的空间地址。
- 使用String str=new String(“hello”)方式创建对象,一共创建了几个对象?
- 一共会创建两个对象,一个是使用new创建的对象,存储在堆中;另一个是常量对象"hello",存储在字符串常量池中。
- String 有个属性 private final char value[]; 用于存放字符串内容【存放的是常量池的地址,指向具体内容,使用value属性可以获得值】
String s1 = "hspedu"; //指向常量池”hspedu”
String s2 = "java"; //指向常量池”java”
String s4 = "java";//指向常量池”java”
String s3 = new String("java");//指向堆中对象
System.out.println(s2 == s3); // F
System.out.println(s2 == s4); //T
System.out.println(s2.equals(s3));//T
System.out.println(s1 == s2); //F注意:s1,s2,s4直接指向常量池中的字符串,因此 == 是T。s3指向堆内存中对象,堆内存对象中有一个value属性,指向常量池中的字符串。
String使用注意事项:String s = "a";//创建了一个字符串s += "b";//实际上原来的"a"已经丢弃了,现在产生出一个新的字符串s +"b"(也就是"ab")。如果多次执行这些改变字符串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大影响程序的性能因此:如果我们对String做大量的修改,不要是哟个String
2.1.2、字符串的特性
- String是一个final类,代表不可改变的字符序列
- 字符串是不可改变的。一个字符串对象一旦被分配,其内容是不可变的。
- 以下语句创建了几个对象?
String s1 = "hello"; String s2 = "hello"; s1 = "haha";
刚开始字符串s1和s2内容相等,都指向字符串常量池中的同一个地址。当s1值的改变之后,此时s2的值不变还是指向原来的内存地址,但是s1会重新分配内存地址进行赋值
上述创建了两个对象
String s = "hello"+"abc";
只创建了一个对象,优化等价于String s = "helloabc";直接指向常量池
String s1 = "hello"; String s2 = "abc"; String s = s1 + s2; String a = "hello"; //创建 a对象 String b = "abc";//创建 b对象 //1. 先 创建一个 StringBuilder sb = StringBuilder() //2. 执行 sb.append("hello"); //3. sb.append("abc"); //4. String c= sb.toString() //最后其实是 c 指向堆中的对象(String) value[] -> 池中 "helloabc" String c = a + b; String d = "helloabc"; System.out.println(c == d);//真还是假? 是false String e = "hello" + "abc";//直接看池, e指向常量池 System.out.println(d == e);//真还是假? 是true
创建了三个对象,底层是StringBuilder sb = new StringBuilder(); sb.append(s1); sb.append(s2); sb对象指向堆中内存,并且append是在原有字符串基础上追加的。常量相加,看的是池,变量相加是在堆内存里。
总结:
public static void main(String[] args) { String s1="Hello"; String s2="World"; String s3="HelloWorld"; String s4="Hello"+"World"; String s5=s1+"World"; String s6="Hello"+s2; String s7=s1+s2; System.out.println(s3==s4); //true System.out.println(s3==s5); //false System.out.println(s3==s6); //false System.out.println(s3==s7); //false System.out.println(s5==s6); //false System.out.println(s5==s7); //false System.out.println(s6==s7); //false String s8=s5.intern(); System.out.println(s3==s8); //true }
- Java中有常量优化机制,“Hello"和"World"本身就是字符串常量,所以在编译时,会直接把"Hello"和"World"合并成"HelloWorld"字符串,又因为在执行s3的时候已经在常量池中创建了"HelloWorld”,所以s3==s4。
- 当变量与字面量或变量与变量进行拼接时,会在堆中创建一个StringBuilde对象,然后使用StringBuilder的append()方法将变量与字面量或变量与变量进行拼接,最后调用toString()方法转成String对象。所以s5、s6、s7指向的都是堆内存中String对象的地址值。
- 使用intern()这个方法时,首先会检查字符串常量池中是否有对应的字符串,如果存在则返回这个字符串的引用;否则会先将字符串添加到字符串常量池中,然后再返回这个字符串的引用。所以s3==s8。
易错笔试题:
public static void main(String[] args) { final String s1="Hello"; String s2="HelloWorld"; String s3=s1+"World"; System.out.println(s2==s3); //true }
此时的s1用final进行修饰,表示的是一个常量,所以此时s1+“World"就相当于"Hello”+“World”,结果仍然是一个常量,所以s2==s3。
2.1.3、String对象常用方法总结
- boolean equals(Object anObject) 比较内容是否相同,区分大小写
- boolean equalsIgnoreCase(String anotherString) 忽略大小写的判断内容是否相等
- int length() 获取字符的个数,字符串的长度
- int indexOf(String str) 获取字符在字符串对象中第一次出现的索引,索引从 0 开始,如果找不到,返回-1
- int lastIndexOf(String str) 获取字符在字符串中最后一次出现的索引,索引从 0 开始,如果找不到,返回-1
- String substring(int beginIndex) 从beginIndex开始截取字串
- String substring(int beginIndex, int endIndex) 截取beginIndex到endIndex - 1的字符串
- String trim() 去除字符串两边空格
- char charAt(int index) 返回指定位置的字符。获取索引index处的字符,注意不能使用str[index]方式,要使用char c = str.charAt(index);
- String toUpperCase() 字符串转大写
- String toLowerCase() 字符串转小写
- concat("str") 拼接字符串
"曹雪芹".concat(" 林黛玉 ").concat(" 薛宝钗 ");"曹雪芹林黛玉薛宝钗" String replace(str1, str2) 替换字符串中的字符,方法执行后,返回的结果才是替换过的,注意对 原字符串 没有任何影响。s1 = "宝玉 and 林黛玉 林黛玉 林黛玉"; String s11 = s1.replace("宝玉", "jack"); System.out.println(s1);//宝玉 and 林黛玉 林黛玉 林黛玉 System.out.println(s11);//jack and 林黛玉 林黛玉 林黛玉
将s1中宝玉用jack来替换,并把替换后的结果放在s11中,s1的内容不变。 String[] split(String regex) 将字符串以regex分割, 对于某些分割字符,我们需要 转义比如 | \\ 等,返回的是字符串数组。
//以 , 为标准对 poem 进行分割 , 返回一个数组 String poem = "锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦"; String[] split = poem.split(","); //在对字符串进行分割时,如果有特殊字符,需要加入 转义符 \ poem = "E:\\aaa\\bbb"; split = poem.split("\\\\");
int compareTo(String anotherString) 比较两个字符串。相等返回0;前大后小返回1;前小后大返回-1 str1.compareTo(str2);char[] toCharArray() 将字符串转换乘char数组
可以将String转为字符数组,然后遍历每一个字符,使用包装类Character的方法可以很轻松盘对字符是大小写,字母。。。。等等
boolean contains(CharSequence s) 判断字符串是否包含s
class StringTest{
public static void main(String[] args) {
String s1 = "hello world";
System.out.println(s1.charAt(6));//w
String s2 = "abc";
String s3 = "xyz";
String s4 = "xyz";
System.out.println(s2.compareTo(s3));//-23
System.out.println(s3.compareTo(s4));//0
System.out.println(s4.compareTo(s1));//16
System.out.println(s2.equals(s3));//false
System.out.println(s1.endsWith("world"));//true
System.out.println(s1.endsWith("t"));//false
String s5 = "HELLO worLD";
System.out.println(s1.equalsIgnoreCase(s5));//true
byte[] b = s1.getBytes();
System.out.println(Arrays.toString(b));//[104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]
System.out.println(s1.indexOf("world"));//6
System.out.println(s1.indexOf("h"));//0
System.out.println(s1.isEmpty());//false
System.out.println(s1.length());//11
String s6 = "javapythonc++cphpjavapython";
System.out.println(s6.lastIndexOf("java"));//17
System.out.println(s6.lastIndexOf("h"));//24
String s7 = "name=zhangsan&age=18&sex=男";
String newS7 = s7.replace("&", ";");
System.out.println(newS7);//name=zhangsan;age=18;sex=男
String[] splitS7 = s7.split("&");
System.out.println(Arrays.toString(splitS7));//[name=zhangsan, age=18, sex=男]
System.out.println(s6.startsWith("java"));//true
System.out.println(s6.startsWith("python"));//false
System.out.println(s6.substring(10));//c++cphpjavapython
System.out.println(s6.substring(10, 13));//c++
char[] charS6 = s6.toCharArray();
System.out.println(Arrays.toString(charS6));//[j, a, v, a, p, y, t, h, o, n, c, +, +, c, p, h, p, j, a, v, a, p, y, t, h, o, n]
System.out.println(s6.toUpperCase());//JAVAPYTHONC++CPHPJAVAPYTHON
System.out.println(s5.toLowerCase());//hello world
String s8 = " 你 好 世 界 ";
System.out.println(s8.trim());//你 好 世 界
System.out.println("------------------------------");
System.out.println(String.valueOf(123));//123
System.out.println(String.valueOf(3.14));//3.14
System.out.println(String.valueOf(true));//true
System.out.println(String.valueOf(new Object()));//java.lang.Object@4554617c
//valueOf会自动调用toString()方法
}
}
2.2、StringBuffer类概述
StringBuffer代表可变的字符序列,可以对字符串的内容进行增删,很多方法与String相同,也是一个final类,不可被继承,但StringBuffer是可变长度的。像一个容器一样,属性char[] value存放数组字符串,该属性不是final修饰的,可变。
StringBuffer sb = new StringBuffer()-----构造一个不带字符的字符串缓冲区,初始容量为16.
注意:
- StringBuffer sb = new StringBuffer()-----构造一个不带字符的字符串缓冲区,初始容量为16.
- 优化StringBuffer:创建StringBuffer对象时,尽可能给定一个初始容量,最好减少底层数组扩容次数,预估一下,给一个大的容量。new StringBuffer(int capacity)
String和StringBuffer对比:
- String保存的是字符串常量,里面的值不能改,每次String类的更新实际上就是更改地址,效率低
- String中有属性 private final char value[]; 因此存放内容是不可变的,要么重新赋值,指向不同的常量,是不同对象
- StringBuffer保存的是字符串变量,里面的值可以更改,每次StringBuffer的更新实际上是在更新内容,不用每次更新地址,效率较高。
- StringBuffer中有属性private char value[];不是用final修饰的,是在堆中,内容可变。
String和StringBuffer相互转换:
1、String——>StringBuffer:
String str = "hello tom"; //方式 1 使用构造器 //注意: 返回的才是 StringBuffer 对象,对 str 本身没有影响 StringBuffer stringBuffer = new StringBuffer(str); //方式 2 使用的是 append 方法 StringBuffer stringBuffer1 = new StringBuffer(); stringBuffer1 = stringBuffer1.append(str);
2、StringBuffer ->String
StringBuffer stringBuffer3 = new StringBuffer("xiaoming"); //方式 1 使用 StringBuffer 提供的 toString 方法 String s = stringBuffer3.toString(); //方式 2: 使用构造器来搞定 String s1 = new String(stringBuffer3);
2.2.1、StringBuffer对象常用方法总结
1、增
StringBuffer StringBuffer对象.append("要增加的内容");2、删StringBuffer StringBuffer对象.delete(startIndex, endIndex);----->删除索引为>=startIndex && <endIndex 处的字符3、改 StringBuffer StringBuffer对象.replace(int start, int end, String str)---->使用str替换 start到end索引的值,左闭右开。 StringBuffer StringBuffer对象.setCharAt(int index, char ch)----> 设置索引为index处的内容为ch字符4、插 StringBuffer StringBuffer对象.insert(index, str );----->在index索引处插入str内容,原索引index内容自动往后移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
5、StringBuffer的toString方法
String StringBuffer对象.toString() 实现将StringBuffer对象转为String字符串。
2.3、StringBuilder类概述
基本上与StringBuffer一样,但StringBuffer是线程安全的,StringBuilder不是线程安全。
String、StringBuffer 和 StringBuilder 的比较:1、StringBuilder和StringBuffer非常类似,均可代表可变的字符序列,而且方法也一样2、String:不可变字符序列,效率低,但是复用率高3、StringBuffer:可变字符序列,效率较高(增删),线程安全4、StringBuilder : 可变字符序列,效率最高,线程不安全、5、String使用注意事项:String s = "a";//创建了一个字符串s += "b";//实际上原来的"a"已经丢弃了,现在产生出一个新的字符串s +"b"(也就是"ab")。如果多次执行这些改变字符串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大影响程序的性能因此:如果我们对String做大量的修改,不要是哟个String
三、Math类
1、Math类概述
Math 类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。均为静态方法
2、Math类常用方法总结
Math类常用方法 方法 说明 static double ceil(double a) 返回大于或等于 a 的最小整数--向上取整 static double floor(double a) 返回小于或等于 a 的最大整数--向下取整 static int round(float a) 四舍五入取整 static double pow(double a,double b) 返回以 a 为底数,以 b 为指数的幂值 static double random() 返回的数据范围是[0,1)
Math.random()*N的变形
Math.random()得等概率范围为[0,1),Math.random()*N等概率返回得范围为[0,N),结合向上取整函数Math.ceil(Math.random()*N)
可以随机取得[1,N]之间任意整数。
如果想取得[0,N]之间的任意整数则+1向下取整:Math.floor( Math.random() * (N+1) )
//[0,10] int floor = (int) Math.floor(Math.random() * (10 + 1)); //[1,10] int ceil = (int)Math.ceil(Math.random() * 10); System.out.println(ceil); System.out.println(floor);
四、Arrays类
1、Arrays类常用方法
Arrays里面包含了一系列静态方法,用于管理或操作数组(比如排序和搜索)
1.1、toString(arr)----返回数组的字符串形式。如果数组元素是对象,则会调用对应的对象的toString方法
Integer[] integers = {1, 20, 90}; //遍历数组 for(int i = 0; i < integers.length; i++) { System.out.println(integers[i]); } for (Integer integer : integers) { System.out.print(integer+"\t"); } //使用Arrarys.toString(integers); System.out.println(Arrays.toString(integers));
1.2、sort排序方法(自然排序和定制排序)
Integer arrs[] = {1,-1,7,0,89} Arrarys.sort(arrs);//-1 0 1 7 89默认从小到大排序
//演示 sort方法的使用 Integer arr[] = {1, -1, 7, 0, 89}; //1. 可以直接使用冒泡排序 , 也可以直接使用Arrays提供的sort方法排序 //2. 因为数组是引用类型,所以通过sort排序后,会直接影响到 实参 arr //3. sort方法重载有很多形参形式,也可以通过传入一个接口 Comparator 实现定制排序 // static <T> void sort(T[] a, Comparator<? super T> c) //4. 调用 定制排序 时,传入两个参数 //(1) 排序的数组 arr //(2) 实现了Comparator接口的匿名内部类 , 要求实现 compare方法 //(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, new Comparator() { @Override public int compare(Object o1, Object o2) { Integer i1 = (Integer) o1; Integer i2 = (Integer) o2; return i2 - i1;//小于0从小到大,大于0从大到小 } }); System.out.println("===排序后==="); System.out.println(Arrays.toString(arr));
1、使用冒泡法完成数组排序:
//使用冒泡完成排序 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; } } } }
2、//结合冒泡 + 定制排序完成数组排序
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; } } } }
3、用上述两种方法实现排序:
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));
1.3、binarySearch 通过二分搜索进行查找,要求需要提前排序
1. 使用 binarySearch 二叉查找2. 要求该数组是有序的. 如果该数组是无序的,不能使用 binarySearch3. 如果数组中不存在该元素,就返回 return -(low + 1); // key not foundInteger[] arr = {1, 2, 90, 123, 567}; int index = Arrays.binarySearch(arr, 567); System.out.println("index=" + index);//index=4
1.4、copyOf(arrs,newLength) 数组元素的复制
1. 返回新数组,新数组长度扩为newLength,并将从 arrs 数组中拷贝 arrs.length个元素到 newArr数组中
2. 如果拷贝的长度 > arrs.length 就在新数组的后面 增加 null
3. 如果拷贝长度 < 0 就抛出异常NegativeArraySizeException
4. 该方法的底层使用的是 System.arraycopy()Integer[] arrs = {1, 2, 90, 123, 567}; Integer[] newArr = Arrays.copyOf(arrs, arrs.length); System.out.println("==拷贝执行完毕后=="); System.out.println(Arrays.toString(newArr)); //原数组 长度为5 int[] arr = {1,2,3,4,5}; int[] ints = Arrays.copyOf(arr, 10); //[1, 2, 3, 4, 5, 0, 0, 0, 0, 0] 新数组的长度为:10 System.out.println(Arrays.toString(ints));
1.5、fill(arrs,arr) 数组元素的填充
Integer[] num = new Integer[]{9,3,2}; //1. 使用 99 去填充 num数组,元素都变为99 可以理解成是替换原理的元素 Arrays.fill(num, 99); System.out.println("==num数组填充后=="); System.out.println(Arrays.toString(num));//[99, 99, 99]
1.6、equals() 比较两个数组元素是否完全一致
1.7、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);//asList=[2, 3, 4, 5, 6, 1] System.out.println("asList的运行类型" + asList.getClass());//asList的运行类型class java.util.Arrays$ArrayList
五、System类
1、System类常见方法与概述
1、exit()退出当前程序,在try-catch-finally中的try块中加入System.exit(0)则finally块中内容不执行。
2、arraycopy:复制数组元素,比较适合底层调用。我们一般使用Arrays.copyOf()完成数组拷贝
3、currentTimeMillens():返回当前时间距离1970-1-1毫秒数
4、gc():运行垃圾回收机制,System.gc();
六、BigInteger 和 BigDecimal 类
1、BigInteger 和 BigDecimal 介绍
1、BigInteger适合保存比较大的整型
2、BigDecimal适合保存精度较高的浮点数(小数)
2、BigInteger 和 BigDecimal 常见方法
1、add()加
2、subtract()减
3、multiply()乘
4、divide()除
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);//除
七、Date类
1、常用方法
Date date = new Date();
//获取当前系统时间,Mon Apr 24 12:50:20 CST 2023
System.out.println(date);
System.out.println(date.toString());
格式化时间格式:
//1. 创建 SimpleDateFormat 对象,可以指定相应的格式//2. 这里的格式使用的字母是规定好,不能乱写SimpleDateFormat sdf = new SimpleDateFormat("yyyy 年 MM 月 dd 日 hh:mm:ss E"); String format = sdf.format(d1); // format:将日期转换成指定格式的字符串 //2023年04月24日 12:50:20 System.out.println("当前日期=" + format);
更多方法内容请查看JDK的官网说明文档