java从基础知识(二)字符串处理

  字符串是程序开发中使用最为频繁,因此为了工作的高效和作为一名想进阶的程序员,了解并掌握字符串的处理显得尤为重要。java为我们提供了String、StringBuffer、StringBuilde三个处理字符串的类,下面我们对其做一个总结和介绍。

1、分别介绍

  1)String

  解答1:

  我们在查看API文档的时候,会发现有这么一句话“字符串是常量,它们的值在创建之后不能更改”。众所周知常量是用final修饰的,一旦创建在程序的其他地方无法修改。这时我们就会快速的回想,在我们日常的开发中String是可以随时随地可对其赋值的,难道是jdk的API文档写错了?其实不然,下面我们对其原理进行讲解。


public static void main(String arg[]){    String str1 = "a";    String str2 = str1;    String str4 = str2;    System.out.println(str1 == str2);//true,说明引用stt1和引用str2指向了同一地址    String str3 = "b";    str1 = str1 + str3;    System.out.println(str1 == str2);//false,说明引用str1所指向的地址已经改变    System.out.println(str2 == str4);//true    str2 = str2 + str3;    System.out.println(str2 == str4);//false,说明引用str2所指向的地址已经改变    System.out.println(str1 == str2);//false}

  因为String是引用类型,引用类型在内存中的存储如下图

  

  也就是说,当我们在对str1做改变的时候,只是改变了其在栈内存中存储的引用所指向的地址,与此同时java虚拟机会为其在堆内存中重新分配新的空间,而原来堆内存地址存储的值(因为是常量)并没有发生改变,会作为无用的引用被java回收站处理,到此相信可以顺利理解上述代码。

  解答2:

public class Test {

private final static String s1 = "abc";    private final static String s2 = "abc";

public static void main(String arg[]){        String str1="abc";        String str2="abc";        String str3="ab"+"c";        String str4=new String(str2);        System.out.println(str1 == str2);//true,说明str1、str2指向同一地址        System.out.println(str1 == str3);//true,说明str1、str3指向同一地址        System.out.println(str1 == str4);//false,说明str1、str4指向不同的地址        System.out.println(s1 == s2);//true,说明s1、s2指向同一地址        System.out.println(str1 == s1);//true,说明str1、s1指向同一地址    }

}

    上述现象是有常量在内存中的存储规则决定的,java代码在编译的阶段会在堆中分配出一块存储区域,作为常量池,用于存储常量值。当再有常量被申明时,编译器会去常量池中查找这个字符串是否存在,若存在则将这个字符串的引用直接指向字符串所在地址,否则为其在常量池中分配新的空间,也就是说所有值相同的常量的引用会指向同一个存储地址。至于str4是编译器为其new了新的存储空间,将其作为对象处理,而不是常量。

  下面给出常量的内存中的存储分配

  

  解答3:String的常用方法

  equals(Object anObject)和equalsIgnoreCase(String anotherString):equals是开发中使用非常频繁的方法,需要区分equals和“==”所比较的对象,equals比较的是两个对象(引用)的值是否相等,“==”比较的对象既可以是基本数据类型,也可以是引用类型,当比较对象为基本数据类型时就是值的比较,当比较对象是引用类型的时候比较的是引用(引用所指的地址),而不是引用所指向的值。后者是不考虑大小写的比较。

  contentEquals(CharSequence cs)、contentEquals(StringBuffer sb):字符串与指定的CharSequence/StringBuffer比较。

  compareTo(String anotherString) 和compareToIgnoreCase(String str) :按字典顺序比较两个字符串,后者忽略大小写。

      matches(String regex):当前字符串是否匹配给定的正则表达式。

      length():返回次字符串的长度

  isEmpty():当且仅当 length() 为 0 时返回 true

      split(String regex)、split(String regex, int limit) :据给定正则表达式拆分字符串

  substring(int beginIndex) 、substring(int beginIndex, int endIndex):按规则返回此字符串的子字符串

  replace(char oldChar, char newChar)、replace(CharSequence target, CharSequence replacement)、replaceAll(String regex, String replacement):替换

  valueOf(boolean b)等:返回基本数据类型的字符串表示形式

  valueOf(Object obj):返回Object的字符串形式

  toLowerCase()和toUpperCase():使用默认语言环境将此字符串中的所有字符转换为小写/大写

  toCharArray():将字符串转为字符数组

  contains(CharSequence s) :当且仅当字符串包含指定的char值序列时返回true。

  indexOf(int ch) 、indexOf(int ch, int fromIndex) 、indexOf(String str) 、indexOf(String str, int fromIndex) :按规则返回索引。

  lastIndexOf(int ch) 、lastIndexOf(int ch, int fromIndex)、lastIndexOf(String str)、lastIndexOf(String str, int fromIndex):按规则返回指定字符或字符串最后出现位置的索引。

  concat(String str):指定字符串连接到此字符串的结尾。(一般用+号解决了,所以用的很少)

  2)StringBuffer

    线程安全的可变字符序列。

  append(String str)等:将字符串追加到此字符串后面

  insert(int offset, String str)等:将字符串插入此字符序列中

  reverse():将此字符序列用其反转形式取代。这是一个非常有用的方法,可方便的将指定字符串逆序输出。

  toString():将StringBuffer串转换为String

  3)StringBuilde

    一个可变的字符序列,基本和StringBuffer相同,但是是非线程安全的,所以效率高于StringBuffer、Stringj。

2、String、StringBuilde、StringBuffer比较

  1、StringBuilde是非线程安全的,StringBuffer是线程安全的。

  2、效率上String<StringBuffer<StringBuilde

    原因在于String是字符串常量,另外两个是字符串变量,String在每次赋值时都需要new一个新的对象(上面有详细介绍),原有对象会被GC当垃圾回收,会大大降低执行效率。而StringBuffer与StringBuilder是字符串变量,改变发生在同一对象,少了创建、销毁对象环节。

  最后建议,如果操作少量数据则使用String,如果单线程下操作大量数据则用StringBuilder,如果是多线程下操作大量数据则用StringBuffer。

时间: 2024-10-25 21:18:56

java从基础知识(二)字符串处理的相关文章

Java SE 基础知识(二)

1. 类由两大部分构成:属性和方法.属性一般用名词来表示,方法一般用动词来表示. 2. 如果一个java源文件中定义了多个类,那么这些类中最多只能有一个类是public的,可以都不是public的. 3. 在Java中进行方法参数传递时,无论传递的是原生数据类型还是引用数据类型,参数传递方式统一是传值(pass by value),Java中没有传递引用(pass by reference)的概念. 4. 方法重载(Overload):表示两个或多个方法名字相同,但方法参数不同.方法参数不同有两

python基础知识(二)---字符串

ord('A'):ascii编码转化为对应的序号 chr(66):整数对应序号的ascii码 string.ascii_lowercase:生成所有的小写英文字母字符串 string.digits:生成所有的数字 string.count(str,beg=0,end=len(string):返回str在string里面出现的次数,如果beg或者end指定下标范围 string.expandtabs(tabsize=8):把字符串中的tab符号转化为空格 string.find(str,beg=0

【Java面向对象基础(二)】细说String、StringBuffer和StringBuilder

[喵"的Android之路][基础篇(二)][Java面向对象基础]细说String.StringBuffer和StringBuilder 1.String String是Java中的一个final类,主要用于字符串的处理. 1.1 不可变性 String内的字符串是不可变的,每一次修改都会重新生成一个新的String对象实例. 例: 1 // 在堆中会创建一个"Hello"字符串实例,把地址赋给对象a 2 String a = new String("Hello&

Java 接口基础知识

一.Java接口基础知识 1, Java语言不支持一个类有多个直接的父类(多继承),但可以实现(implements)多个接口,间接的实现了多继承. 2, 与Java接口相关的设计模式: 1, 定制服务模式 设计精粒度的接口,每个Java接口代表相关的一组服务,通过继承来创建复合接口 2, 适配器模式 当每个系统之间接口不匹配时,用适配器来转换接口 3, 默认适配器模式 为接口提供简单的默认实现 4, 代理模式 为Java接口的实现类创建代理类,使用者通过代理来获得实现类的服务 5, 标识类型模

Java Web基础知识之Filter:过滤一切你不想看到的事情

不要相信客户端, 所以做后端的人都应该铭记的事情.因为前端传过来的数据并不总是合法和有效的,所以后端是对访问资源的最后一道保护伞.之前我们在Spring中说到过AOP编程,AOP基础知识,它就可以在执行我们的方法之前进行一些预处理和验证来保护后端的资源.不难想到她的实现方式和本篇要说的过滤器的实现原理应该是相同的,都是通过Java的动态代理实现的(自己的理解). 在Java Web的开发中,过滤器用于拦截请求,并对ServletRequest对象进行处理,我们可以想到的,它可以用来验证权限.加密

黑马程序员——Java集合基础知识之Map

Map概念 要同时存储两个元素Key和Value,他们之间有映射关系,每个键不能重复,每个键只能映射到一个值. 当数据之间存在映射关系的时候,考虑使用Map集合. Map常用方法 如果添加的键原来有值,后添加的值会覆盖前面的值,并返回之前的值.put会返回来先添加的值,后添加的值会覆盖原有的值. Map tm =new TreeMap(); tm.put (key, value);//MAP没有add tm.remove (key) ;//去除一个key和对应的value,若不存在key返回nu

黑马程序员——Java集合基础知识之Collection

集合基础知识--Collection Java中集合框架由常用的Collection接口和Map接口组成,而Collection接口又有两个子接口,是List接口和Set接口,常用的集合框架由这三个类组成. List接口的功能方法 List的使用最为简单,创建集合,通过add方法添加元素,get方法获取元素,通过迭代器获取元素.List接口存放的数据无序的,添加速度快,但是查询速度慢,因为查询的时候必须遍历,每次都重头开始,效率较低.常用实现类有ArrayList,LinkedList. Lis

什么才是java的基础知识?

近日里,很多人邀请我回答各种j2ee开发的初级问题,我无一都强调java初学者要先扎实自己的基础知识,那什么才是java的基础知识?又怎么样才算掌握了java的基础知识呢?这个问题还真值得仔细思考. 我做j2ee开发已经超过十载,作为过来人,心路历程估计和大家差不多.编码的前几年,很长一段时间觉得java简单,开发实现各种功能都很轻松,代码写起来根本不费劲(主要是因为写的代码都是一些功能业务逻辑).但同时自己心里明白,自己其实没有什么水平,自己这3,4年以来学懂的东西就那么多,其他人几个月就可以

java多线程基础知识

1.ThrTest.java 继承Thread类方式 public class ThrTest extends Thread { private String name; public ThrTest() { } public ThrTest(String name) { this.name = name; } public void run() { for (int i = 0; i < 5; i++) { System.out.println(name + "运行 " + i

黑马程序员——java多线程基础知识1

多线程 进程是一个正在执行的程序. cpu在同时执行这些程序,其实是跳跃式的,做快速的切换,时间很短.一个进程可能存在多条路径.迅雷的多路径.每一个进行执行都有一个执行顺序,该顺序是一个执行路径,或这叫一个控制单元.每一个进程至少有一个线程,线程就是进程中的一个独立的控制单元,线程控制进程的执行.jvm启动的时候会有一个进程就叫做java,exe,该进程中至少有一个线程在控制Java程序的执行 ,而且该线程的执行代码在 主函数中.该线程称为主线程.虚拟机至少也有两个线程,一个主线程执行,另一个负