1. Arrays 数组
// 声明一维数组,[]内不允许有值
int[] arr;
int arr[];
// 创建一维数组对象,[]内必须有值
arr = new int[6];
// 对一维数组元素的初始化,动态初始化用 for 循环
int arr[] = {1, 2, 3};// 静态初始化;
// 声明二维数组
int[][] arr;
// 创建二维数组对象
arr = new int[3][4];
// 对二维数组元素的初始化,动态初始化用双重 for 循环
int[][] a = {
{1,2},
{3,3,4,4},
{5,6,7}
};// 静态初始化
// Arrays 常用方法
Arrays.toString(arr);// 返回数组元素
Arrays.sort(arr);// 从小到大排序
Arrays.binarySearch(arr, number);// 对有序数组进行二分查找 number,并返回其对应的索引
Arrays.copyOf(char[] original, int newLength);// 复制指定数组,并赋予新的数组长度,底层是:System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); + return copy;
System.arraycopy(arr01, 2, arr02, 0, 6);// 数组 arr01 从下标为 2 的元素开始的 6 个元素拷贝到目标数组 arr02 中
Arrays.fill(arr, 2, 4, 100);// 将 arr 中下标 [2, 4) 的元素替换成 100
2. String 不可变字符序列
// 声明
String str;
// 创建字符串对象
str = new String();
// 初始化
String str = "abcdefg";
String str = new String("abcdefg");
// 常用方法
str.charAt(1);// 该下标对应的内容
str.equals(str02);
str.equalsIgnoreCase();// 忽略大小写的比较
str.length();
str.indexOf("a");// 从左往右数碰到的第一个"a"的位置
str.lastIndexOf("a");// 从右往左数碰到的第一个"a"的位置
str.substring(int beginIndex, int endIndex);// 打印【beginIndex,endIndex)的字符
str.replace(a,b);// 将字符串中所有的 a 替换成 b
str.split("*");// 按"*"切割成数组
str.trim();// 去除首尾空格
str.startsWith("ab");// 判断是否以"ab"开头
str.endsWith("ab");// 判断是否以"ab"结尾
str.toLowerCase();// 转换成小写字母
str.toUpperCase();// 转换成大写字母
3. StringBuilder & StringBuffer 可变字符序列
1. 与 String 类不同的是,StringBuffer 和 StringBuilder 类的对象在被多次的修改后,不产生新的对象
2. StringBuilder 线程不安全,效率高
3. StringBuffer 线程安全,效率低
4. 线程安全:就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,直到该线程读取完,其他线程才可使用,因而不会出现数据不一致或者数据污染
5. 线程不安全:就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据
6. 由于 StringBuilder 效率较高,所以多数情况下建议使用 StringBuilder 类;然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类
public class Test01 {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();// 默认字符数组容量初始为 16,看源码
StringBuilder sb1 = new StringBuilder(32);// 字符数组容量初始为 32,看源码
StringBuilder sb2 = new StringBuilder("abcd");// 字符数组容量初始为 20(4+16),相当于在数组添加结束符:value[]={'a', 'b', 'c', 'd', \0, \0,...}
sb2.append("efg");// 追加方法
System.out.println(sb2);
System.out.println(sb2.hashCode());
sb2.append(true).append(321).append("可变字符序列");// 通过 return this; 实现方法链,看源码
System.out.println(sb2);
System.out.println(sb2.hashCode());
}
}
// 结果: abcdefg
// 366712642
// abcdefgtrue321可变字符序列
// 366712642
public class Test02 {
public static void main(String [] args){
StringBuilder sb = new StringBuilder("abcdefghijklmn");
sb.delete(1, 3);// 删除下标【1, 3)的元素
System.out.println(sb);
sb.delete(1, 3).delete(1, 3);// 利用 return this; 实现方法链
System.out.println(sb);
sb.reverse();// 反转字符串
System.out.println(sb);
}
}
// 结果: adefghijklmn
// ahijklmn
// nmlkjiha
// 为了更深入了解 StringBuilder,让我们分析一下 StringBuilder 的部分源码
![]()
// StringBuilder 继承于 AbstractStringBuilder(AbstractStringBuilder 实现了 Appendable 接口, CharSequence 接口的部分方法)
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
// 无参构造器,调用了父类有参构造器,初始化字符数组容量为 16
public StringBuilder() {
super(16);
}
public StringBuilder(int capacity) {
super(capacity);
}
public StringBuilder(String str) {
super(str.length() + 16);
append(str);
}
@Override
public StringBuilder append(Object obj) {
return append(String.valueOf(obj));
/* 这里我们给出 java.lang.String 类定义的 valueOf()方法
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
*/
}
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
}
// 从上面可以看出 StringBuilder 类的大部分方法都是继承自 AbstractStringBuilder,所以我们直接看 AbStractStringBuilder 类是怎么样实现这些方法的
abstract class AbstractStringBuilder implements Appendable, CharSequence {
char[] value;// 底层用的是 char 数组来存储数据
int count;// 字符串长度
// 无参构造器
AbstractStringBuilder() {
}
// 有参构造器,用于初始化 char 数组的容量
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
// 返回字符串长度
@Override
public int length() {
return count;
}
// 返回字符数组的容量
public int capacity() {
return value.length;
}
// 追加方法
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);// 判断是否需要扩容
str.getChars(0, len, value, count);// 底层是:System.arraycopy(str, 0, value, count, len - 0);
count += len;
return this;
}
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0) {
value = Arrays.copyOf(value, newCapacity(minimumCapacity));// 底层是:System.arraycopy(value, 0, copy, 0, Math.min(value.length, newCapacity)); + return copy;
}
}
private int newCapacity(int minCapacity) {
// overflow-conscious code
int newCapacity = (value.length << 1) + 2;// 新容量 = old容量 * 2 + 2
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0) ? hugeCapacity(minCapacity) : newCapacity;
}
private int hugeCapacity(int minCapacity) {
if (Integer.MAX_VALUE - minCapacity < 0) { // overflow
throw new OutOfMemoryError();
}
return (minCapacity > MAX_ARRAY_SIZE) ? minCapacity : MAX_ARRAY_SIZE;
}
}
StringBuilder