1.String类的理解(以jdk8为例说明)
1.1 类的声明
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
-final:String是不可被继承的
-Serializable:可序列化接口。凡是实现此接口的类的对象都可以通过网络或本地流进行数据的传输。
-Comparable:凡是实现此接口的类,其对象都可以比较大小。
1.2 内部声明的属性
jdk8中:
private final char value[];//储存字符串数据的容器
-final:指明此value数组一旦初始化,其地址就不可变
jdk9开始:为了节省内存空间
private final byte[] value;
2. 字符串常量的储存位置
-字符串常量都储存在字符串常量池(StringTable)中
-字符串常量池不允许存放两个相同的字符串常量
-字符串常量池,在不同的jdk版本中,存放位置不同
jdk7之前,字符串常量池存放在方法区
jdk7及之后,字符串常量池,存放在堆空间
3. String的不可变性的理解
4. String实例化的两种方式
【面试题】
String s2 = new String("hello");在内存中创建了几个对象?
一个是堆空间中new的对象。另一个是在字符串常量池中生成的字面量
5. String的连接操作:+
情况1:常量 + 常量 :结果仍然储存在字符串常量池中,返回此字面量的地址。注:此时的常量可能是字面量,也可能是final修饰的常量
情况2:常量 + 变量 或 变量 + 常量 :都会通过new的方式创建一个新的字符串,返回堆空间中此字符串对象的地址值
情况3:调用字符串的intern() :返回的是字符串常量池中字面量的地址
(了解)情况4:concat():无论是常量调用方法,还是变量调用方法,无论参数是参量还是变量,调用完concat()方法都会返回一个新new的对象
6. String的构造器和常用方法
6.1 构造器
public String():初始化新创建的String对象,以使其表示空字符序列
public String(String original):初始化一个新创建的String对象,使其表示一个与参数相同的字符序列
public String(char value[]):通过当前参数中的字符数组来构造新的String
public String(char value[], int offset, int count):通过字符数组的一部分来构造新的String
public String(byte bytes[]):通过使用平台的默认字符集解码当前参数中的字节数组来构造新的String
public String(byte bytes[], String charsetName):通过使用指定的字符集解码当前参数中的字节数组来构造新的String
针对于StringBuilder来说:
内部属性有:
char[] value;//储存字符序列
int count;//实际储存的字符的个数
StringBuilder sb1 = new StringBuilder();//char[] value = new char[16];
StringBuilder sb1 = new StringBuilder("abc");//char[] value = new char[16+"abc".length()];
sb1.append("ac");//value[0] = 'a';value[1] = 'c';
sb1.append("b");//value[2] = 'b';
当count超过value.length()时,就需要扩容:默认扩容为原容量的2倍+2,并将原有value数组中的元素复制到新的数组中
3. 原码启示
-如果开发中需要频繁的针对于字符串进行增、删、改、查等,建议使用StringBuilder或StringBuffer替换String,因为String效率低
-如果开发中,不涉及 到线程安全问题,建议使用StringBuilder替换StringBuffer。因为StringBuilder效率高
-如果开发中大体确定要操作的字符的个数,建议使用带int capacity参数的构造器,避免底层多次扩容操作,性能降低
4. StringBuffer和StringBuilder中的常用方法
增:
StringBuffer append(xx):提供了很多的append()方法,用于进行字符串追加的方式拼接
删:
StringBuffer delete(int start,int end):删除[start,end]之间的字符
StringBuffer deleteCharAt(int index):删除[index]位置的字符
改:
StringBuffer replace(int start,int end,String str):替换[start,end)范围的字符序列
void setCharAt(int index,char c):替换[index]位置字符
查:
char charAt(int index):查找指定位置index位置上的字符
插:
StringBuffer insert(int index,xx):在[index]位置上插入xx
长度:
int length():返回储存的字符数据的长度
反转:
StringBuffer reverse():反转
5. 对比三者的执行效率
效率从高到低排列:
StringBuilder > StringBuffer > String
一、jdk8之前的API
1. System类的currentTimeMillis()
-获取当前时间对应的毫秒数,long类型,时间戳:是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起到现在的总秒数
-当前时间与1970年1月1日0时0分0秒之间的毫秒数
-常用来计算时间差
2. 两个Date类
- java.util.Date
-两个构造器的使用
-两个方法的使用
- java.sql.Date:对应数据库中的date类型
3. SimpleDateFormat类
6.8 集合类
Collection:集合 Array:数组
集合和数组非常类似,都是存储数据的一个容器。
区别:
数组是定长,且只能存储相同类型的数据。
集合是变长,不仅可以存储相同数据而且可以存储不同类型的数据的容器。
Java中的集合可以看成JavaScript的数组。仅仅是概念一样,代码完全不一样。
备注:和集合相关的类都需要导包。注意都是java.util下。
Java中的集合分为两大类:
A.单列集合(类似数组,只需要存值,通过下标访问值)
B.双列集合(类似对象,不仅需要存值,还要存与之对应的属性名,通过属性名访问属性值)
Collection就是所有单列集合的父接口
所有单列集合都实现了该接口,所以:所有单列集合都拥有共同的方法。
所以学会了一种单列集合,剩下的单列集合都能依葫芦画瓢。
Collection又分为:
List子接口(内部元素:有序且可以重复)
Set子接口(内部元素:无序且无法重复)
List接口下主要分为以下两个实现类:
ArrayList 集合:采用数组结构,元素增删慢,查找快,由于日常开发中使用最多的功能就是查询,所以 ArrayList 是最常用的集合之一。没有保证线程安全,但是效率高。
Vector集合: 保证了线程安全,但是效率较低。除此和ArrayList都一样
LinkedList 集合:采用链表结构。元素增删快,但是查找慢。
线程安全:保证多个用户共同使用它也不会出错
数组结构:元素增删慢,查找快
链表结构:元素增删快,查找慢
原因:
数组结构是有序的,每个元素都有一个下标,查找的时候只需要根据下标查找即可, 所以元素的查找快,但是一旦发生了元素的增加或减少, 会引发每个元素的下标发生 变化,导致增删慢。
链表结构是无序的,每个元素仅仅存储了本身的值,和引入下一个元素的地址。
所以查询都是一个一个轮流查询,而不是像数组结构,直接根据下标查询。
但是增删快,因为只需要对增删位置的元素进行修改即可,不会影响别的元素。
//常见的集合1: ArrayList:
//复习: 特点1:采用了数组结构:查询快。增删慢 特点2:线程非安全所以效率快
//特点3:有序且可以重复 特点4:父类是List 祖父类:Collection
//如何创建一个ArrayList :类似于多态: 左边放父类 右边放自类
List list = new ArrayList();
// boolean add(Object o); //往集合尾部添加元素,一般不需要返回值
System.out.println(list.add("张三"));
System.out.println(list.add("李四"));
System.out.println(list.add("wangw"));
System.out.println(list.add("jakc"));
// void add(int index, Object o );//往集合指定位置添加元素
list.add(2,"王五");
System.out.println(list);
//常见的方法:
// int size(); //返回集合的长度
System.out.println(list.size());
// boolean isEmpty(); //判断集合的内部是否为null 注意:并不是判断集合为空
System.out.println(list.isEmpty());
// boolean contains(Object o)