介绍jdk
中的常用的类中常用的方法 , 包括:
String
类String
类不能继承,因为它是使用 final 修饰的
public final class String ...
String
表面上是一个字符串,实际上底层是用一个字符数组存的;String
类是不可变类,也就是说String
对象声明后,将不可修改
/** The value is used for character storage. */
private final char value[];
// 这个字符数组还是用 final 关键字修饰的,也是为什么String创建之后不可修改的原因
Java.lang.String; 是字符串类型
字符串一旦创建,不可以再改变
由于在程序中字符串经常出现,所以为了提升字符串的访问效率,在程序中使用了**“缓存”**技术。即在Java中使用 **“ ”**括起来的字符串都会在 字符串常量池 中创建一份
字符串常量池在JVM 的方法区内存中存取
在程序执行过程中,如果程序中用到某一个字符串,例如 “abc”,那么程序会首先在 字符串常量池 中去搜索这个字符串。如果没有找到则在字符串常量池中新建一个 “abc” 字符串;如果找到了就直接拿来用。(字符串常量池是一个缓存区,是为了提高字符串的访问效率)
public class Test01 {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "abc";
// == 比较的是两个引用指向的内存空间
System.out.println(s1 == s2); // 输出啥? // true
String s3 = new String("bcd"); // 存储在栈空间
String s4 = new String("bcd");
System.out.println(s3 == s4);// 输出啥? // false
System.out.println(s3.equals(s4)); // String 类中的 equals方法比较的是字符串的值
// 输出 true
// 以下程序执行会在字符串常量池中创建 3 个 字符串常量
// "aaa", "bbb", "aaabbb"
// 所以在涉及到频繁的字符串拼接的程序中,不推荐使用 直接字符串相+
String s5 = "aaa";
String s6 = "bbb";
String s7 = s5 + s6;
}
}
分析以下程序创建字符串对象的区别
public class Test02 {
public static void main(String[] args) {
String s1 = "abc";
String s2 = new String("abc");
}
}
String s1 = “abc”; 只会在方法区中的 “字符串常量池” 中创建一个 “abc” 字符串对象
String s2 = new String(“bac”); 会在字符串常量池中创建一个 “bac” 字符串对象,并且会在 堆内存 中再创建一个字符串对象
第二种方式比较浪费内存,常用的是第一种方式
判断以下程序中创建了几个字符串对象
public class Test03 {
public static void main(String[] args) {
String s1 = new String("abc");
String s2 = new String("abc");
}
}
使用String类型的字符串时请注意不要进行字符串的频繁拼接
关于字符串中的常用方法:
常用的构造方法
public class Test04 {
public static void main(String[] args) {
// 1
String s1 = "abc";
// 2
String s2 = new String("abc");
// 3
byte[] bytes = {97, 98, 99, 100};
String s3 = new String(bytes); // abcd
System.out.println(s3);
// 4
String s4 = new String(bytes, 1, 3); // bcd
System.out.println(s4);
// 5
char[] chars = {'a', 'b','c', 'd', 'e'};
String s5 = new String(chars);// abcde
System.out.println(s5);
// 6
String s6 = new String(chars, 2, 2);// cd
System.out.println(s6);
}
}
常用的方法
package com.test.classandmethod;
public class Test05 {
public static void main(String[] args) {
//1. char charAt(int index)
char c1 = "abcedfa".charAt(3);
System.out.println(c1); // e
//2. boolean endsWith(String suffix)
System.out.println("HelloWorld.java".endsWith(".java")); // true
//3. boolean equals(Object anObject)
System.out.println("hello".equals(new String("hello"))); // true
//4. boolean equalsIgnoreCase(String anotherString)
System.out.println("hello".equalsIgnoreCase("Hello"));
//5. byte[] getBytes()
byte[] res = "hello".getBytes();
for(int i=0; i<res.length; i++) {
System.out.print(res[i]+" "); // 104 101 108 108 111
}
System.out.println();
//6. int indexOf(String str)
int index = "jdhfadfa".indexOf("a");
System.out.println(index); // 4
//7. int indexOf(String str, int fromIndex)
index = "jkdhkajlf".indexOf("j", 2);
System.out.println(index); // 6
//8. int lastIndexOf(String str)
index = "jdhfakljdhfap[qijkmdnv;kajkha".lastIndexOf("f");
System.out.println(index); // 10
//9. int lastIndexOf(String str, int fromIndex) // 从开始位置往前找
index = "jdhfakljdhfap[qijkmdnv;kajka".lastIndexOf("h", 6);
System.out.println(index); // 2
//10. int length()
System.out.println("hdgahdg".length());// 7
//11. String replaceAll(String regex, String replacement)
String resS = "jkhaflkjhfdlakjdfha".replaceAll("d", "D");
System.out.println(resS);//jkhaflkjhfDlakjDfha
//12. String[] split(String regex)
String[] s1 = "jdhaflkjdhl,fmakdjfa.mafsdkfjak.sajdfhal.sdflajdfuq".split("f");
System.out.println(s1.length);
for(int i=0; i<s1.length; i++) {
System.out.println(s1[i]);
}
//13. boolean startsWith(String prefix)
System.out.println("aafdsfads".startsWith("aa"));// true
//14. String substring(int beginIndex);
System.out.println("dhjfajdfha".substring(2)); // jfajdfha
//15. String substring(int beginIndex, int endIndex)
System.out.println("jahdjfa".substring(2, 5));//hdj
//16. char[] toCharArray()
char[] ch1 = "dkjhfaljkd".toCharArray();
for (int i = 0; i < ch1.length; i++) {
System.out.print(ch1[i] + " "); //d k j h f a l j k d
}
System.out.println();
//17. String toLowerCase()
System.out.println("JHDGFADF".toLowerCase()); //jhdgfadf
System.out.println("jhdgfadf".toUpperCase()); //JHDGFADF
//18. String trim()
System.out.println(" ajdhflaj dhfaljkd dfhal ".trim()); //ajdhflaj dhfaljkd dfhal
//19. static String valueOf(...)
System.out.println(String.valueOf(true)); // true
Object obj = null;
System.out.println(obj); // 不会报错 相当于调用了String.valueOf(obj)
System.out.println(obj.toString()); // 空指针异常
}
}
“正则表达式”
正则表达式是一种字符模型,专门做字符串格式匹配的。正则表达式是通用的。
例如:
"^a{2}$" // 表示 2 个 a 字符, 等同于 "aa"
String 类中有一个matches方法: public boolean matches(String regex); 用于判断正则表达式是否匹配给定的字符串;
一些表示:
\d 数字
\D 非数字
\w 英文字母
\W 非英文字母
public class Test06 {
public static void main(String[] args) {
String s1 = "jkdafa23j4ddeq32941aiuhdef89qy";
// 将 dd 替换为 中
System.out.println(s1.replaceAll("dd", "中"));
// 将 dd 替换为 中
System.out.println(s1.replaceAll("d{2}", "中"));
//将所有的 数字 替换为 中
System.out.println(s1.replaceAll("\\d", "中"));
//将所有的 非数字 替换为 中
System.out.println(s1.replaceAll("\\D", "中"));
System.out.println("aa".matches("^a{2}$")); // true
System.out.println("ab".matches("^a{2}$")); // false
}
}
StringBuffer
和 StringBuilder
java.lang.StringBuffer
java.lang.StringBuilder
StringBuffer
和 StringBuilder
是什么?
是一个字符串缓冲区
工作原理
预先再内存中申请一块内存,以容纳字符序列。如果预留的空间不够用,则进行自动扩容,以容纳更所字符序列
和String
的最大区别
StringBuffer 和 StringBuilder 的默认初始化容量是 16
如何优化 StringBuffer 和 StringBuilder 呢?
最好在创建 StringBuffer 和 StringBuilder 的时候预测他们存储的字符数量,然后在创建 StringBuffer 和 创建 StringBuilder 的时候采用指定初始化容量的方法创建StringBuffer/StringBuilder, 从而实现减少底层数组的拷贝,提高效率。
在做字符串频繁拼接的时候,建议使用 StringBuffer 和 StringBuilder
public class Test07 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer(20);
String[] s = {"运动","休闲","娱乐","工作"};
for(int i=0; i<s.length; i++) {
if(i == s.length-1) {
sb.append(s[i]);
}else {
sb.append(s[i]);
sb.append(",");
}
}
System.out.println(sb);
}
}
Stringbuffer 和 StringBuilder 之间的区别:
基本数据类型 | 包装类型 |
---|---|
byte | java.lang.Byte; |
short | java.lang.Short; |
int | java.lang.Integer; |
long | java.lang.Long; |
float | java.lang.Float; |
double | java.lang.Double; |
boolean | java.lang.Boolean; |
char | java.lang.Character; |
已经有基本数据类型了,为什么还要提供包装类?
为了方便
public class Test08 {
public static void main(String[] args) {
// 基本数据类型
byte b = 10;
// 引用数据类型
Byte b1 = new Byte(b);
m1(b1); // 10 Byte类已经将Object类中的 toString类重写
// 备注: 其实可以直接传进去 10, 涉及到自动装箱, 自动拆箱
}
// 需求: 规定m1方法可以接收任何一种数据类型
// m1方法如果想接收byte类型的数据的时候,可以先将byte类型包装成 java.lang.Byte; 再传递参数
private static void m1(Object obj) {
System.out.println(obj);
}
}
包装类的继承结构图
常用的包装类及常用的方法 ---- 以 java.lang.Integer
为例:
构造方法
public class Test09 {
public static void main(String[] args) {
// 获取 integer 的最大值最小值
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
// 获取 Byte的最大值最小值
System.out.println(Byte.MAX_VALUE);
System.out.println(Byte.MIN_VALUE);
// 创建Integer类型的对象
Integer i1 = new Integer(11); // int --> Integer
Integer i2 = new Integer("123"); // String ---> Integer
System.out.println(i1);
System.out.println(i2);
// 一下程序编译可以通过,但是运行的时候会报异常
// 虽然可以将字符串转换成 Integer 类型,但是该字符串也应该是 "数字字符串"
// Integer i3 = new Integer("abc");//java.lang.NumberFormatException
}
}
常用方法
integer 常用方法
public class Test10 {
public static void main(String[] args) {
// intValue, byteValue, floatValue, doubleValue, longValue
// int --> Integer
Integer i1 = new Integer(10);
// String --> Integer
Integer i3 = new Integer("132");
// Integer --> int
// 引用类型 --> 基本类型
int i2 = i1.intValue();
System.out.println(i2+1); // 11
// 重要:static int parseInt(String s)
// String --> int
int i4 = Integer.parseInt("4321");// 里面的字符串必须是“数字字符串”
System.out.println(i4+1);//4322
// 重要: static double parseDouble(String s)
// String --> double
double d1 = Double.parseDouble("3.14");
System.out.println(d1);//3.14
// static String toBinaryString(int i)
// static String toHexString(int i)
// static String toOctalString(int i);
int i5 = 324;
String s1 = Integer.toBinaryString(i5);//101000100
System.out.println(s1);
String s2 = Integer.toHexString(i5);//144
System.out.println(s2);
String s3 = Integer.toOctalString(i5);//504
System.out.println(s3);
}
}
三种类型相互转换
/**
* 三种类型相互转换
* Integer
* String
* int
*
*/
public class Test11 {
public static void main(String[] args) {
// 1. int --> Integer
Integer i1 = Integer.valueOf(10);
// 2. Integer --> int
int i2 = i1.intValue();
// 3. String --> Integer
Integer i3 = Integer.valueOf("123");
// 4. Integer --> String
String s1 = i3.toString();
// 5. String --> int
int i4 = Integer.parseInt("123");
// 6. int --> String
String s2 = 12 + "";
}
}
自动装箱和自动拆箱
自动装箱 auto_boxing
自动拆箱 auto_unboxing
/**
* 自动装箱
* auto_boxing
* 自动拆箱
* auto_unboxing
*
*/
public class Test12 {
public static void main(String[] args) {
//1.
// int --> Integer
Integer i1 = new Integer(10); // 装箱
// Integer --> int
int i2 = i1.intValue(); // 拆箱
//2.
// int --> Integer
Integer i3 = 10; // 自动装箱
// Integer --> int
int i4 = i3; // 自动拆箱
m2(10, 5); // 自动装箱
}
public static Integer m2(Integer i1, Integer i2) {
return i1 - i2; // 存在自动拆箱,自动装箱
}
}
深入自动装箱,自动拆箱
自动装箱 和 自动拆箱 是 程序编译阶段的概念,与程序运行无关。
自动装箱 和 自动拆箱 的主要目的是方便程序员的编码
整型常量池:
像方法区中的“字符串常量池”一样,java为**[-128, 127]之间的整数在方法区内存中建立了一个“整型常量池“**
该整型常量池只存储【-128, 127】之间的数,每个数都对应放在方法区内存空间
Integer i7 = 127;
这行代码就会直接从方法区整型常量池中寻找 127 存储的内存地址,直接给 i7;不会在堆中创建对象
整型常量池中的数据 在 Integer 类加载后就创建了
public class Test13 {
public static void main(String[] args) {
Integer i1 = new Integer(10);// 会在堆中创建对象
Integer i2 = new Integer(10);
System.out.println(i1 == i2);// false 这里不会出现自动拆箱
// 比较两个Integer类型的数据是否相等,不能用 “==”
// Integer 已经重写了 Object中的 equals 方法
System.out.println(i1.equals(i2)); // true
// 重点
Integer i3 = 128;
Integer i4 = 128;
//上面两行代码等价于
Integer i5 = new Integer(128);
Integer i6 = new Integer(128);// 发生了自动装箱
System.out.println(i3 == i4); // false
// 注意以下代码(面试常考)
Integer i7 = 127; // 不会在堆中创建对象,会直接从整型常量池中拿
Integer i8 = 127; // 不会在堆中创建对象,会直接从整型常量池中拿
System.out.println(i7 == i8);// true
Integer i9 = -128;
Integer i10 = -128;
System.out.println(i9 == i10);// true
Integer i11 = -129;
Integer i12 = -129;
System.out.println(i11 == i12); // false
// 为什么会出现这种情况呢?
// 如果数据在 [-128, 127] 之间,java中引入了一个"整型常量池"(在方法区内存中)
// 该整型常量池只存储 [-128, 127]之间的数据(在类加载后就会创建,对应代码放在静态代码区)
}
}
获取毫秒数
/**
* 获取自 1970年1月1日0时0分0秒000毫秒到当前的毫秒数
* 1000 毫秒 = 1 秒
* java.lang
* System Class
* currentTimeMillis()
*/
public class Test14 {
public static void main(String[] args) {
// static long currentTimeMillis()
long now = System.currentTimeMillis();
System.out.println(now); // 1583735040606
}
}
日期格式化
import java.util.Date;
import java.text.SimpleDateFormat;
public class Test15 {
public static void main(String[] args) {
// 获取系统当前的时间
Date now = new Date();
System.out.println(now);// Mon Mar 09 14:47:44 CST 2020
// 如何定制日期的输出格式呢?
// 引入格式化日期
// java.util.Date --> String
// java.text.SimpleDateFormat
SimpleDateFormat sdf = new SimpleDateFormat();
String sdfNow = sdf.format(now);
System.out.println(sdfNow); // 20-3-9 下午2:55
sdf = new SimpleDateFormat("yyyy-MM-dd:HH-mm-ss-SSS");
sdfNow = sdf.format(now);
System.out.println(sdfNow);// 2020-03-09:14-56-54-987
sdf = new SimpleDateFormat("yyyy年MM月dd日:HH时mm分ss秒SSS毫秒");
sdfNow = sdf.format(now);
System.out.println(sdfNow);// 2020年03月09日:14时57分44秒278毫秒
}
}
获取特定的日期
import java.util.Date;
import java.text.ParseException;// 直接继承 Exception类,是编译型异常
import java.text.SimpleDateFormat;
public class test16 {
public static void main(String[] args) throws ParseException {
// 获取特定时刻的日期
String strTime = "2008年8月8日 08:08:08 888";
// 将String类型的日期转换成日期类型Date的日期
// String --> Date
//1. 创建日期格式化对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss SSS"); //格式不能随意,应该和上面的字符串格式相同
//2. 将字符串转换成日期类型
Date date = sdf.parse(strTime);// 需要处理编译型异常
System.out.println(date);// Fri Aug 08 08:08:08 CST 2008
}
}
获取当前时间的前10分钟的时间
import java.text.SimpleDateFormat;
import java.util.Date;
/*
Date date = new Date();// 获取系统当前时间
Date date = new Date(long date);
date - the milliseconds since January 1, 1970, 00:00:00 GMT.
*/
public class Test17 {
public static void main(String[] args) {
Date t1 = new Date(1000);
// Date --> String
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
String s1 = sdf.format(t1);
// 在北京东八区,所以是8点
System.out.println(s1); //1970-01-01 08:00:01 000
// 获取当前系统时间的前10分钟的时间
// 2020-03-09 16:01:38 175
// 2020-03-09 16:11:38 175
Date t2 = new Date(System.currentTimeMillis()- 1000*60*10);
System.out.println(sdf.format(t2));
System.out.println(sdf.format(new Date()));
}
}
java.util.Calendar
日历
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
/**
* 日历
* java.util.Calendar
*
*/
public class Test18 {
public static void main(String[] args) throws ParseException {
// 获取系统的当前日历
// static Calendar getInstance()
// Gets a calendar using the default time zone and locale.
Calendar c = Calendar.getInstance();
// 查看当前日历的星期几
// int get(int field)
int i = c.get(Calendar.DAY_OF_WEEK);// 中国人的星期日,外国人看作第一天
System.out.println(i);// 2
// 查看当前日历的day
i = c.get(Calendar.DAY_OF_MONTH);
System.out.println(i);// 9
// 获取 2008年8月8日是星期几
// void setTime(Date date) // Sets this Calendar's time with the given Date.
// 1. 获取2008年8月8日的日期 String-->Date
String str = "2008年08月08日";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
Date date = sdf.parse(str);
// 2. 创建该日期对应的日历
c.setTime(date);
// 3. 获取星期几
System.out.println(c.get(Calendar.DAY_OF_WEEK));//6
}
}
关于数字格式化
java.text.DecimalFormat
数字格式元素:
# 任意数字
, 千分位
. 小数点
0 不够补零
/**
* 数字格式化
*/
import java.text.DecimalFormat;
public class Test19 {
public static void main(String[] args) {
// 1. 创建数字格式化对象, 加入千分位
DecimalFormat df = new DecimalFormat("###,###");// 1,234,567
// 2. 开始格式化
// Number --> String
System.out.println(df.format(1234567));
// 加入千分位,保留两位小数
df = new DecimalFormat("###,###.##");
System.out.println(df.format(123456.234));// 123,456.23
// 加入千分位,保留4位小数,不够补零
df = new DecimalFormat("###,###.0000");
System.out.println(df.format(1233432.23));// 1,233,432.2300
}
}
java.math.bigDecimal;
该类型的数据精确度极高,适合做财务软件
double 类型的精度对于财务处理来说太低
import java.math.BigDecimal;
public class Test20 {
public static void main(String[] args) {
// 创建大数据
BigDecimal v1 = new BigDecimal(10);
BigDecimal v2 = new BigDecimal(20);
//做加法运算
// v1+v2 // 错误,两个引用类型不能做加法运算
BigDecimal v3 = v1.add(v2);
System.out.println(v3); // 30
}
}
Random 位于 java.util 包下,可以产生随机数
import java.util.Random;
public class Test21 {
public static void main(String[] args) {
// 创建一个新的随机数生成器
Random random = new Random();
// 生成 int 类型的随机数
int i = random.nextInt(101); //生成[0,101)之间的随机数
System.out.println(i);
double d = random.nextDouble();
System.out.println(d);
}
}
Enum
// 枚举类型
public class Test22 {
public static void main(String[] args) {
int a = 10;
int b = 0;
Result resValue = m1(a, b);
if(Result.SUCCESS == resValue) {
System.out.println("成功");
}else {
System.out.println("失败");
}
}
// 实现两个数相乘,如果成功,返回0, 如果失败,返回1
private static Result m1(int a, int b) {
try {
int res = a/b;
return Result.SUCCESS;
} catch (Exception e) {
return Result.FAIL;
}
}
}
// 定义枚举类型
enum Result{
// 枚举类型中的成员建议大写
SUCCESS,
FAIL
}