JavaSE基础:字符串

栏目: Java · 发布时间: 6年前

内容简介:JavaSE基础:字符串

说在前面的话:

String类是我个人认为是 Java 设计当中一个特殊的,虽然String本身 特殊引用数据类型

但是她却可以想基本数据类型那样直接赋值!!!

1.String类的两种对象实例化方式

String类之所以特殊,主要原因在于其有两种不同的对象的实例化方式.

  • 采用直接赋值字符串的形式为String类对象实例化(推荐使用的写法)

    package com.shxt.demo01;
    public class StringDemo01 {
        public static void main(String[] args) {
            String str = "直接方式实例化方式";//使用频率特别高
            System.out.println(str);
        }
    }
  • 采用String类的构造方法为String类进行实例化,String类重载了构造方法,在Java EE中我们会使用到字符串转码问题等会使用到

    package com.shxt.demo01;
    public class StringDemo02 {
        public static void main(String[] args) {
            String str = new String("构造函数实例化String字符串");
            System.out.println(str);
        }
    }

2.String是不可变的

对下面的代码进行分析说明

package com.shxt.demo01;
public class StringDemo03 {
    public static void main(String[] args) {
        String s = "abcd";

        s = "dbcdel";
    }
}

String不可变很简单,我们给一个已有的s字符串变量赋值为"abcd",第二次赋值成"abcdel",不是在原内存地址上修改,而是重新执行一个新对象,行地址.

JavaSE基础:字符串

为什么String就是不可变的呢? 我需要知道原因

开JDK源码, java.lang.String 类起手前三行,是这样写的:

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /* String的本质是一个char数组,并且使用了final关键修饰*/
    /** The value is used for character storage. */
    private final char value[];
	... ...
	... ...
}

代码分析:

1.String类是用final关键字修饰,这说明String不可继承

2.String类的主要成员字段value是个char[ ]数组,而且是用 final 修饰的。

final修饰的字段创建以后就不可改变。

3.String类的用法说明

String类在java.lang包中,java使用String类创建一个字符串变量,字符串变量属于对象。java把String类声明的final类,不能有子类。String类对象创建后不能修改,由0或多个字符组成,包含在一对双引号之间,下面简单的熟悉一下其常用的API

java.lang.String  
  
 char charAt (int index)              返回index所指定的字符  
 String concat(String str)            将两字符串连接  
 boolean endsWith(String str)         测试字符串是否以str结尾  
 boolean equals(Object obj)           比较两对象  
 char[] getBytes                      将字符串转换成字符数组返回  
 char[] getBytes(String str)          将指定的字符串转成制服数组返回  
 boolean startsWith(String str)       测试字符串是否以str开始  
 int length()                         返回字符串的长度  
 String replace(char old ,char new)   将old用new替代  
 char[] toCharArray                   将字符串转换成字符数组  
 String toLowerCase()                 将字符串内的字符改写成小写  
 String toUpperCase()                 将字符串内的字符改写成大写  
 String valueOf(Boolean b)            将布尔方法b的内容用字符串表示  
 String valueOf(char ch)              将字符ch的内容用字符串表示  
 String valueOf(int index)            将数字index的内容用字符串表示  
 String valueOf(long l)               将长整数字l的内容用字符串表示  
 String substring(int1,int2)          取出字符串内第int1位置到int2的字符串

(1) 字符串比较

A.字符串上使用"=="比较

实际开发中字符的比较不会使用"=="进行比较,请回顾我们之前学习的内存地址方面的知识

package com.shxt.demo01;
public class StringDemo04 {
    public static void main(String[] args) {
        String str1 = "hanpang" ;                     //直接赋值实例化对象
        String str2 = new String("hanpang");  //构造方法实例化对象
        String str3 = str2;                           //引用传递


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

内存分析图如下:

JavaSE基础:字符串

代码分析:

使用"=="的确完成了相等的判断,但是最终判断的是两个对象是否相等,属于 数值判断 --判断两个对象的内存地址的数值,并没有判断起内容

如果想完成字符串内从的判断,必须要使用String类的操作方法

public boolean equals(String str)

B.使用equals()方法进行比较

package com.shxt.demo01;
public class StringDemo05 {
    public static void main(String[] args) {
        String str1 = "hanpang" ;                     //直接赋值实例化对象
        String str2 = new String("hanpang");          //构造方法实例化对象
        String str3 = str2;                           //引用传递


        System.out.println(str1.equals(str2));   //true
        System.out.println(str1.equals(str3));   //true
        System.out.println(str2.equals(str3));   //true
    }
}

C.使用equals()方法的陷阱

以后要注意如何使用equals方法

package com.shxt.demo01;
public class StringDemo06 {
    public static void main(String[] args) {
        String str1 = null ;

        if(str1.equals("Hello")){
            System.out.println("成功");
        }
    }
}

运行后会在控制台报空指针的异常信息

Exception in thread "main" java.lang.NullPointerException
	at com.shxt.demo01.StringDemo06.main(StringDemo06.java:6) //错误的位置

修改后的代码为[重点!重点!重点]

package com.shxt.demo01;
public class StringDemo06 {
    public static void main(String[] args) {
        String str1 = null ;

        if("Hello".equals(str1)){ //修改后的代码
            System.out.println("成功");
        }
    }
}

常见面试题分析,请解释String类中"=="和"equals()"的区别?

  • == : 比较两个字符串内存地址的数值是否相等,属于数值比较
  • equals() : 比较两个字符串的内容,属于内容比较

简单的面试,这个属于常识

(2) 字符串与字符

编号 方法名称 类型 描述
1 public String(char[] value) 构造方法 将字符数组内容变成字符串
2 public String(char[] value,int offset,int count) 构造方法 将部分字符数组变为字符串
offset表示开始点
count标识操作的长度
3 public char charAt(int index) 普通方法 取得指定索引位置的字符串,
索引从0开始
4 public char[] toCharArray() 普通方法 将字符串转换为字符数组

验证charAt()方法

package com.shxt.demo01;
public class StringDemo07 {
    public static void main(String[] args) {
        String str = "welcomeshxt" ;
        char c = str.charAt(0);
        System.out.println(c);
    }
}

验证toCharArray()方法

package com.shxt.demo01;
public class StringDemo08 {
    public static void main(String[] args) {
        String str = "welcomeshxt" ;
        char[] data = str.toCharArray();

        for (int i = 0; i < data.length; i++) {
            System.out.print(data[i]+",");
        }
    }
}

练习题

将全小写的英文字符串"welcomeshxt",变成大写的字符串,在控制台输出的内容为WELCOMESHXT 和 SHXT 两个字符串

package com.shxt.demo01;
public class StringDemo09 {
    public static void main(String[] args) {
        String str = "welcomeshxt" ;
        
      	
        
    }
}

(4) 字符串和字节

编号 方法名称 类型 描述
1 public String(byte[] bytes) 构造方法 将字节数组内容变成字符串
2 public String(byte[] bytes,int offset,int length) 构造方法 将部分字节数组变为字符串
3 public byte[] getBytes() 普通方法 将字符串变为字节数组
4 public byte[] getBytes(String charsetName)
throws UnsupportedEncodingException
普通方法 字符串转码操作[重点]
package com.shxt.demo01;
public class StringDemo09 {
    public static void main(String[] args) {
        String str = "welcomeshxt" ;
        byte[] data = str.getBytes();

        for (int i = 0; i < data.length; i++) {
            System.out.print(data[i]+",");
            data[i] -=32;//扩展赋值运算符,不会改变类型
        }
        System.out.println();
        System.out.println("全部字节转为字符串:"+new String(data));
        System.out.println("全部部分字节转为字符串:"+new String(data,7,4));
    }
}

(5) 字符串查找

在String类中提供了从一个字符串查找指定字符串是否存在的操作,下面提供的说明必须要牢记

编号 方法名称 类型 描述
1 public boolean contains(String s) 普通方法 查找指定的字符串是否存在
2 public int indexOf(String s) 普通方法 从头查找指定的字符串位置,
找不到返回-1
3 public int indexOf(String s,int fromIndex) 普通方法 由指定位置向后查找字符串的位置,
找不到返回-1
4 public int lastIndexOf(String s) 普通方法 从后查找指定的字符串位置,
找不到返回-1
5 public int lastIndexOf(String s,int fromIndex) 普通方法 从指定的位置由后向前查找
6 public boolean startsWith(String prefix) 普通方法 判断是否以指定的字符串开头
7 public boolean startsWith(String prefix,int offset) 普通方法 从指定的位置判断是否以指定的字符串开头
8 public boolean endsWith(String suffix) 普通方法 判断是否以指定字符串结尾
package com.shxt.demo01;
public class StringDemo10 {
    public static void main(String[] args) {
        String str = "##pang@@sir**" ; //定义一个字符串
        System.out.println(str.startsWith("##")); //判断开头
        System.out.println(str.startsWith("sir",5)); // 从指定的位置开始判断开头
        System.out.println(str.endsWith("**")); // 判断结尾

        System.out.println(str.contains("sir")); //查找字符串是否存在
        System.out.println(str.contains("AA"));

        System.out.println(str.indexOf("sir"));//查找字符串的位置
        System.out.println(str.indexOf("AA"));

        System.out.println(str.lastIndexOf("sir"));//查找字符串的位置
        System.out.println(str.lastIndexOf("AA"));

    }
}

(6) 字符串截取

编号 方法名称 类型 描述
1 public String substring(int beginIndex) 普通方法 从指定位置截取到结尾
2 public String substring(int beginIndex,int endIndex) 普通方法 截取部分字符串
package com.shxt.demo01;
public class StringDemo12 {
    public static void main(String[] args) {
        String str = "Hello World" ;
        System.out.println(str.substring(2));
        System.out.println(str.substring(2,8)); // [2,8)
    }
}

练习题

  • 已知一个文件名称为"西游记.悟空.docx"的字符串,请获取该文件的后缀名称 docx

(7) 字符串替换操作

编号 方法名称 类型 描述
1 public String replace(char oldChar,char newChar) 普通方法 字符替换,不常用
2 public String replaceAll(String regex,String s) 普通方法 全部替换
3 public String replaceFirst(String regex,String s) 普通方法 替换首个
package com.shxt.demo01;
public class StringDemo11 {
    public static void main(String[] args) {
        String str = "pangpang" ;
        System.out.println(str.replace('n','X'));
        System.out.println(str.replaceAll("an","*"));
        System.out.println(str.replaceFirst("an","#"));
    }
}
/**
运行结果
paXgpaXg
p*gp*g
p#gpang
*/

(8) 字符串拆分

编号 方法名称 类型 描述
1 public String[] split(String regx) 普通方法 按照指定的字符串全拆分
2 public String[] split(String regx,int limit) 普通方法 拆分为指定的长度
package com.shxt.demo01;
public class StringDemo13 {
    public static void main(String[] args) {
        String str = "Hello#World#!!!" ;
        String[] result = str.split("#");
        for (int i = 0; i < result.length; i++) {
            System.out.println(result[i]);
        }
    }
}

练习题:(进行拆分时也会出翔一些字符无法进行拆分,此时需要使用 \\(表示一个\) )进行转义

  • 拆分IP地址(192.168.7.199),输出结果为 192 168 7 199

(9) 其他方法

编号 方法名称 类型 描述
1 public boolean isEmpty() 普通方法 判断是否为空的字符串("")
无法进行null的判断
2 public int length() 普通方法 取得字符串长度
3 public String trim() 普通方法 去掉左右空格
4 public String toLowerCase() 普通方法 将全部字母转小写
5 public String toUpperCase() 普通方法 将全部字母转大写
6 public String concat(String s) 普通方法 字符串连接(+)
package com.shxt.demo01;
public class StringDemo14 {
    public static void main(String[] args) {
        String str = "Hello World" ;
        System.out.println(str.isEmpty());//false
        System.out.println("".isEmpty());//true
        System.out.println(str.length());//获取长度
        System.out.println("  HAHA   ".length());
        System.out.println("  HAHA   ".trim().length());//去空格的长度
        System.out.println(str.toLowerCase());
        System.out.println(str.toUpperCase());

        System.out.println(str.concat("HAHA").concat("WOWO"));
    }
}

练习题

  • 设置字符串的首字母大写 user_nameUser_name

(10) 字符串与基本数据类型互转

A.基本数据类型转字符串

String类中提供了String valueOf()放法,用作基本类型转换为字符串类型

static String valueOf(char data[])
static String valueOf(char data[], int offset, int count)
static String valueOf(boolean b)
static String valueOf(char c)
static String valueOf(int i)
static String valueOf(long l)
static String valueOf(float f)
static String valueOf(double d)
package com.shxt.demo01;
public class StringDemo15 {
    public static void main(String[] args) {
        int num = 100;

        String s1 = String.valueOf(num);
        String s2 = ""+100;
    }
}

B.字符串转基本数据类型

java.lang包中有Byte、Short、Integer、Float、Double类的调用方法:

public static byte parseByte(String s)
public static short parseShort(String s)
public static short parseInt(String s)
public static long parseLong(String s)
public static float parseFloat(String s)
public static double parseDouble(String s)
package com.shxt.demo01;
public class StringDemo16 {
    public static void main(String[] args) {
        String s = "999";

        int num1 = Integer.parseInt(s);
        long num2 = Long.parseLong(s);
        float num3 = Float.parseFloat(s);

        System.out.println(num1+"-"+num2+"-"+num3);
    }
}

StringBuffer和StringBuilder

我们来分析一下字符串的程序代码,看看这段代码为什么要在实际开发中尽量避免呢?

package com.shxt.demo02;

public class Demo01 {
    public static void main(String[] args) {
        String str = "";
        for (int i = 0; i < 10000; i++) {
            str += i;  //字符串拼接
        }
        System.out.println(str);
    }
}

代码分析:

我们说过String是不可变的,上面的代码需要"断开-连接"String对象10000次,会产生大量垃圾,所以不推荐这种方式,那么我们如何改进代码呢?

1.StringBuffer类

StringBuffer字符串变量(线程安全)是一个容器,最终会通过toString方法变成字符串;

public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, Appendable, CharSequence
{
    /**
     * Constructs a string buffer with no characters in it and an
     * initial capacity of 16 characters.
     */
    public StringBuffer() {
        super(16);
    }
    public synchronized StringBuffer append(int i) {
        super.append(i);
        return this;
    }
    public synchronized StringBuffer delete(int start, int end) {
        super.delete(start, end);
        return this;
    }
}

代码分析:

super(16)调用AbstractStringBuilder的抽象类的构造函数,对字符数组进行初识化操作

abstract class AbstractStringBuilder implements Appendable, CharSequence {

    char[] value;

    AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }
}

我们发现字符数组不是final修饰,意味着是可变的!

A.StringBuffer的内容是可以改变的,引用传递

package com.shxt.demo02;

public class Demo02 {
    public static void main(String[] args) {
        StringBuffer buf = new StringBuffer();      //定义StringBuffer对象
        buf.append("Han ").append(" Pang");         //连接字符串
        fun(buf);   //引用传递

        System.out.println(buf.toString());  //将buf转为字符串
    }

    public static void fun(StringBuffer temp){
        temp.append(" Welcome ").append("shxt");
    }
}
编号 方法名称 类型 描述
1 public StringBuffer append(数据类型 b) 普通方法 追加内容到当前StringBuffer对象的末尾,
类似于字符串的连接。
调用该方法以后,
StringBuffer对象的内容也发生改变
2 public StringBuffer deleteCharAt(int index) 普通方法 删除指定位置的字符,
然后将剩余的内容形成新的字符串
3 public StringBuffer insert(int offset, 数据类型 b) 普通方法 插入内容,然后形成新的字符串
4 public StringBuffer reverse() 普通方法 内容反转
5 public void setCharAt(int index, char ch) 普通方法 修改对象中索引值为index位置的字符为新的字符ch
6 public void trimToSize() 普通方法 将StringBuffer对象的中存储空间缩小到和
字符串长度一样的长度,减少空间的浪费
package com.shxt.demo02;

public class Demo03 {
    public static void main(String[] args) {
        StringBuffer buf = new StringBuffer("西游记");      //定义StringBuffer对象,并初始化数据
        buf.append(",悟空").append(999); //append追加内容
        System.out.println("结果1"+buf.toString());
        //删除数据
        buf = buf.deleteCharAt(buf.length()-1);
        buf = buf.deleteCharAt(buf.length()-1);
        buf = buf.deleteCharAt(buf.length()-1);
        System.out.println("删除后的结果:"+buf.toString());
        //插入数据
        buf.insert(3,"====>");
        System.out.println("插入后的结果:"+buf.toString());

        buf.replace(3,8,"");//替换数据
        System.out.println("替换后的结果:"+buf.toString());
        //反转数据
        buf.reverse();
        System.out.println("反转的数据为:"+buf.toString());
        
    }
}
/*
结果1西游记,悟空999
删除后的结果:西游记,悟空
插入后的结果:西游记====>,悟空
替换后的结果:西游记,悟空
反转的数据为:空悟,记游西
*/
StringBuffer sb=new StringBuffer();
sb.delete(0, sb.length());
sb.setLength(0);
StringBuffer通过使用sb.setLength(0)来清空StringBuffer对象中的内容效率最高

2.StringBuilder类

StringBuilder 字符串变量(非线程安全),使用方式跟StringBuffer一样


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

游戏编程算法与技巧

游戏编程算法与技巧

【美】Sanjay Madhav / 刘瀚阳 / 电子工业出版社 / 2016-10 / 89

《游戏编程算法与技巧》介绍了大量今天在游戏行业中用到的算法与技术。《游戏编程算法与技巧》是为广大熟悉面向对象编程以及基础数据结构的游戏开发者所设计的。作者采用了一种独立于平台框架的方法来展示开发,包括2D 和3D 图形学、物理、人工智能、摄像机等多个方面的技术。《游戏编程算法与技巧》中内容几乎兼容所有游戏,无论这些游戏采用何种风格、开发语言和框架。 《游戏编程算法与技巧》的每个概念都是用C#......一起来看看 《游戏编程算法与技巧》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

SHA 加密
SHA 加密

SHA 加密工具