一、String
1.1、理解:
- 第一:字符串 一旦创建不可变。
- 内部定义了 final char[] value 用于存储字符串数据。
- 第二:双引号 括起来的字符串存储在 字符串常量池中。
- 第三:字符串的 比较 必须使用equals方法。
- 第四:String已经重写了toString()和equals()方法。
- 第五:实现了 Comparable 接口:表示 String 可以比较大小。
- 第六:声明为 final 的,不可被继承。
String str = new String("字符串");
// 这句话分别在字符串常量池和堆中创建对象
- 这句话将在字符串常量池和堆内存中产生两个对象。
- str保存:String对象在堆内存的引用地址
- 堆内存的String对象保存 : 在字符串常量池(方法区)中 “字符串” 的引用地址
1.2、String的构造方法。
- 1.字符串常量存储在字符串常量池,目的是共享。
- 2.字符串非常量对象存储在堆中。
String s = "abc";
String s = new String("abc");
String s = new String(byte数组);
String s = new String(byte数组, 起始下标, 长度);
String s = new String(char数组);
String s = new String(char数组, 起始下标, 长度);
1.3、String类常用方法。
方法名 | 作用 |
---|---|
endsWith | 判断字符串是否以指定的后缀结束 |
startsWith | 判断字符串是否以指定的前缀开始 |
equals | 字符串相等比较,不忽略大小写 |
equalsIgnoreCase | 字符串相等比较,忽略大小写 |
indexOf | 取得指定字符在字符串的位置 |
lastIndexOf | 返回最后一次字符串出现的位置 |
length | 取得字符串的长度 |
replaceAll | 替换字符串中指定的内容 |
split | 根据指定的表达式拆分字符串 |
substring | 截子串 |
trim | 去前尾空格 |
valueOf | 将其他类型转换成字符串 |
compareTo | 基于字符串中各个字符的Unicode值,相同返回0 |
1.4 字符串拼接造成内存溢出
- 因为 String 是不可变对象,如果多个字符串进行拼接,将会形成多个对象,这样可能会造成内存溢出,会给垃圾回收带来工作量,而且 在字符串常量池中的字符串是不会被回收的 。为避免出现内存溢出,使用StringBuffer或者StringBuilder拼接字符串
1.5 String中的正则表达式
做字符串处理,正则表达式可以描述特定的字符模式,如:
- ”a{2}”表示由两个字符“a”构成的字符串,等同于普通字符串“aa”
- ”\d”代表任意一个数字 0~9
- \D 代表所有的非数字
- \w 代表所有的英文字母
- \W 代表所有的非英文字母
方法名 | 作用 |
---|---|
public boolean matches(String regex) | 返回此字符串是否匹配给定的正则表达式 |
public String replaceAll(String regex, String replacement) | 使用给定的 replacement 字符串替换此字符串匹配给定的正则表达式的每个子字符串 |
- 测试
String s1 = "asdd33dfsdaf33ddsre343fr2gfred55fdd3dssf4343sdf455ddsdddh565gggh55ddhg";
//将 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", "下"));
结果:
as测33dfsdaf33测sre343fr2gfred55f测3dssf4343sdf455测s测dh565gggh55测hg
as试33dfsdaf33试sre343fr2gfred55f试3dssf4343sdf455试s试dh565gggh55试hg
asdd一一dfsdaf一一ddsre一一一fr一gfred一一fdd一dssf一一一一sdf一一一ddsdddh一一一gggh一一ddhg
下下下下33下下下下下下33下下下下下343下下2下下下下下55下下下3下下下下4343下下下455下下下下下下下565下下下下55下下下下
1.6 经典面试题
String s = new String(“abc”); 创建了几个对象?
1. 一个是堆空间 new 结构创建的对象。(堆内存)
2. char[] 数对应的常量池中的数据:“abc”.(方法区)
1.7 String的hashCode() 方法
重写了Object的hashCode() 方法 public native int hashCode(); 原Object是调用C++的方法
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
二、 StringBuffer/StringBuilder
StringBuffer 称为字符串缓冲区,它的工作原理是:预先申请一块内存,存放字符序列,如果字符序列满了,(扩容)会重新改变缓存区的大小,以容纳更多的字符序列。StringBuffer 是可变对象,这个是 String 最大的不同
- 扩容原理:
System.arraycopy();
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
- 2.1、StringBuffer/StringBuilder可以看做可变长度字符串
- 2.2、StringBuffer/StringBuilder初始化容量16
- 2.3、StringBuffer/StringBuilder是完成字符串拼接操作的,方法名:append
- 2.4、StringBuffer是线程安全的,方法被 synchronized 修饰
- 2.5、StringBuilder是非线程安全的
- 2.6、频繁进行字符串拼接不建议使用“+”
- 2.7、底层都是调用底层使用 char[] 存储
- 2.8、String,StringBuffer,StringBuilder 效率对比
- 从高到低排列: StringBuilder > StringBuffer > String
三、基础类型对应的 8 个包装类
3.1 包装类概述
基本类型的包装类主要提供了更多的实用操作,这样更容易处理基本类型。所有的包装类都是final 的,所以不能创建其子类,包装类都是不可变对象。
基本类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
char | Character |
int | Integer |
long | Long |
float | Float |
double | Double |
boolean | Boolean |
3.2 类层次
- 除了 boolean 和 Character 的父类是 Object 外,其他包装类都是Number的子类
- 除了 boolean 和 Character 外,其它的包装类都有 valueOf()和 parseXXX 方法,并且还具有byteVaue(),shortVaue(),intValue(),longValue(),floatValue()和 doubleValue()方法。
3.3 自动装箱和拆箱
在 JDK5.0 以前,包装类和基本类型做运算时,必须将包装类转换成基本类型才可以,而 JDK5.0提供 Auto-boxing/unboxing(自动装箱和拆箱)
- 装箱:自动将基础类型转换为对象
- 拆箱:自动将对象转换为基础类型
3.4 Integer 的缓存来支持自动装箱的对象标识语义
- 测试
Integer x = new Integer(10);
Integer y = new Integer(10);
System.out.println(x == y);//false
x = 10;
y = 10;
System.out.println(x == y);//true
x = 128;
y = 128;
System.out.println(x == y);//false
- 自动装箱的值在 -128和127(包括) 之间。[-128,128)
//源码:
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
四、日期相关类
- 常用日期类:
- java.util.Date
- java.text.SimpleDateFormat
- java.util.Calendar
- java.lang.System
4.1 计算时间差
- System 类提供的 public static long currentTimeMills() 用来返回当前时间与 1970年1月1日0时0分0秒之间以毫秒为单位的时间差。时间戳。
System.currentTimeMillis();
//例如
long begin = System.currentTimeMillis();
Date d = new Date(begin - 1000 * 60 * 60 * 24);//得到昨天现在的时间
4.2 new Date对象
表示特定的瞬间,精确到毫秒
- 构造器:
- Date() : 使用无参构造器创建的对象可以获取本地当前时间。
- Date(long date)
- 常用方法:
- getTime() : 返回自 1970年1月1日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
- toString() : 把此 Date 对象转换为以下形式的 String : dow mon dd hh:mm:ss zzz yyy
//获取系统当前时间
Date d = new Date();
4.3 SimplateDateFormat
格式化:日期 ——> 文本 | 解析:文本 ——> 日期 |
---|---|
SimpleDateFormat() : 默认的模式和语言环境创建对象 | public Date parse(String source) : 从给定的字符串的开始解析文本,以生成一个日期。 |
SimpleDateFormat(String pattern) : 该构造方法可以用参数 pattern 指定的格式 创建一个对象,该对象调用:format(Date date) : 方法格式化时间对象 date |
//日期格式化:Date --> String
yyyy-MM-dd HH:mm:ss SSS//年,月,日,时,分,秒,毫秒
SimpleDateFormat sdf = new SimpleDate("yyyy-MM-dd HH:mm:ss SSS");
String s = sdf.format(new Date());
//String --> Date
SimpleDateFormat sdf = new SimpleDate("yyyy-MM-dd HH:mm:ss");
Date d = sdf.parse("2018-08-08 08:08:08");
五、数字相关类
5.1、DecimalFormat – 数字格式化
// ###,###.## 表示加入千分位,保留两个小数。
// ###,###.0000 表示加入千分位,保留4个小数,不够补0
//加入千分位,保留两位小数
DecimalFormat df = new DecimalFormat("###,###.##");
System.out.println(df.format(1234.23452));
//加入千分位保留 4 位小数,不够补零
System.out.println(new DecimalFormat("###,###.0000").format(12345.12));
5.2、BigDecimal – 大数
- 财务软件中通常使用BigDecimal
BigDecimal v1 = new BigDecimal(100);
BigDecimal v2 = new BigDecimal(88);
//相加运算
BigDecimal v3 = v1.add(v2);
System.out.println(v3);
六、Random
6.1 产生int类型随机数
Random r = new Random();
int i = r.nextInt();
6.2、产生某个范围之内的int类型随机数
Random r = new Random();
int i = r.nextInt(101); // 产生[0-100]的随机数。[0~101)
七、Enum
- 7.1、枚举是一种引用数据类型。
- 7.2、枚举编译之后也是class文件。
- 7.3、枚举类型定义
enum 枚举类型名{
枚举值,枚举值2,枚举值3
}
- 7.4、当一个方法执行结果超过两种情况,并且是一枚一枚可以 列举 出来的时候,建议返回值类型设计为枚举类型。