JavaSE第3篇字符串与数组

基本类型包装类

Java中的基本数据类型不是面向对象的,为了解决这个问题,Java提供了基本数据类型的包装类,除了char、int其他基本数据类型包装类的写法都是首字母大写,char则是Character、int是Integer。

实现原理

1
2
3
4
private final int value;  //类中实际上就靠这个变量在存储包装的值
public Integer(int value) {
this.value = value;
}

自动装箱
自动装箱指的是引用数据类型可以直接接受基本数据类型的值

1
2
3
4
5
public static void main(String[] args) {
Integer a = 10; //将int类型值作为包装类型使用
//等价写法
Integer b = Integer.valueOf(10);
}

自动拆箱
自动拆箱指的是基本数据类型可以直接接受引用数据类型的值

1
2
3
4
5
6
7
public static void main(String[] args) {
Integer i = 10;
int a = i;

Integer ii = 10;
int aa = i.intValue(); //通过此方法变成基本类型int值
}

注意事项
如果采用自动装箱机制,如果值相同,并且在缓存范围之类,那么他们的值是相同的。如果采用带参数的构造方法赋值的话,对象值是不同的

1
2
3
4
5
6
7
8
public static void main(String[] args) {
Integer a = new Integer(10);
Integer b = new Integer(10);
System.out.println(a == b); //虽然a和b的值相同,但是并不是同一个对象,所以说==判断为假

Integer aa = 10, bb = 10;
System.out.println(aa == bb); //aa、bb的值是相同的
}

缓存机制原理代码

1
2
3
4
5
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high) //这里会有一个IntegerCache,如果在范围内,那么会直接返回已经提前创建好的对象
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}

其他应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class TypeDemo {
public static void main(String[] args) {
//包装类类型转化案例
int num = 12131232;
System.out.println("原始数据:" + num);
System.out.println("二进制:" + Integer.toBinaryString(num));
System.out.println("八进制:" + Integer.toOctalString(num));
System.out.println("十六进制:" + Integer.toHexString(num));

//类型解码
Integer hexNum = Integer.decode("0xFF");
System.out.println(hexNum);
}
}

特殊包装类

1
2
3
4
5
6
7
8
9
import java.math.BigInteger;
public class BigIntDemo {
public static void main(String[] args) {
//特殊包装类进行超大数计算
BigInteger i = BigInteger.valueOf(Long.MAX_VALUE);
i = i.pow(100); //long的最大值来个100次方吧
System.out.println(i);
}
}

数组

数组是相同类型数据的有序集合。数组在Java中是用类的形式进行存储,即使使用基本数据类型创建的数组,也是以对象的形式存在。所以在Java中数组需要使用new关键字来定义初始化。数组在定义之后,其长度是不可以修改的。如果是基本数据类型的数组,是不支持自动装箱和拆箱的,引用数据类型可以。

数组下标是从0开始的,因为从数组存储的内存模型上来看,“下标”最确切的定义应该是“偏移(offset)”, 如果用a来表示数组的首地址, a[0]就是偏移为0的位置,也就是首地址,a[k]就表示偏移k个type_size的位置

初始化方式

类型[] 变量名称 = new 类型[数组大小];

类型 变量名称[] = new 类型[数组大小]; //支持C语言样式,但不推荐

类型[] 变量名称 = new 类型[]{…}; //静态初始化(直接指定值和大小)

类型[] 变量名称 = {…}; //同上,但是只能在定义时赋值

遍历方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.util.Arrays;

public class ArrayDemo {
public static void main(String[] args) {
//使用for循环
int[] array = new int[10];
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
System.out.println();

//使用foreach
for (int i : array) { //int i就是每一个数组中的元素,array就是我们要遍历的数组
System.out.print(i+" "); //每一轮循环,i都会更新成数组中下一个元素
}
System.out.println();

//使用Arrays类,Arrays不仅提供了遍历操作,还提供了排序等其他常见操作
System.out.println(Arrays.toString(array));
}
}

多维数组

Java中的多维数组和C语言不同的是,可以只指定行数,不指定列数,每一行的长度可以是不同的,Java中多维数组在内存中并不是连续的。可以获取多维数组中每一行的长度。遍历采用双重循环的方式。

多维数组指针解释

1
2
3
int **a2 = (int**)malloc(N*sizeof(int*));
for(int i=0;i<N;++i)
a2[i] = (int*)malloc(M*sizeof(int));

遍历操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class MulArrayDemo {
public static void main(String[] args) {
//创建二维数组
int[][] a = {
{1, 2, 3},
{4, 5, 6, 9},
{7},
};
//计算每行的长度
System.out.println("二维数组行数:" + a.length);
System.out.println("第1行的长度: " + a[0].length);
System.out.println("第2行的长度: " + a[1].length);
System.out.println("第3行的长度: " + a[2].length);

//遍历方法1
for (int i = 0; i < a.length; ++i) {
for(int j = 0; j < a[i].length; ++j) {
System.out.print(a[i][j] + " ");
}
System.out.println();
}

System.out.println("foreach遍历");
//遍历方法2
for (int[] innerArray: a) {
//第二次for ... each循环访问行内的每个元素
for(int data: innerArray) {
System.out.print(data + " ");
}
System.out.println();
}
}
}

字符串

字符串是保存字符的类,Java中没有字符串这种基本类型,所以使用String类来保存字符串。使用构造方法初始化的内容相同的字符串是不同的对象,使用赋值的方法创建的字符串是同一个对象。但使用equals方法比较内容是比较的内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
public class StrDemo {
public static void main(String[] args) {
String str1 = "Hello World";
String str2 = "Hello World";
System.out.println(str1 == str2);

String str3 = new String("Hello World");
String str4 = new String("Hello World");
System.out.println(str3 == str4);

System.out.println(str1.equals(str2) + "," + str3.equals(str3));
}
}

基本操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class StrDemo {
public static void main(String[] args) {
String str = "Hello World";
//字符串裁切
String sub = str.substring(0, 3);
System.out.println(sub);

//字符串分割
String[] strings = str.split(" ");
for (String string : strings) {
System.out.println(string);
}

//转字符数组
char[] chars = str.toCharArray();
System.out.println(chars);

//字符数组转字符串
char[] chArr = new char[]{'U', 'F', 'O'};
String strArr = new String(chArr);
System.out.println(strArr);

//字符串拼接
String abb = "abb";
String cdd = "cdd";
String ss = "";
ss += abb;
System.out.println(abb + cdd + ss);
}
}

StringBuilder
StringBuilder类是String类的构造者,用于构造字符串。提供了拼接、裁剪、比较等操作。

1
2
3
4
5
6
7
8
9
10
11
12
public class StringBuilderDemo {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder();
builder.append("aaa");
builder.append("bbb");
builder.append("ccc");
System.out.println(builder.toString());
//基本操作
builder.delete(2,4); //删除范围内字符,不包括范围开始和结尾
System.out.println(builder.toString());
}
}

正则表达式
正则表达式是用来判断字符串是否匹配规则的一种公式。是通过Pattern类与Matcher类来实现。Pattern可以理解为一个模式, 字符串需要与某种模式进行匹配。Matcher可以理解为模式匹配某个字符串后产生的结果。除了使用Pattern类与Matcher类,也可以简单的使用字符串”.matches”方法来实现简单匹配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Regular {
public static void main(String[] args) {
//邮箱匹配
Pattern emailPattern = Pattern.compile("^[A-Za-z0-9\\u4e00-\\u9fa5]+@[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(?:\\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+$");

//日期匹配,格式2022-06-12
Pattern dataPattern = Pattern.compile("^\\d{1,4}-(?:1[0-2]|0?[1-9])-(?:0?[1-9]|[1-2]\\d|30|31)$");

//判断是否符合邮箱
Matcher emailMatcher = emailPattern.matcher("admin@eldpepar.com");
System.out.println(emailMatcher.matches());

//判断是否符合日期
Matcher dataMatcher = dataPattern.matcher("2022-10-19");
System.out.println(dataMatcher.matches());

//简单匹配
String str = "https://www.eldpepar.com/";
String reg = "^([hH][tT]{2}[pP]://|[hH][tT]{2}[pP][sS]://)(([A-Za-z0-9-~]+).)+([A-Za-z0-9-~\\\\/])+$";
System.out.println(str.matches(reg));
}
}

常用正则规则

CodeSheep常用正则

StringBuilder与StringBuffer区别

(1)基本原则:如果要操作少量的数据,用String ;单线程操作大量数据,用StringBuilder ;多线程操作大量数据,用StringBuffer。

(2)不要使用String类的”+”来进行频繁的拼接,因为那样的性能极差的,应该使用StringBuffer或StringBuilder类,这在Java的优化上是一条比较重要的原则。


JavaSE第3篇字符串与数组
https://www.eldpepar.com/coding/12232/
作者
EldPepar
发布于
2022年10月18日
许可协议