Java系列(33)——字符串

本系列博客汇总在这里:Java系列_汇总


一、字符串概述

  1. 字符串广泛应用 在 Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串。
  2. 示例
    package cn.tx;
    
    public class Demo
    {
    	public static void main(String[] args)
    	{	
    		String str = "abc";
    		System.out.println(str);		
    	}	
    }
    
    在这里插入图片描述
  3. 内存结构图
    在这里插入图片描述
    (1)说明:在定义 String str = “abc”;的时候,abc 是常量存储在数据共享区,定义是首先回到数据共享区中去查找是否存在 ”abc” 这样的字符串,如果存在,直接把 ”abc” 的地址赋值给 str,如果数据共享区中不存在 ”abc”,那么就去创建一个 ”abc”。
    (2)注意:字符串加上任何类型返回的都是字符串。

二、常量字符串的特点

  1. String 类代表字符串,java 程序中所有字符串字面值(如 “abc” )都作为此类的实例实现。字符串是常量;他们的值在创建之后不能更改。

  2. 示例

    package cn.tx;
    
    public class Demo
    {
    	public static void main(String[] args)
    	{	
    		String str = "abc";
    		str = str + "de";
    		//面试知识点(String str1 = new String();)与(str = str + "de";)区别是什么
    		System.out.println(str);//此str非彼str,见内存图		
    	}	
    }
    

    在这里插入图片描述

  3. 内存结构图
    在这里插入图片描述

三、字符串的构造器

  1. 部分构造器,更多详见 API。
    在这里插入图片描述
  2. 示例
    package cn.tx;
    
    public class Demo
    {
    	public static void main(String[] args)
    	{	
    		/**
    		 * String()
    		 */
    		// 创建一个空字符串的对象
    		String str = new String();
    		System.out.println("打印字符串str" + str + "----");
    		
    		/**
    		 * String(byte[] bytes)
    		 */
    		// 定义一个字节数组
    		byte[] bs = { 97, 98, 5, 4, 7 };
    		// 以字节数组作为参数的字符串对象的创建
    		String str1 = new String(bs);
    		// 把字节数组中的每一个数值转换成相应的ASCII码组装成字符创,找不到的就是方框(见输出)
    		System.out.println("以字节数组作为参数的字符串对象的创建:" + str1);
    		
    		/**
    		 * String(byte[] bytes, int offset, int length)
    		 */
    		// 字节数组 a b c d e f g
    		byte[] bs1 = { 97, 98, 99, 100, 101, 102, 103 };
    		// 第一个参数是字节数组,第二个参数是从指定索引开始,第三个参数是截取的长度(注意越界)
    		String str2 = new String(bs1, 3, 3);
    		System.out.println("以字节数组作为参数的字符串截取创建:" + str2);
    		
    		/**
    		 * String(char[] value)
    		 */
    		// 创建一个字符数组
    		char[] cs = { 'k', 'y', 'f', 'l', 'c', 'j' };
    		String str3 = new String(cs);
    		System.out.println("以字符数组作为参数创建字符串:" + str3);
    		
    		/**
    		 * String(char[] value, int offset, int count)
    		 */
    		String str4 = new String(cs, 3, 2);
    		System.out.println("以字节数组作为参数的字符串对象的创建:" + str4);
    		
    		/**
    		 * String(String original)
    		 */
    		// 以常量的字符串来作为参数
    		String str5 = new String("kyflcj");
    		System.out.println("以常量的字符串来作为参数:" + str5);
    	}
    }
    
    在这里插入图片描述

四、面试题

  1. 示例

    package cn.tx;
    
    public class Demo
    {
    	public static void main(String[] args)
    	{
    		// 创建常量的字符串
    		String str = "helloworld";
    		// 创建字符串的对象
    		String str1 = new String("helloworld");
    
    		// == 比较的是地址
    		System.out.println(str == str1);
    		// 字符串值的比较
    		System.out.println(str.equals(str1));
    
    		// 定义一个字符串的常量
    		String str2 = "魏宇轩";
    		String str3 = "魏宇轩";
    		// 地址是否相等
    		System.out.println(str2 == str3);
    		// 值是否相等
    		System.out.println(str2.equals(str3));
    
    		String str4 = "hello";
    		String str5 = "world";
    		String str6 = "helloworld";
    		// str4和str5拼接后一定会产生新的字符串(即使在数据共享区中存在拼接后值相等的字符串)
    		System.out.println(str6 == (str4 + str5));
    		// 如果是两个没有引用的常量做拼接,那么就会去数据共享区当中查找是否有相等的字符串,如果有相等的就不去创建字符串了,直接使用
    		// 常量相加不会产生新字符串,有变量参与相加一定会产生新字符串
    		System.out.println(str6 == "hello" + "world");
    	}
    }
    

    在这里插入图片描述

  2. 内存结构图
    在这里插入图片描述

  3. 区别介绍
    在这里插入图片描述
    上图中创建常量的字符串 “helloworld” 与创建字符串的对象 “helloworld”。前者是引用在数据共享区中 “helloworld” 的地址;后者虽然 new 了一个对象,实际上也是引用了数据共享区的 “helloworld”。String str = “helloworld”; 在数据共享区创建的是一个对象String str1 = new String(“helloworld”); 在堆中创建一个字符传串对象,然后再到数据共享区中创建一个字符串的常量的对象(在此过程当中,如果发现数据共享区当中已经存在 “helloworld”,则不再在数据共享区当中创建该对象),然后把堆中的对象指向数据共享区中的对象。
    在这里插入图片描述
    上图中首先是用 str2 作为引用,在数据共享区创建了对象 “helloworld”,当使用 str3 作为引用创建对象 “helloworld” 时,过程中发现数据共享区当中已经存在 “helloworld” 对象,则不再创建,则直接指向该地址。

五、字符串的判断

  • 示例
    package cn.tx;
    
    public class Demo
    {
    	public static void main(String[] args)
    	{
    
    		/**
    		 * endsWith(String suffix) 描述:测试此字符串是否以指定的后缀结尾。
    		 */
    		// 创建常量的字符串
    		String str = "helloworld";
    		// 判断字符串是否以ld结尾
    		System.out.println(str.endsWith("ld"));
    
    		/**
    		 * equals(Object anObject) 描述:将此字符串与指定对象进行比较。
    		 */
    		// 判断两个字符串是否相等,equals比较的是值
    		// 格式一:(不建议使用)
    		// 原因:如果前面定义为String str = null;那么str就是一个空指针,就会由于无法引用方法equals()而出现异常
    		System.out.println(str.equals("ld"));
    		// 格式二:(建议使用)
    		// 原因:不会发生空指针的异常
    		System.out.println("ld".equals(str));
    
    		/**
    		 * equalsIgnoreCase(String anotherString) 描述:不区分大小写的比较(验证码的校验)
    		 */
    		System.out.println("HELLOWORLD".equalsIgnoreCase(str));
    
    		/**
    		 * boolean contains(CharSequence s) 描述:判断是否包含某段连续的字符串
    		 */
    		System.out.println(str.contains("hello"));
    
    		/**
    		 * startsWith(String prefix) 描述:判断是否以某段连续的字符串开头
    		 */
    		System.out.println(str.startsWith("hello"));
    
    		/**
    		 * isEmpty() 描述:判断字符创是否是空串
    		 */
    		System.out.println(str.isEmpty());
    		System.out.println("".isEmpty());
    
    		/**
    		 * int length() 描述:获得此字符串的长度。
    		 */
    		// 空格是字符,空串不是字符,空串长度为0
    		System.out.println(str.length());
    	}
    }
    
    在这里插入图片描述

六、空指针异常的原理

  1. 示例

    package cn.tx;
    
    public class Demo
    {
    	public static void main(String[] args)
    	{
    		String str = null;
    		System.out.println(str.length());
    	}
    }
    

    在这里插入图片描述

  2. 内存结构图
    在这里插入图片描述
    由于 str 指向 null,那么相当于红色线条代表的直线是不存在的,也就不能使用“st.方法名”的方式去调用这个方法,那么就会产生空指针异常。

七、字符串的获取

  1. 部分方法,更多详见 API。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  2. 示例

    package cn.tx;
    
    public class Demo
    {
    	public static void main(String[] args)
    	{
    
    		// 创建常量的字符串
    		String str = "helloworld";
    
    		/**
    		 * charAt(int index) 描述:返回 char指定索引处的值。
    		 */
    		char c = str.charAt(5);
    		System.out.println(c);
    
    		/**
    		 * indexOf(int ch) 描述:返回指定字符第一次出现的字符串内的索引。
    		 */
    		int index = str.indexOf('l');// 注意:单引号
    		System.out.println(index);
    
    		/**
    		 * ndexOf(String str) 描述:返回指定子字符串第一次出现的字符串内的索引,如果返回-1说明不存在要查找的子字符串。
    		 */
    		int index1 = str.indexOf("w");// 注意:双引号
    		System.out.println(index1);
    
    		/**
    		 * lastIndexOf(String str) 描述:返回指定子字符串最后一次出现的字符串中的索引。
    		 */
    		// 查找字符最后一次出现的字符串中的索引(从后面开始查找)。
    		int index2 = str.lastIndexOf("l");
    		System.out.println(index2);
    
    		/**
    		 * indexOf(String str, int fromIndex) 描述:返回指定子串的第一次出现的字符串中的索引,从指定的索引开始。
    		 */
    		// 从索引5开始查找第一次出现的“l”,找不到返回-1
    		int index3 = str.indexOf("l", 5);
    		System.out.println(index3);
    
    		/**
    		 * lastIndexOf(String str, int fromIndex)
    		 * 描述:返回指定子字符串的最后一次出现的字符串中的索引,从指定索引开始向后搜索。
    		 */
    		// 在给定的索引前面倒叙查找第一次出现子字符串的索引
    		int index4 = str.lastIndexOf("l", 9);
    		System.out.println(index4);
    
    		/**
    		 * 其余lastIndexOf不再演示,详见API
    		 */
    
    		/**
    		 * substring(int beginIndex) 描述:返回一个字符串,该字符串是此字符串的子字符串。
    		 */
    		// 获得从指定索引(包括索引)开始往后的子字符串
    		String index5 = str.substring(4);
    		System.out.println(index5);
    
    		/**
    		 * substring(int beginIndex, int endIndex) 描述:返回一个字符串,该字符串是此字符串的子字符串。
    		 */
    		// 获得从指定开始索引(包括开始索引)到指定结束索引(不包括结束索引)的子字符串
    		String index6 = str.substring(4, 8);
    		System.out.println(index6);
    
    		/**
    		 * getBytes() 描述:使用平台的默认字符集将此 String编码为字节序列,将结果存储到新的字节数组中。
    		 */
    		// 获得字符串对应的字节数组
    		byte[] bs = str.getBytes();
    		for (int i = 0; i < bs.length; i++)
    		{
    			System.out.print(bs[i] + "\t");
    		}
    
    		/**
    		 * toCharArray() 描述:将此字符串转换为新的字符数组。
    		 */
    		System.out.println();
    		// 把字符串转换成字符数组
    		char[] cs = str.toCharArray();
    		for (int i = 0; i < cs.length; i++)
    		{
    
    			System.out.print(cs[i] + "\t");
    		}
    
    		/**
    		 * valueOf(boolean b) 描述:返回 boolean参数的字符串 boolean形式。
    		 */
    		System.out.println();
    		// 把Boolean类型转化成字符类型
    		String strBoolean = String.valueOf(true);
    		System.out.println(strBoolean);
    
    		char[] cc = { 'j', 'u', 'a', 'n' };
    		// String cArray = String.valueOf(new char [] {'j','u','a','n'});
    		System.out.println(cc);
    
    		/**
    		 * 其余valueOf不再演示,详见API
    		 */
    
    		/**
    		 * toUpperCase() 描述:将所有在此字符 String使用默认语言环境的规则大写。
    		 */
    		// 把字符串转换成大写
    		String str1 = "liuchengjuan";
    		System.out.println(str1.toUpperCase());
    
    		/**
    		 * toLowerCase() 描述:将所有在此字符 String使用默认语言环境的规则,以小写。
    		 */
    		// 把字符串转换成小写
    		String str2 = "KANGYANFENG";
    		System.out.println(str2.toLowerCase());
    
    		/**
    		 * concat(String str) 描述:将指定的字符串连接到该字符串的末尾。
    		 */
    		// 拼接字符串
    		System.out.println(str1.concat(str2));
    		System.out.println(str1 + str2);
    	}
    }
    

    在这里插入图片描述

  3. 计算一个字符串中大写字母和小写字母还有数字的数量

    package cn.tx;
    import java.util.Scanner;
    public class Demo
    {
    	public static void main(String[] args)
    	{
    
    		// 创建Scanner对象
    		Scanner sc = new Scanner(System.in);
    		// 获得我们输入的字符串
    		System.out.println("请输入一串字符:");
    		String str = sc.nextLine();
    
    		// 调用parseStr()的方法
    		// 方法一:
    		Demo Str = new Demo();
    		Str.parseStr(str);
    		// 方法二:
    		// new StringDemo7().parseStr(str);
    		// 方法三:将parseStr()变为静态方法后直接调用
    		// parseStr(str);
    	}
    
    	public static void parseStr(String str)
    	{
    		int upperCount = 0;
    		int lowerCount = 0;
    		int num = 0;
    		int els = 0;
    
    		int length = str.length();
    		for (int i = 0; i < length; i++)
    		{
    			// 获得每一个字符。如果使用int接收,就会自动转化为ASCII码(下面做相应修改)。
    			char c = str.charAt(i);
    			// int c = str.charAt(i);
    
    			if (c >= 'A' && c <= 'Z')
    			{
    				upperCount++;
    			} else if (c >= 'a' && c <= 'z')
    			{
    				lowerCount++;
    			} else if (c >= '0' && c <= '9')
    			{
    				num++;
    			} else
    			{
    				els++;
    			}
    		}
    		System.out.println("大写字母数量:" + upperCount);
    		System.out.println("小写字母数量:" + lowerCount);
    		System.out.println("数字数量:" + num);
    		System.out.println("其他字符:" + els);
    	}
    }
    

    在这里插入图片描述

  4. 从控制台输入一段字符串,然后把首字母变成大写,其余变成小写

    package cn.tx;
    
    import java.util.Scanner;
    
    public class Demo
    {
    	public static void main(String[] args)
    	{
    
    		callMethod();
    	}
    
    	// 递归调用,主函数不能通过程序来调用
    	public static void callMethod()
    	{
    
    		try
    		{
    			getResult();
    		} catch (Exception e)
    		{
    
    			System.out.println("输入不正确!");
    			callMethod();
    		}
    	}
    
    	public static void getResult()
    	{
    
    		Scanner sc = new Scanner(System.in);
    		System.out.println("请输入:");
    		// 获得输入的字符串
    		String line = sc.nextLine();
    
    		// 获得首字符,但是此过程中可能出现异常,如果出现异常,就向上抛出
    		char firstChar = line.charAt(0);
    		// System.out.println(firstChar);
    		// 转成字符串形式
    		String strFirstchar = String.valueOf(firstChar);
    		// 首字母转大写
    		String strFirstchar1 = strFirstchar.toUpperCase();
    
    		// 获得首字符以外的字符串
    		String elseChar = line.substring(1);
    		// System.out.println(elseChar);
    		// substring()返回的本身就是字符串形式,没必要转成字符串形式
    		// String strElseChar = String.valueOf(elseChar);
    		// 其余字母转小写
    		String strElseChar1 = elseChar.toLowerCase();
    
    		// 拼接
    		System.out.println(strFirstchar1.concat(strElseChar1));
    		// System.out.println(strFirstchar1+strElseChar1);
    	}
    }
    

    在这里插入图片描述

    package cn.tx;
    
    import java.util.Scanner;
    
    public class Demo
    {
    
    	public static void main(String[] args)
    	{
    
    		callMethod();
    	}
    
    	// 递归调用,主函数不能通过程序来调用
    	public static void callMethod()
    	{
    
    		try
    		{
    			getResult();
    		} catch (Exception e)
    		{
    
    			System.out.println("输入不正确!");
    			callMethod();
    		}
    	}
    
    	public static void getResult()
    	{
    
    		Scanner sc = new Scanner(System.in);
    		System.out.println("请输入:");
    		// 获得输入的字符串
    		String line = sc.nextLine();
    
    		// 多步同时进行(精简)
    		// String result =
    		// String.valueOf(line.charAt(0)).toUpperCase().concat(line.substring(1).toLowerCase());
    		// System.out.println(result);
    
    		// (极精简)采用substring(0,1)跳过将首字母转为字符串的过程,因为它返回的就是String类型
    		String result = line.substring(0, 1).toUpperCase().concat(line.substring(1).toLowerCase());
    		// String result = line.substring(0,1).toUpperCase() +
    		// line.substring(1).toLowerCase();
    		System.out.println(result);
    	}
    }
    

    在这里插入图片描述
    在这里插入图片描述

八、字符串的特殊功能

  1. 介绍部分方法,更多参见API。
    在这里插入图片描述

  2. 示例

    package cn.tx;
    
    public class Demo
    {
    
    	public static void main(String[] args)
    	{
    
    		String str = "liu-cheng-juan";
    
    		/**
    		 * split(String regex) 描述:将此字符串分割为给定的 regular expression的匹配。
    		 */
    		// 分隔字符串
    		// String str = "liu\\cheng\\juan";
    		// 注意:特殊字符需要添加转义字符“\\”。疑惑点:为什么用“\\”,不是“\”就表示转义(已解决,见笔记转义字符)
    		// String [] strs = str.split("\\\\");
    		String[] strs = str.split("-");
    		for (int i = 0; i < strs.length; i++)
    		{
    			String str1 = strs[i];
    			System.out.println(str1);
    		}
    		
    		/**
    		 * replace(char oldChar, char newChar) 描述: 返回从替换所有出现的导致一个字符串 oldChar在此字符串
    		 * newChar 。
    		 */
    		// 将原字符串中的单个字符替换成新的单个字符,第一个参数是被替换字符
    		String str2 = str.replace("-", "+");
    		System.out.println(str2);
    
    		/**
    		 * replace(CharSequence target, CharSequence replacement)
    		 * 描述:将与字面目标序列匹配的字符串的每个子字符串替换为指定的字面替换序列。
    		 */
    		// 字符串中的子字符串的替换,第一个参数是被替换字符串
    		String str3 = str.replace("liu", "kang");
    		System.out.println(str3);
    
    		/**
    		 * trim() 描述:返回一个字符串,其值为此字符串,并删除任何前导和尾随空格。
    		 */
    		// 去掉字符串两边的空格,中间的不能去掉
    		String Str = "   liu cheng juan   ";
    		String str4 = Str.trim();
    		System.out.println("-" + str4 + "-");
    	}
    }
    

    在这里插入图片描述

  3. 找出该字符串中 li 的数量 “iloliphfoileliwipiilorlloiyherliolipigf”

    package cn.tx;
    
    public class Demo
    {
    	public static void main(String[] args)
    	{
    		String str = "iloliphfoileliwipiilorlloiyherliolipigf";
    		int count = 0;
    		// 获得li在字符串当中第一次出现的索引(计数器的初始化)
    		// 返回的数组索引是第一次查到目标字符串的第一个字符的下标索引
    		int index = str.indexOf("li");
    		// System.out.println(index);
    		while (index != -1)
    		{
    			count++;
    			index = str.indexOf("li", index + 2);
    		}
    		System.out.println("li出现次数:" + count);
    	}
    }
    

    在这里插入图片描述

4、分割该的字符串 “2016104101:liuchengjuan:20:1|2016104102:kangyanfeng:20:2”

  • 定义一个方法,传入字符串格式为(idcard:name:age:gender)的分隔形式如:
    “2016104101:liuchengjuan:20:1|2016104102:kangyanfeng:20:2”,将该字符串分解,并将属性赋给定义的 Person 类的对象中并输出。提示:创建每个 Person 对象,每个对象有 idcard,name,age 和 gender 属性。
  • 示例
    package cn.tx;
    
    public class Demo
    {
    	public static void main(String[] args)
    	{
    		// 定义源字符
    		String str = "2016104101:liuchengjuan:20:1|2016104102:kangyanfeng:20:2";
    		Person[] ps = getPersons(str);
    		// 打印数组
    		printArr(ps);
    	}
    
    	public static Person[] getPersons(String str)
    	{
    		Person[] ps = null;
    		// 判断输入的字符串不是空
    		if (str != null && !"".equals(str))
    		{
    			// 根据字符串来做分隔
    			String[] pstrs = str.split("\\|");
    			ps = new Person[pstrs.length];
    			// 遍历字符串的数组
    			for (int i = 0; i < pstrs.length; i++)
    			{
    				// 获得每一个Person的字符串数据
    				String personStr = pstrs[i];
    				// 把子字符串按冒号进行拆分
    				String[] personAttr = personStr.split(":");
    				// 创建person对象
    				Person p = new Person();
    				// 给学号赋值
    				p.setIdcard(personAttr[0]);
    				// 给姓名赋值
    				p.setName(personAttr[1]);
    				// 给年龄赋值
    				p.setAge(personAttr[2]);
    				// 给性别赋值
    				p.setGender(personAttr[3]);
    				ps[i] = p;
    			}
    		}
    		return ps;
    	}
    
    	public static void printArr(Person[] ps)
    	{
    		for (int i = 0; i < ps.length; i++)
    		{
    			System.out.println(ps[i]);
    		}
    	}
    }
    
    package cn.tx;
    
    public class Person
    {
    	private String idcard;
    	private String name;
    	private String age;
    	private String gender;
    
    	public String getIdcard()
    	{
    		return idcard;
    	}
    
    	public void setIdcard(String idcard)
    	{
    		this.idcard = idcard;
    	}
    
    	public String getName()
    	{
    		return name;
    	}
    
    	public void setName(String name)
    	{
    		this.name = name;
    	}
    
    	public String getAge()
    	{
    		return age;
    	}
    
    	public void setAge(String age)
    	{
    		this.age = age;
    	}
    
    	public String getGender()
    	{
    		return gender;
    	}
    
    	public void setGender(String gender)
    	{
    		this.gender = gender;
    	}
    
    	@Override
    	public String toString()
    	{
    		return "Person [idcard=" + idcard + ", name=" + name + ", age=" + age + ", gender=" + gender + "]";
    	}
    }
    
    在这里插入图片描述

如有错误,欢迎指正!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值