Java基础入门语法

网友投稿 201 2022-10-20


Java基础入门语法

今天带大家了解一下java的基础法语---String

字符串是我们以后工作中非常常用到的类型. 使用起来都非常简单方便, 我们一定要使用熟练。

那么C语言中是否有字符串类型? 答案是 “ 没有 ” !!

char *p = " hello";

那么p 的类型是一个字符串类型么? 不是,p是一个指针!!

而在 Java当中 是有 字符串类型的——String

一、定义方式

创建字符串的方式有很多种,常见的构造 String 的方式如以下:

方式一:直接赋值法

String str1 = "hello";

方式二: new String()

String str2 = new String("hello");

方式三:创建一个字符数组ch,new String ( ch )

char chs[] = {'h','e','l','l','l','o'};

String str3 = new String(chs);

二、内存

在此之前我们要先引入一个概念 字符串常量池

Sting constant pool 字符串常量池 的特性

1.在JDK.7 开始,字符串常量池 被挪到堆里了

2.池内的数据不存在重复

下面我们通过一系列的练习来熟悉 字符串常量池以及 字符串类型数据在内存中的存放。

public static void main(String[] args) {

String str1 = "hello";

String str2 = new String("hello");

System.out.println(str1 == str2);

String str3 = "hello";

System.out.println(str1 == str3);

}

我们来看这样的代码,str 代表的是引用\地址,请判断 两次打印分别是什么?

我们来看结果

这个结果说明 str1 和 str2存放的地址是不一样的, str1 和 str3 存放的地址是一样的。

好的,为什么是这样的结果呢?我们来看一下这几个字符串类型变量的内存。

"hello"如果存放在常量池当中,就会占用内存,假如这块空间的地址为111,那么str1中存放的就是111.

str2 new一个String对象,那么肯定在堆上开辟内存,假设内存地址是888,在这个String 对象中,存在一个value[] 保存着 orginal传入的字符串,这个val ==“hello”,因为在字符串常量池中已经有了"hello",所以val 直接指向 常量池中的"hello".但是str2 指向的依然是 888在堆中的空间。

所以 str1 不等于 str2。

之后呢,str3 也等于"hello",他也准备把hello放在常量池当中.此时常量池中已经存在"hello",那么之后str3 在存放"hello"地址的时候,就指向的是常量池中原来hello的地址。

所以 str1 等于 str3

再看一组练习

public static void main(String[] args) {

String str1 = "hello";

String str2 = "hel"+"lo";

System.out.println(str1==str2);

String str3 = new String("hel")+"lo";

System.out.println(str1==str3);

}

请判断两次打印的结果…

结果如下:

str1 指向字符串常量池中的 “hello”

str2 是"hel"与"lo" 组合而成的,常量在编译的时候就已经确定了,所以在编译时,已经被处理为"hello",所以也指向 常量池中的"hello"。

所以 str1 等于 str2

str3 首先new 了一个String(“hel”)对象,在堆中开辟一块空间,这个对象中的"hel"同时存放在常量池中,之后又在常量池中开辟一块空间存放 “lo”。两块部分之间的"+",将 String 的对象 与常量池中的 "lo"结合在堆中再次开辟一块新的空间,这块内存中的val ==“hello”,str3指向的是合并之后的对象 ,地址为999.

所以 str1 不等于 str3.

再看一组练习

public static void func(String str,char[] array){

str = "abcdef";

array[0] = 'g';

}

public static void main(String[] args) {

String str1 = "hello";

char[] val = {'a'};

System.out.println(str1);

System.out.println(Arrays.toString(val));

func(str1,val);

System.out.println("=================");

System.out.println(str1);

System.out.println(Arrays.toString(val));

http:// }

请看一下,我们将String str 作为参数,改变str 的内容,以及传入 数组 val 改变 数组元素,其打印结果是什么?

我们看到 String str 的内容并未改变,但是数组 val 的元素却改变了。

我们从内存的角度来分析。

str1 指向字符串常量区的"hello",地址为888

val 作为数组引用,指向堆中开辟的数组空间,地址为777

str 作为函数的形参,接收str1实参的值,也就是888,此时str指向常量区的”hello“,但是在方法的内部,str = “abcde”,在字符串常量区中有开辟一块"abcde"的内存,地址为000,最后 str 存放的地址为000.

array 作为函数的形参,接收val 实参的值,也就是777,此时array 指向堆中 开辟的数组空间,此时通过array 来改变数组元素的内容,最终 改变的也同样是val 实参的内容.

三、字符串比较相等

如果现在有两个int型变量,判断其相等可以使用 == 完成。

str1 = "world";

System.out.println(str2);

// 执行结果

//Hello

int x = 10 ;

int y = 10 ;

System.out.println(x == y);

// 执行结果

//true

如果说现在在String类对象上使用 == ?

代码1

String str1 = "Hello";

String str2 = "Hello";

System.out.println(str1 == str2);

// 执行结果

//true

看起来貌似没啥问题, 再换个代码试试, 发现情况不太妙.

代码2

String str1 = new String("Hello");

String str2 = new String("Hello");

System.out.println(str1 == str2);

// 执行结果

//false

在上面的几个练习中,我们 用 str1 == str2 比较的是两个字符串的引用/地址,如果比较字符串里面的内容,我们需要用到 equals 方法。

public static void main(String[] args) {

String str1 = "hello";

String str2 = new String("hello");

System.out.println(str1==str2); //比较的是引用

System.out.println(str1.equals(str2)); //比较 str1 和 str2 字符串的内容

String str3 = "hello";

System.out.println(str1.equals(str3)); //比较 str1 和 str3 字符串的内容

}

最后的打印结果

打印的结果符合字符串的内容比较。

常用的比较方式:

我们再来看一种情况,

public static void main(String[] args) {

String str1 = null;

String str2 = "hello";

System.out.println(str1.equals(str2));

}

这时候运行程序,就会出现以下情况:

空指针异常,因为 null. 任何方法都会出现异常。

所以一定要保证 str1 不能为null。

那么如果我们改一下,

public static void main(String[] args) {

String str1 = null;

String str2 = "hello";

System.out.println(str2.equals(str1));

}

所以我们知道 equals(),括号里可以是null,但是 点之前一定不能是 null.

public static void main(String[] args) {

String str1 = "hello";

System.out.println(str1.equals("hello")); // 方式1

System.out.println("hello".equals(str1)); // 方式2

}

当我们写代码遇到以上的情况时,我们应该尽量选方式2,这样保证 equals之前一定不为null,以防出现异常.

四、字符串常量池

在上面的例子中, String类的两种实例化操作, 直接赋值和 new 一个新的 String.

(1) 直接赋值

System.out.println("Hello".equals(str)); // 执行结果 false

String str1 = "hello" ;

String str2 = "hello" ;

String str3 = "hello" ;

System.out.println(str1 == str2); // true

System.out.println(str1 == str3); // true

System.out.println(str2 == str3); // true

String类的设计使用了共享设计模式

在JVM底层实际上会自动维护一个对象池(字符串常量池)

如果现在采用了直接赋值的模式进行String类的对象实例化操作,那么该实例化对象(字符串内容)将自动保存到这个对象池之中.

如果下次继续使用直接赋值的模式声明String类对象,此时对象池之中如若有指定内容,将直接进行引用

如若没有,则开辟新的字符串对象而后将其保存在对象池之中以供下次使用

理解 “池” (pool)

“池” 是编程中的一种常见的, 重要的提升效率的方式, 我们会在未来的学习中遇到各种 “内存池”, “线程池”, “数据库连接池” …然而池这样的概念不是计算机独有, 也是来自于生活中.   举个栗子:现实生活中有一种女神, 称为 “绿茶”, 在和高富帅谈着对象的同时, 还可能和别的屌丝搞暧昧. 这时候这个屌丝被称为 “备胎”. 那么为啥要有备胎? 因为一旦和高富帅分手了, 就可以立刻找备胎接盘, 这样 效率比较高.如果这个女神, 同时在和很多个屌丝搞暧昧, 那么这些备胎就称为 备胎池.

(2)采用构造方法

类对象使用构造方法实例化是标准做法。分析如下程序:

String str = new String("hello");

这样的做法有两个缺点:

1.  如果使用String构造方法就会开辟两块堆内存空间,并且其中一块堆内存将成为垃圾空间(字符串常量 “hello” 也是一个匿名对象, 用了一次之后就不再使用了, 就成为垃圾空间, 会被 JVM 自动回收掉).

2.  字符串共享问题. 同一个字符串可能会被存储多次, 比较浪费空间.

(3)intern 的使用

String str1 = "hello";

String str2 = new String("hello").intren();

从上面的由 构造方法定义字符串,我们会浪费内存空间,而这里有一个方法 ,叫做intern(),手动入池。

那这是什么意思呢?

这是先看一下传入构造方法的字符串在字符串常量池中是否存在,如果有的话,就把常量池中的引用传给当前的引用类型变量。

综上所述,我们一般使用 直接赋值法来 创建 String 对象。

我们再来看这样一组代码,来画一下他的内存结构

在第一步的代码中,new 了两个字符串"1",在堆中创建了两个对象,指向常量池中的"1",拼接在一起,s3.interb(),s3手动入池,“11"在池中没有,所以就把 堆中的"11"的引用 555 传入常量池中。s4 指向池中的"11”,而这时池中已经有了"11"的引用,所以s4 指向的就是 s3在入池的引用。

所以结果为 true。

所以呢,我们解决了一个疑问

在常量池当中,可以放 字符串的字面值常量,也可以放引用。什么时候放引用,就是类似于上面的那种情况之下,s3.intern(),s3所指向的这个对象在字符串常量池中是不存在的,那么入池的时候就把堆中s3的引用放入。

五、理解字符串不可变

字符串是一种不可变对象. 它的内容不可改变.这是什么意思呢?

public static void main(String[] args) {

String str = "hello" ;

str = str + " world" ;

str += "!!!" ;

System.out.println(str);

}

对于这种代码,乍一看我们以为成功的将str 每次与其他的字符串拼接,但是这样是不可以的, str 原来指向的是"hello",但是 在与" world"拼接之后,又会产生一个新的对象"helll world",再次拼接一个"!!!",那么又会产生一个新的对象"hello world!!!",在内存中就会产生多个对象。

我们最后需要的是"hello world!!!",但是却开辟了5块内存空间。

如果在一个循环中拼接,那么会开辟更多的内存空间!!

所以这样的代码是极为不可取的!!!

那么如何拼接呢,具体在之后的StringBuff、StringBuilder中介绍。

六、字符、字节、字符串

(1)字符与字符串

字符串内部包含一个字符数组,String 可以和 char[] 相互转换

1.字符数组转字符串

public static void main(String[] args) {

char[] val = {'h','e','l','l','o'};

String str = new String(val);

System.out.println(val);

}

此时我们 的 str 结果就是 “hello”,同时他也可以再给两个参数.

2.将部分字符数组中的内容转换为字符串

offset–偏移量

count-- 转换几个

public static void main(String[] args) {

char[] val = {'h','e','l','l','o'};

String str = new String(val,1,2);

System.out.println(str);

}

此时我们将val 中偏移1个,转换之后的两个数组元素为字符串

打印结果应该为 el

运行结果如下:

3.将字符串中对应索引转换为字符

public static void main(String[] args) {

String str = "hello";

char ch = str.charAt(1);

System.out.println(ch);

}

索引从0开始,我们输入1,所以转换的为字符串中的e

运行结果如下:

4.将字符串转换为字符数组

public static void main(String[] args) {

String str = "hello";

char[] val = str.toCharArray();

System.out.println(Arrays.toString(val));

}

我们用字符数组接收 str转换后的字符。

运行结果如下:

好了,了解了这几种字符与字符串的方法,我们通过几个练习来继续熟悉。

练习一

给定字符串一个字符串, 判断其是否全部由数字所组成.

思路: 将字符串变为字符数组而后判断每一位字符是否是" 0 “~”‘9'"之间的内容,如果是则为数字.

public static boolean func1(String str){

for (int i = 0; i

if(str.charAt(i)>'9' || str.charAt(i)<'0'){

return false;

}

}

return true;

}

(2)字节与字符串

字节常用于数据传输以及编码转换的处理之中,String 也能方便的和 byte[] 相互转换

常用方法:

1.字节数组转换为字符串

public static void main(String[] args) {

byte[] bytes = {97,98,99,100};

String str = new String(bytes);

System.out.println(str);

}

2.部分字节数组的内容转换为字符串

public static void main(String[] args) {

byte[] bytes = {97,98,99,100};

String str = new String(bytes,2,1);

System.out.println(str);

}

运行结果:

3.字符串转换为字节数组

public static void main(String[] args) {

String str = "abcd";

byte[] bytes = str.getBytes();

System.out.println(Arrays.toString(bytes));

}

运行结果:

(3) 小结

那么何时使用 byte[], 何时使用 char[] 呢?

byte[] 是把 String 按照一个字节一个字节的方式处理, 这种适合在网络传输, 数据存储这样的场景下使用. 更适合针对二进制数据来操作.

char[] 是吧 String 按照一个字符一个字符的方式处理, 更适合针对文本数据来操作, 尤其是包含中文的时候.

七、字符串的常见操作

(1)字符串比较

上面使用过String类提供的equals()方法,该方法本身是可以进行区分大小写的相等判断。除了这个方法之外,String类还提供有如下的比较操作.

1.区分大小写比较

public static void main(String[] args) {

String str1 = "abcd";

String str2 = "Abcd";

System.out.println(str1.equals(str2));

}

运行结果:

我们常

用的equals 方法 是区分大小写的,这点要注意。

2.不区分大小写的比较

public static void main(String[] args) {

String str1 = "abcd";

String str2 = "Abcd";

System.out.println(str1.equalsIgnoreCase(str2));

}

运行结果:

这种不区分大小写的比较还是很常见的,比如应用于验证码上,不区分大小写。

3.比较两个字符串的大小关系

public static void main(String[] args) {

String str1 = "abcd";

String str2 = "Abcd";

System.out.println(str1.compareTo(str2));

}

运行时结果

掌握了字符串比较相等的方法,下来我们来做一道练习题

比较字符串是否相等

题解思路:

将word1 字符串数组的内容都在str1 追加,word2 字符串数组的内容在str2 追加,最终equals 比较str1 str2 字符串的内容,相等返回 true,不等返回 false.

注意:参数等问题要考虑全面

(2)字符串查找

从一个完整的字符串之中可以判断指定内容是否存在,对于查找方法有如下定义:

判断一个字符串中是否存在子字符串

我们可以先看一下 contains 方法的源码

contains 方法的使用

public static void main(String[] args) {

String str = "bcdabc";

boolean flg = str.contains("abc");

System.out.println(flg);

}

运行结果:

所以可判断在"badabc" 这个字符串中存在 这个 “abc” 的子字符串。

找到子字符串的下标

我们先来看一下一个参数的 index 方法的源码

带一个参数的 index 方法的使用

public static void main(String[] args) {

String str = "ababcabcdabcde";

int index1 = str.indexOf("abc");

int index2 = str.indexOf("hello");

System.out.println(index1);

System.out.println("============");

System.out.println(index2);

}

运行结果:

两个参数的index 方法的使用

在下面我们又看到了一个index 方法,这说明 默认情况下,index 是从0下标开始查找的,如果再给他一个下标参数,那么就从指定的下标位置进行字符串查找。

使用:

public static void main(String[] args) {

String str = "abcabcdabcdef";

int index1 = str.indexOf("abc");

int index2 = str.indexOf("abc",6);

System.out.println(index1);

System.out.println("=================");

System.out.println(index2);

}

运行结果:

lastIndexOf 是从后向前查找 子字符串的位置

lastIndexOf 方法的使用

public static void main(String[] args) {

String str = "abcabcdabcdef";

int index = str.lastIndexOf("abc");

System.out.println(index);

}

运行结果:

同时 lastIndexOf 也有两个参数的方法,从指定下标开始从后向前进行查找。

判断是否由 参数字符串开头的

同时也有两个参数的方法,从指定位置判断是否由 指定字符串开头

判断是否由指定字符串进行结尾的

(3)字符串替换

(1)替换所有的指定内容

replaceAll 的使用

public static void main(String[] args) {

String str = "abcabcacbabc";

System.out.println(str);

System.out.println("=================");

String ret = str.replaceAll("ab","AB");

System.out.println(ret);

}

运行结果:

成功的把所有的 “ab” 替换成为 “AB”.

(2)替换首个要替换的内容.

replaceFirst 的使用

public static void main(String[] args) {

String str = "abcabcacbabc";

System.out.println(str);

System.out.println("=================");

String ret = str.replaceFirst("ab","AB");

System.out.println(ret);

}

运行结果:

注意说明:

由于字符串是不可变对象, 替换不修改当前字符串, 而是产生一个新的字符串.

(4)字符串拆分

可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串。

1.将字符串全部拆分

接收的类型是字符串数组类型,传参数时,传一个我们想要分割的符号。

split 的使用

public static void main(String[] args) {

String str = "rain7 is cool";

String[] strs = str.split(" ");

for (String s:strs) {

System.out.println(s);

}

}

我们在用 split 方法时, 以 空格 为分割符,将我们的str 字符串 进行拆分

我们来看拆分的效果

2.带两个参数的split 方法

还是以上面的字符串为例

public static void main(String[] args) {

String str = "rain7 is cool";

String[] strs = str.split(" ",2);

for (String s:strs) {

System.out.println(s);

}

}

运行结果:

我们除了将字符串作为参数,还将limit 设置为2,那么拆分后的数组长度就为2,所以运行结果就如上所示。

难点:

拆分是特别常用的操作. 一定要重点掌握. 另外有些特殊字符作为分割符可能无法正确切分, 需要加上转义字符

示例1

拆分 IP 地址

比如说我们要分割IP 地址,192.168.1.1,以 “.” 分割。

当我们运行时会发现 打印为空,这是为什么呢?

有些符号比较特殊,必须用到转义字符

“ \. ”才能表示一个真正的 “.”

同时"\"也需要进行转义,那么就又要再加一个斜杠。

“\\.”这时字符串才只能被 “ . ”分割。

1

public static void main(String[] args) {

String str = "19RcsejcZ2.168.1.1";

String[] strs = str.split("\\.");

for (String s:strs) {

System.out.println(s);

}

}

运行结果:

1. 字符"|","*","+"都得加上转义字符,前面加上"\\".

2. 而如果是"\",那么就得写成"\\".

3. 如果一个字符串中有多个分隔符,可以用"|"作为连字符.

连字符 “ | ” 的使用

public static void main(String[] args) {

String str = "1212@qq.com";

String[] ret = str.split("@|\\.");

for (String s:ret) {

System.out.println(s);

}

}

运行结果:

我们来一道练习题:

代码题解:

public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);

while(scanner.hasNext()){

String ret ="";

String str = scanner.nextLine();

String[] strs = str.split(" ");

for (String s:strs) {

ret += s;

}

System.out.println(ret);

}

}

运行结果:

注意:

1.注意多组输入 2.不建议在for循环中拼接字符串,在之后讲到的StringBuilder StringBuffer 之后可以知道如何拼接。

(5)字符串截取

从一个完整的字符串之中截取出部分内容。可用方法如下:

1.从指定下标截取到字符串结束

方法的使用

public static void main(String[] args) {

String str = "ilikeBeijing";

String ret = str.substring(4);

System.out.println(ret);

}

运行结果:

2.带有两个参数的subString 方法,截取指定下标范围内的字符串内容

方法的使用

public static String reverse(String s){

if(s==null){

return null;

}

int begun = 0;

int end = s.length()-1;

char[] chars = s.toCharArray();

while(begun

char tmp = chars[begun] ;

chars [begun] = chars [end];

chars[end] = tmp;

begun++;

end--;

}

return new String(chars);

}

public static void main(String[] args) {

String str = "Hello World!";

String ret = reverse(str);

System.out.println(ret);

}

运行结果

意:

1.指定下标范围 是 左闭右开的区间

2.截取后的字符串是一个新的对象

(6)其他操作方法

字符串操作还有很多其他的方法,在这里我们只进行简单介绍。

(7)字符串操作练习题

1.逆置字符串

题目要求

将字符串进行整体逆置

代码题解:

public static String reverse(String s){

if(s==null){

return null;

}

int begun = 0;

int end = s.lRcsejcZength()-1;

char[] chars = s.toCharArray();

while(begun

char tmp = chars[begun] ;

chars [begun] = chars [end];

chars[end] = tmp;

begun++;

end--;

}

return new String(chars);

}

public static void main(String[] args) {

String str = "Hello World!";

String ret = reverse(str);

System.out.println(ret);

}

运行结果:

成功的将字符串进行逆置

2.翻转字符串

我们首先对题目进行一下解读,我们要实现一个方法,给这个方法传入 一个字符串和一个 整数 size 。将大小为 size 的左半区 翻转到 右半区。如图所示:

思路实现:

1.首先将size 左半区进行单独逆置。

2.再将 size的右半区单独逆置。

3.整体字符串进行逆置。

代码展示:

public static String reverse(String s,int begun,int end){

if(s==null){

return null;

}

char[] chars = s.toCharArray();

while(begun

char tmp = chars[begun] ;

chars [begun] = chars [end];

chars[end] = tmp;

begun++;

end--;

}

return new String(chars);

}

public static String reversSentence(String str,int k){

str = reverse(str,0,k-1);

str = reverse(str,k,str.length()-1);

str = reverse(str,0,str.length()-1);

return str;

}

public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);

String str = scanner.next();

int n = scanner.nextInt();

String ret = reversSentence(str,n);

System.out.println(ret);

}

运行结果:

八、StringBuffer 和 StringBuilder

StringBuffer 和 StringBuilder 又是一种新的字符串类型。

通常来讲String的操作比较简单,但是由于String的不可更改特性,为了方便字符串的修改,提供 StringBuffer 和 StringBuilder 类。

StringBuffer 和 StringBuilder 在功能上大部分是相同的,在这里我们着重介绍 StringBuffer.

(1)append 方法

public static void main(String[] args) {

StringBuffer sb = new StringBuffer();

sb.append("a");

sb.append("b");

sb.append("c");

System.out.println(sb);

}

在String中使用"+"来进行字符串连接,但是这个操作在StringBuffer类中需要更改为append()方法。

String和StringBuffer最大的区别在于:String的内容无法修改,而StringBuffer的内容可以修改。频繁修改字符串的情况考虑使用 StingBuffer。

运行结果:

我们来看一下 StringBuffer 的 append 方法的源码

我们来看一下 以下的代码:

public static void main(String[] args) {

String str1 = "abc";

String str2 = "def";

String str3 = str1+str2;

System.out.println(str3);

}

我们对以上代码进行编译一下:

我们将这个过程用 StringBuilder 写一下:

public static void main(Sthttp://ring[] args) {

String str1 ="abc";

String str2 = "def";

StringBuilder sb = new StringBuilder();

sb.append(str1);

sb.append(str2);

String str3 = sb.toString();

System.out.println(str3);

}

说明:

String 的“+” 拼接,会被底层优化为一个 StringBuilder ,拼接的时候会用到 append 方法

(2)注意

注意:  String和StringBuffer类不能直接转换。如果要想互相转换,可以采用如下原则:

String变为StringBuffer:利用StringBuffer的构造方法或append()方法   StringBuffer变为String:调用toString()方法。

除了append()方法外,StringBuffer也有一些String类没有的方法:

字符串反转:

public synchronized StringBuffer reverse();

(3)区别

String 和 StringBuilder 及 StringBuffer 的区别

String 进行拼接时,底层会被优化为StringBuilder

String的拼接会产生临时对象,但是后两者每次都只是返回当前对象的引用。

String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.

StringBuilder 和 StringBuffer 的区别

我们来看一下这两个类的 append 方法

所以 StringBuffer 和 StringBuilder 的区别主要体现在线程安全上 。

1.StringBuffer与StringBuilder大部分功能是相似的

2.StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作

九.总结

字符串操作是我们以后工作中非常常用的操作. 使用起来都非常简单方便, 我们一定要使用熟练.

好了今天的知识就分享到这里,希望大家多多关注我们的其他内容!

if(str.charAt(i)>'9' || str.charAt(i)<'0'){

return false;

}

}

return true;

}

(2)字节与字符串

字节常用于数据传输以及编码转换的处理之中,String 也能方便的和 byte[] 相互转换

常用方法:

1.字节数组转换为字符串

public static void main(String[] args) {

byte[] bytes = {97,98,99,100};

String str = new String(bytes);

System.out.println(str);

}

2.部分字节数组的内容转换为字符串

public static void main(String[] args) {

byte[] bytes = {97,98,99,100};

String str = new String(bytes,2,1);

System.out.println(str);

}

运行结果:

3.字符串转换为字节数组

public static void main(String[] args) {

String str = "abcd";

byte[] bytes = str.getBytes();

System.out.println(Arrays.toString(bytes));

}

运行结果:

(3) 小结

那么何时使用 byte[], 何时使用 char[] 呢?

byte[] 是把 String 按照一个字节一个字节的方式处理, 这种适合在网络传输, 数据存储这样的场景下使用. 更适合针对二进制数据来操作.

char[] 是吧 String 按照一个字符一个字符的方式处理, 更适合针对文本数据来操作, 尤其是包含中文的时候.

七、字符串的常见操作

(1)字符串比较

上面使用过String类提供的equals()方法,该方法本身是可以进行区分大小写的相等判断。除了这个方法之外,String类还提供有如下的比较操作.

1.区分大小写比较

public static void main(String[] args) {

String str1 = "abcd";

String str2 = "Abcd";

System.out.println(str1.equals(str2));

}

运行结果:

我们常

用的equals 方法 是区分大小写的,这点要注意。

2.不区分大小写的比较

public static void main(String[] args) {

String str1 = "abcd";

String str2 = "Abcd";

System.out.println(str1.equalsIgnoreCase(str2));

}

运行结果:

这种不区分大小写的比较还是很常见的,比如应用于验证码上,不区分大小写。

3.比较两个字符串的大小关系

public static void main(String[] args) {

String str1 = "abcd";

String str2 = "Abcd";

System.out.println(str1.compareTo(str2));

}

运行时结果

掌握了字符串比较相等的方法,下来我们来做一道练习题

比较字符串是否相等

题解思路:

将word1 字符串数组的内容都在str1 追加,word2 字符串数组的内容在str2 追加,最终equals 比较str1 str2 字符串的内容,相等返回 true,不等返回 false.

注意:参数等问题要考虑全面

(2)字符串查找

从一个完整的字符串之中可以判断指定内容是否存在,对于查找方法有如下定义:

判断一个字符串中是否存在子字符串

我们可以先看一下 contains 方法的源码

contains 方法的使用

public static void main(String[] args) {

String str = "bcdabc";

boolean flg = str.contains("abc");

System.out.println(flg);

}

运行结果:

所以可判断在"badabc" 这个字符串中存在 这个 “abc” 的子字符串。

找到子字符串的下标

我们先来看一下一个参数的 index 方法的源码

带一个参数的 index 方法的使用

public static void main(String[] args) {

String str = "ababcabcdabcde";

int index1 = str.indexOf("abc");

int index2 = str.indexOf("hello");

System.out.println(index1);

System.out.println("============");

System.out.println(index2);

}

运行结果:

两个参数的index 方法的使用

在下面我们又看到了一个index 方法,这说明 默认情况下,index 是从0下标开始查找的,如果再给他一个下标参数,那么就从指定的下标位置进行字符串查找。

使用:

public static void main(String[] args) {

String str = "abcabcdabcdef";

int index1 = str.indexOf("abc");

int index2 = str.indexOf("abc",6);

System.out.println(index1);

System.out.println("=================");

System.out.println(index2);

}

运行结果:

lastIndexOf 是从后向前查找 子字符串的位置

lastIndexOf 方法的使用

public static void main(String[] args) {

String str = "abcabcdabcdef";

int index = str.lastIndexOf("abc");

System.out.println(index);

}

运行结果:

同时 lastIndexOf 也有两个参数的方法,从指定下标开始从后向前进行查找。

判断是否由 参数字符串开头的

同时也有两个参数的方法,从指定位置判断是否由 指定字符串开头

判断是否由指定字符串进行结尾的

(3)字符串替换

(1)替换所有的指定内容

replaceAll 的使用

public static void main(String[] args) {

String str = "abcabcacbabc";

System.out.println(str);

System.out.println("=================");

String ret = str.replaceAll("ab","AB");

System.out.println(ret);

}

运行结果:

成功的把所有的 “ab” 替换成为 “AB”.

(2)替换首个要替换的内容.

replaceFirst 的使用

public static void main(String[] args) {

String str = "abcabcacbabc";

System.out.println(str);

System.out.println("=================");

String ret = str.replaceFirst("ab","AB");

System.out.println(ret);

}

运行结果:

注意说明:

由于字符串是不可变对象, 替换不修改当前字符串, 而是产生一个新的字符串.

(4)字符串拆分

可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串。

1.将字符串全部拆分

接收的类型是字符串数组类型,传参数时,传一个我们想要分割的符号。

split 的使用

public static void main(String[] args) {

String str = "rain7 is cool";

String[] strs = str.split(" ");

for (String s:strs) {

System.out.println(s);

}

}

我们在用 split 方法时, 以 空格 为分割符,将我们的str 字符串 进行拆分

我们来看拆分的效果

2.带两个参数的split 方法

还是以上面的字符串为例

public static void main(String[] args) {

String str = "rain7 is cool";

String[] strs = str.split(" ",2);

for (String s:strs) {

System.out.println(s);

}

}

运行结果:

我们除了将字符串作为参数,还将limit 设置为2,那么拆分后的数组长度就为2,所以运行结果就如上所示。

难点:

拆分是特别常用的操作. 一定要重点掌握. 另外有些特殊字符作为分割符可能无法正确切分, 需要加上转义字符

示例1

拆分 IP 地址

比如说我们要分割IP 地址,192.168.1.1,以 “.” 分割。

当我们运行时会发现 打印为空,这是为什么呢?

有些符号比较特殊,必须用到转义字符

“ \. ”才能表示一个真正的 “.”

同时"\"也需要进行转义,那么就又要再加一个斜杠。

“\\.”这时字符串才只能被 “ . ”分割。

1

public static void main(String[] args) {

String str = "19RcsejcZ2.168.1.1";

String[] strs = str.split("\\.");

for (String s:strs) {

System.out.println(s);

}

}

运行结果:

1. 字符"|","*","+"都得加上转义字符,前面加上"\\".

2. 而如果是"\",那么就得写成"\\".

3. 如果一个字符串中有多个分隔符,可以用"|"作为连字符.

连字符 “ | ” 的使用

public static void main(String[] args) {

String str = "1212@qq.com";

String[] ret = str.split("@|\\.");

for (String s:ret) {

System.out.println(s);

}

}

运行结果:

我们来一道练习题:

代码题解:

public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);

while(scanner.hasNext()){

String ret ="";

String str = scanner.nextLine();

String[] strs = str.split(" ");

for (String s:strs) {

ret += s;

}

System.out.println(ret);

}

}

运行结果:

注意:

1.注意多组输入 2.不建议在for循环中拼接字符串,在之后讲到的StringBuilder StringBuffer 之后可以知道如何拼接。

(5)字符串截取

从一个完整的字符串之中截取出部分内容。可用方法如下:

1.从指定下标截取到字符串结束

方法的使用

public static void main(String[] args) {

String str = "ilikeBeijing";

String ret = str.substring(4);

System.out.println(ret);

}

运行结果:

2.带有两个参数的subString 方法,截取指定下标范围内的字符串内容

方法的使用

public static String reverse(String s){

if(s==null){

return null;

}

int begun = 0;

int end = s.length()-1;

char[] chars = s.toCharArray();

while(begun

char tmp = chars[begun] ;

chars [begun] = chars [end];

chars[end] = tmp;

begun++;

end--;

}

return new String(chars);

}

public static void main(String[] args) {

String str = "Hello World!";

String ret = reverse(str);

System.out.println(ret);

}

运行结果

意:

1.指定下标范围 是 左闭右开的区间

2.截取后的字符串是一个新的对象

(6)其他操作方法

字符串操作还有很多其他的方法,在这里我们只进行简单介绍。

(7)字符串操作练习题

1.逆置字符串

题目要求

将字符串进行整体逆置

代码题解:

public static String reverse(String s){

if(s==null){

return null;

}

int begun = 0;

int end = s.lRcsejcZength()-1;

char[] chars = s.toCharArray();

while(begun

char tmp = chars[begun] ;

chars [begun] = chars [end];

chars[end] = tmp;

begun++;

end--;

}

return new String(chars);

}

public static void main(String[] args) {

String str = "Hello World!";

String ret = reverse(str);

System.out.println(ret);

}

运行结果:

成功的将字符串进行逆置

2.翻转字符串

我们首先对题目进行一下解读,我们要实现一个方法,给这个方法传入 一个字符串和一个 整数 size 。将大小为 size 的左半区 翻转到 右半区。如图所示:

思路实现:

1.首先将size 左半区进行单独逆置。

2.再将 size的右半区单独逆置。

3.整体字符串进行逆置。

代码展示:

public static String reverse(String s,int begun,int end){

if(s==null){

return null;

}

char[] chars = s.toCharArray();

while(begun

char tmp = chars[begun] ;

chars [begun] = chars [end];

chars[end] = tmp;

begun++;

end--;

}

return new String(chars);

}

public static String reversSentence(String str,int k){

str = reverse(str,0,k-1);

str = reverse(str,k,str.length()-1);

str = reverse(str,0,str.length()-1);

return str;

}

public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);

String str = scanner.next();

int n = scanner.nextInt();

String ret = reversSentence(str,n);

System.out.println(ret);

}

运行结果:

八、StringBuffer 和 StringBuilder

StringBuffer 和 StringBuilder 又是一种新的字符串类型。

通常来讲String的操作比较简单,但是由于String的不可更改特性,为了方便字符串的修改,提供 StringBuffer 和 StringBuilder 类。

StringBuffer 和 StringBuilder 在功能上大部分是相同的,在这里我们着重介绍 StringBuffer.

(1)append 方法

public static void main(String[] args) {

StringBuffer sb = new StringBuffer();

sb.append("a");

sb.append("b");

sb.append("c");

System.out.println(sb);

}

在String中使用"+"来进行字符串连接,但是这个操作在StringBuffer类中需要更改为append()方法。

String和StringBuffer最大的区别在于:String的内容无法修改,而StringBuffer的内容可以修改。频繁修改字符串的情况考虑使用 StingBuffer。

运行结果:

我们来看一下 StringBuffer 的 append 方法的源码

我们来看一下 以下的代码:

public static void main(String[] args) {

String str1 = "abc";

String str2 = "def";

String str3 = str1+str2;

System.out.println(str3);

}

我们对以上代码进行编译一下:

我们将这个过程用 StringBuilder 写一下:

public static void main(Sthttp://ring[] args) {

String str1 ="abc";

String str2 = "def";

StringBuilder sb = new StringBuilder();

sb.append(str1);

sb.append(str2);

String str3 = sb.toString();

System.out.println(str3);

}

说明:

String 的“+” 拼接,会被底层优化为一个 StringBuilder ,拼接的时候会用到 append 方法

(2)注意

注意:  String和StringBuffer类不能直接转换。如果要想互相转换,可以采用如下原则:

String变为StringBuffer:利用StringBuffer的构造方法或append()方法   StringBuffer变为String:调用toString()方法。

除了append()方法外,StringBuffer也有一些String类没有的方法:

字符串反转:

public synchronized StringBuffer reverse();

(3)区别

String 和 StringBuilder 及 StringBuffer 的区别

String 进行拼接时,底层会被优化为StringBuilder

String的拼接会产生临时对象,但是后两者每次都只是返回当前对象的引用。

String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.

StringBuilder 和 StringBuffer 的区别

我们来看一下这两个类的 append 方法

所以 StringBuffer 和 StringBuilder 的区别主要体现在线程安全上 。

1.StringBuffer与StringBuilder大部分功能是相似的

2.StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作

九.总结

字符串操作是我们以后工作中非常常用的操作. 使用起来都非常简单方便, 我们一定要使用熟练.

好了今天的知识就分享到这里,希望大家多多关注我们的其他内容!

char tmp = chars[begun] ;

chars [begun] = chars [end];

chars[end] = tmp;

begun++;

end--;

}

return new String(chars);

}

public static void main(String[] args) {

String str = "Hello World!";

String ret = reverse(str);

System.out.println(ret);

}

运行结果

意:

1.指定下标范围 是 左闭右开的区间

2.截取后的字符串是一个新的对象

(6)其他操作方法

字符串操作还有很多其他的方法,在这里我们只进行简单介绍。

(7)字符串操作练习题

1.逆置字符串

题目要求

将字符串进行整体逆置

代码题解:

public static String reverse(String s){

if(s==null){

return null;

}

int begun = 0;

int end = s.lRcsejcZength()-1;

char[] chars = s.toCharArray();

while(begun

char tmp = chars[begun] ;

chars [begun] = chars [end];

chars[end] = tmp;

begun++;

end--;

}

return new String(chars);

}

public static void main(String[] args) {

String str = "Hello World!";

String ret = reverse(str);

System.out.println(ret);

}

运行结果:

成功的将字符串进行逆置

2.翻转字符串

我们首先对题目进行一下解读,我们要实现一个方法,给这个方法传入 一个字符串和一个 整数 size 。将大小为 size 的左半区 翻转到 右半区。如图所示:

思路实现:

1.首先将size 左半区进行单独逆置。

2.再将 size的右半区单独逆置。

3.整体字符串进行逆置。

代码展示:

public static String reverse(String s,int begun,int end){

if(s==null){

return null;

}

char[] chars = s.toCharArray();

while(begun

char tmp = chars[begun] ;

chars [begun] = chars [end];

chars[end] = tmp;

begun++;

end--;

}

return new String(chars);

}

public static String reversSentence(String str,int k){

str = reverse(str,0,k-1);

str = reverse(str,k,str.length()-1);

str = reverse(str,0,str.length()-1);

return str;

}

public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);

String str = scanner.next();

int n = scanner.nextInt();

String ret = reversSentence(str,n);

System.out.println(ret);

}

运行结果:

八、StringBuffer 和 StringBuilder

StringBuffer 和 StringBuilder 又是一种新的字符串类型。

通常来讲String的操作比较简单,但是由于String的不可更改特性,为了方便字符串的修改,提供 StringBuffer 和 StringBuilder 类。

StringBuffer 和 StringBuilder 在功能上大部分是相同的,在这里我们着重介绍 StringBuffer.

(1)append 方法

public static void main(String[] args) {

StringBuffer sb = new StringBuffer();

sb.append("a");

sb.append("b");

sb.append("c");

System.out.println(sb);

}

在String中使用"+"来进行字符串连接,但是这个操作在StringBuffer类中需要更改为append()方法。

String和StringBuffer最大的区别在于:String的内容无法修改,而StringBuffer的内容可以修改。频繁修改字符串的情况考虑使用 StingBuffer。

运行结果:

我们来看一下 StringBuffer 的 append 方法的源码

我们来看一下 以下的代码:

public static void main(String[] args) {

String str1 = "abc";

String str2 = "def";

String str3 = str1+str2;

System.out.println(str3);

}

我们对以上代码进行编译一下:

我们将这个过程用 StringBuilder 写一下:

public static void main(Sthttp://ring[] args) {

String str1 ="abc";

String str2 = "def";

StringBuilder sb = new StringBuilder();

sb.append(str1);

sb.append(str2);

String str3 = sb.toString();

System.out.println(str3);

}

说明:

String 的“+” 拼接,会被底层优化为一个 StringBuilder ,拼接的时候会用到 append 方法

(2)注意

注意:  String和StringBuffer类不能直接转换。如果要想互相转换,可以采用如下原则:

String变为StringBuffer:利用StringBuffer的构造方法或append()方法   StringBuffer变为String:调用toString()方法。

除了append()方法外,StringBuffer也有一些String类没有的方法:

字符串反转:

public synchronized StringBuffer reverse();

(3)区别

String 和 StringBuilder 及 StringBuffer 的区别

String 进行拼接时,底层会被优化为StringBuilder

String的拼接会产生临时对象,但是后两者每次都只是返回当前对象的引用。

String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.

StringBuilder 和 StringBuffer 的区别

我们来看一下这两个类的 append 方法

所以 StringBuffer 和 StringBuilder 的区别主要体现在线程安全上 。

1.StringBuffer与StringBuilder大部分功能是相似的

2.StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作

九.总结

字符串操作是我们以后工作中非常常用的操作. 使用起来都非常简单方便, 我们一定要使用熟练.

好了今天的知识就分享到这里,希望大家多多关注我们的其他内容!

char tmp = chars[begun] ;

chars [begun] = chars [end];

chars[end] = tmp;

begun++;

end--;

}

return new String(chars);

}

public static void main(String[] args) {

String str = "Hello World!";

String ret = reverse(str);

System.out.println(ret);

}

运行结果:

成功的将字符串进行逆置

2.翻转字符串

我们首先对题目进行一下解读,我们要实现一个方法,给这个方法传入 一个字符串和一个 整数 size 。将大小为 size 的左半区 翻转到 右半区。如图所示:

思路实现:

1.首先将size 左半区进行单独逆置。

2.再将 size的右半区单独逆置。

3.整体字符串进行逆置。

代码展示:

public static String reverse(String s,int begun,int end){

if(s==null){

return null;

}

char[] chars = s.toCharArray();

while(begun

char tmp = chars[begun] ;

chars [begun] = chars [end];

chars[end] = tmp;

begun++;

end--;

}

return new String(chars);

}

public static String reversSentence(String str,int k){

str = reverse(str,0,k-1);

str = reverse(str,k,str.length()-1);

str = reverse(str,0,str.length()-1);

return str;

}

public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);

String str = scanner.next();

int n = scanner.nextInt();

String ret = reversSentence(str,n);

System.out.println(ret);

}

运行结果:

八、StringBuffer 和 StringBuilder

StringBuffer 和 StringBuilder 又是一种新的字符串类型。

通常来讲String的操作比较简单,但是由于String的不可更改特性,为了方便字符串的修改,提供 StringBuffer 和 StringBuilder 类。

StringBuffer 和 StringBuilder 在功能上大部分是相同的,在这里我们着重介绍 StringBuffer.

(1)append 方法

public static void main(String[] args) {

StringBuffer sb = new StringBuffer();

sb.append("a");

sb.append("b");

sb.append("c");

System.out.println(sb);

}

在String中使用"+"来进行字符串连接,但是这个操作在StringBuffer类中需要更改为append()方法。

String和StringBuffer最大的区别在于:String的内容无法修改,而StringBuffer的内容可以修改。频繁修改字符串的情况考虑使用 StingBuffer。

运行结果:

我们来看一下 StringBuffer 的 append 方法的源码

我们来看一下 以下的代码:

public static void main(String[] args) {

String str1 = "abc";

String str2 = "def";

String str3 = str1+str2;

System.out.println(str3);

}

我们对以上代码进行编译一下:

我们将这个过程用 StringBuilder 写一下:

public static void main(Sthttp://ring[] args) {

String str1 ="abc";

String str2 = "def";

StringBuilder sb = new StringBuilder();

sb.append(str1);

sb.append(str2);

String str3 = sb.toString();

System.out.println(str3);

}

说明:

String 的“+” 拼接,会被底层优化为一个 StringBuilder ,拼接的时候会用到 append 方法

(2)注意

注意:  String和StringBuffer类不能直接转换。如果要想互相转换,可以采用如下原则:

String变为StringBuffer:利用StringBuffer的构造方法或append()方法   StringBuffer变为String:调用toString()方法。

除了append()方法外,StringBuffer也有一些String类没有的方法:

字符串反转:

public synchronized StringBuffer reverse();

(3)区别

String 和 StringBuilder 及 StringBuffer 的区别

String 进行拼接时,底层会被优化为StringBuilder

String的拼接会产生临时对象,但是后两者每次都只是返回当前对象的引用。

String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.

StringBuilder 和 StringBuffer 的区别

我们来看一下这两个类的 append 方法

所以 StringBuffer 和 StringBuilder 的区别主要体现在线程安全上 。

1.StringBuffer与StringBuilder大部分功能是相似的

2.StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作

九.总结

字符串操作是我们以后工作中非常常用的操作. 使用起来都非常简单方便, 我们一定要使用熟练.

好了今天的知识就分享到这里,希望大家多多关注我们的其他内容!

char tmp = chars[begun] ;

chars [begun] = chars [end];

chars[end] = tmp;

begun++;

end--;

}

return new String(chars);

}

public static String reversSentence(String str,int k){

str = reverse(str,0,k-1);

str = reverse(str,k,str.length()-1);

str = reverse(str,0,str.length()-1);

return str;

}

public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);

String str = scanner.next();

int n = scanner.nextInt();

String ret = reversSentence(str,n);

System.out.println(ret);

}

运行结果:

八、StringBuffer 和 StringBuilder

StringBuffer 和 StringBuilder 又是一种新的字符串类型。

通常来讲String的操作比较简单,但是由于String的不可更改特性,为了方便字符串的修改,提供 StringBuffer 和 StringBuilder 类。

StringBuffer 和 StringBuilder 在功能上大部分是相同的,在这里我们着重介绍 StringBuffer.

(1)append 方法

public static void main(String[] args) {

StringBuffer sb = new StringBuffer();

sb.append("a");

sb.append("b");

sb.append("c");

System.out.println(sb);

}

在String中使用"+"来进行字符串连接,但是这个操作在StringBuffer类中需要更改为append()方法。

String和StringBuffer最大的区别在于:String的内容无法修改,而StringBuffer的内容可以修改。频繁修改字符串的情况考虑使用 StingBuffer。

运行结果:

我们来看一下 StringBuffer 的 append 方法的源码

我们来看一下 以下的代码:

public static void main(String[] args) {

String str1 = "abc";

String str2 = "def";

String str3 = str1+str2;

System.out.println(str3);

}

我们对以上代码进行编译一下:

我们将这个过程用 StringBuilder 写一下:

public static void main(Sthttp://ring[] args) {

String str1 ="abc";

String str2 = "def";

StringBuilder sb = new StringBuilder();

sb.append(str1);

sb.append(str2);

String str3 = sb.toString();

System.out.println(str3);

}

说明:

String 的“+” 拼接,会被底层优化为一个 StringBuilder ,拼接的时候会用到 append 方法

(2)注意

注意:  String和StringBuffer类不能直接转换。如果要想互相转换,可以采用如下原则:

String变为StringBuffer:利用StringBuffer的构造方法或append()方法   StringBuffer变为String:调用toString()方法。

除了append()方法外,StringBuffer也有一些String类没有的方法:

字符串反转:

public synchronized StringBuffer reverse();

(3)区别

String 和 StringBuilder 及 StringBuffer 的区别

String 进行拼接时,底层会被优化为StringBuilder

String的拼接会产生临时对象,但是后两者每次都只是返回当前对象的引用。

String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.

StringBuilder 和 StringBuffer 的区别

我们来看一下这两个类的 append 方法

所以 StringBuffer 和 StringBuilder 的区别主要体现在线程安全上 。

1.StringBuffer与StringBuilder大部分功能是相似的

2.StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作

九.总结

字符串操作是我们以后工作中非常常用的操作. 使用起来都非常简单方便, 我们一定要使用熟练.

好了今天的知识就分享到这里,希望大家多多关注我们的其他内容!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:工业以太网交换机的光口和电口有什么区别?
下一篇:工业路由器和工业交换机的区别介绍
相关文章

 发表评论

暂时没有评论,来抢沙发吧~