博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JavaSE| String常用方法
阅读量:5025 次
发布时间:2019-06-12

本文共 9393 字,大约阅读时间需要 31 分钟。

 字符串

* java.lang.String类型:字符串类型 * 1、String类型是final修饰,不能被继承的 * 2、Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。 *     简单的说,就是程序中的所有""构成的都是String的对象,只不过他们是字符串常量对象。 *  *  比较特殊的空字符串常量对象:"",它的长度为0 *      * 3、所有的 字符串都是常量;它们的值在创建之后不能更改。 * 简单理解就是String对象是不可变的,一旦修改(拼接、截取、替换...)一定会产生新的字符串对象。 *  * 4、因为 String 对象是不可变的,所以可以共享。 字符串常量对象是共享的,存在字符串的常量池中。 *  * 字符串常量池在JVM内存的哪个部分: * JDK1.6:方法区 * JDK1.7:堆中单独开辟一块空间用于存储字符串的常量 * JDK1.8:从堆中又挪出来,挪到了“元空间” *  * 5、字符串对象中如何存储字符串的内容 * 内部使用一个char[]数组来存储的 *  * "hello" -> {'h','e','l','l','o'} *  * 字符串对象不可变有很多原因:(1)value数组是final修饰的,无法创建新的value数组 *                       (2)String类型中没有提供修改value数组的元素的方法 */

String s3 = new String ( " hello " ) ;   //这里有两个对象,一个是"hello"字符串常量对象,在常量池;另一个是new的字符串对象,在堆里边。

字符串的比较:

  1 )  == 比较地址

  2 )  equals 比较字符串内容

String s1 = "hello";        String s2 = "atguigu";        String s3 = "helloatguigu";//常量池                String s4 = "hello" +"atguigu";//编译期间就可以确定的常量 拼接 结果还在常量池        String s5 = s1 + "atguigu";//编译期间s1是变量,只要变量参与了,结果就在堆        String s6 = s1 + s2;//编译期间s1是变量,只要变量参与了,结果就在堆                System.out.println(s3 == s4);//true        System.out.println(s3 == s5);//false ;如果s1、s2用final修饰,s5编译期间s1是常量,拼接 结果还在常量池,变为true;        System.out.println(s3 == s6);//false ;如果s1和s2用final修饰,s6//编译期间s1和s2都是常量,拼接 结果还在常量池,结果变为true。        String s4 = s1 + s2;         System.out.println(s3 == s4);//false        System.out.println(s3.equals(s4));//true        String s4 = (s1+ s2).intern();//把结果存到常量池里,这样s3 == s4就为true了。
String a = "abc", b = "abc";a == b  -->true  因为这里”abc”和”abc”是常量,是共享,在字符串的常量池中,是同一个对象a.equals(b) -->true

 

创建对象| 判断对象是否为空

String s1;//变量声明,但是未初始化,要先初始化才能使用。        String s2 = null;//变量声明并且初始化为null        //s1和s2是没有字符串的对象的        String s3 = "";//在常量池中创建字符串对象,是非空的字符串对象。        String s4 = new String();//在堆中创建字符串对象        String s0 = "Hello"; //存储在字符串的常量池中        String s11 = new String();        String s22 = new String("Hello"); //创建对象        System.out.println(s11.length()); //0判断是否为空的4种方法:     s3 != null && !s3.isEmpty()    s3 != null && s3.length()!=0    s3 != null && !s3.equals("")  //前面加s3!=null是为了避免s3.equals()空指针异常    !"".equals(s3)

 

字符串常用系列方法一

* 字符串的常用方法系列1: * (1)int length():返回字符串对象的长度,其实就内部value数组的长度; s.length( ); * (2)String toUpperCase():把当前字符串中的字符转成大写,返回一个新的字符串对象  s.toUpperCase() * (3)String toLowerCase():把当前字符串中的字符转成小写,返回一个新的字符串对象  s.toLowerCase() * (4)字符串比较:boolean equals()  严格区分大小写 *             boolean equalsIgnoreCase():不区分大小写 * (5)String trim():去掉前后空格     s.trim()     s.trim不能去掉全角空格,只能去掉半角空格     replaceAll替换为半角再trim
* (6)String concat():完全等价于 +  如 s1 + s2  <==>  s1.concat(s2) * (7)判断字符串是否为空 * !"".equals(字符串)  非空 * "".equals(字符串)  空字符串  ; 如 "".equals( "abc" ) 为false; “ ”,加了个空格就不是空的了。 *

 字符串与字符数组的转换

* 字符串的常用方法系列之二: *  * 字符串与字符数组之间的转换: * 1、把字符数组 -> 字符串 * String(char[] arr):用整个数组构建字符串 * String(char[] arr, int start, int count):取arr[start]开始的count个字符构造字符串 * char[] arr = {'h','e','l','l','o'};String str = new String(arr); //helloString str2 = new String(arr,2,2); //从下标为2的开始取,截取长度为2,即 llSystem.out.println(str2); * 2、把字符串转成字符数组: * char[] toCharArray()String strr = "Hello";char[] charArray = str.toCharArray(); * 思想: * String中用char[] value存 * toCharArray()复制了一个新数组,原因是保证字符串的不可变性 *  *  * 3、取第几个字符 * charAt(index)//input.next()返回的String类型的对象char gender = input.next().charAt(0);

 

 编码与解码

* String的常用方法系列三:   字符:给人看的;   字节:给机器识别  在开发中,输出到“文件”,在网络中传输,都要把“字符”->"字节" * 如果对方接收到数据,从"文件”中读取,显示给用户看,又得“字节”-“字符” *  * 编码:把字符-->字节 * 编码方式:GB2312,GBK,UTF-8,ISO8859-1 * 编码的方法: * byte[] getBytes():按照平台默认的字符编码 * byte[] getBytes(String charsetName) :按照指定的字符编码方式进行编码    byte[] bytes = str.getBytes();    byte[] bytes = str.getBytes("GBK");   ---->>>  System.out.println(Arrays.toString(bytes)); 调用字符串的toString方法。    byte[] bytes = str.getBytes("ISO8859-1");//无法表示中文 *  * 解码:把字节-->字符 * 解码的方法: * String(byte[] data):按照平台默认的字符编码 * String(byte[] data,String charsetName):按照指定的字符编码方式进行解码byte[] arr = {-55, -48, -71, -24, -71, -56}; //要解码成字符String string = new String(arr,"GBK"); System.out.println(new String(str.getBytes("ISO8859-1"),"ISO8859-1"));//?,不能表示中文,如果str表示中文,会乱码,中文有几个就编码几个。 System.out.println(new String(str.getBytes("UTF-8"),"UTF-8"));//以UTF-8编码,以UTF-8解码。 * GBK:一个汉字对应2个字节 * UTF-8:一般一个汉字对应3个字节 * ASCII码表中的字符是在任意字符集中都兼容的,这些个只占1个字节 乱码--->>>字符编码与解码不一致; 丢/多字节;

 

 字符串以..开头,以..结尾

* String的常用方法系列之四: *   判断字符串是否以xx开头,结尾 *  * boolean startsWith(xx)  如 str.startsWith("java"); 判断str字符串是否以java开头的 * boolean endsWith(xx)

 字符串的查找

* String的常用方法系列之五: * 在字符串中查找: * (1)boolean contains(str):是否包含                                 s1.contains(s2); * (2)int indexOf(str):如果存在就返回从左到右第一次出现的下标,否则返回-1   int index = str1.indexOf(str2); * (3)int lastIndexOf(str):如果存在就返回最后一次出现的下标,否则返回-1 */

 字符串的截取

* 字符串的常用方法系列六: * 字符串的截取 *  * substring( 起始下标 )         --->>   [ 起始下标,最后 ] * substring( 起始下标,结束下标 ) --->>  [ 起始下标,结束下标 ) */String fileName = "d:/atguigu/java1111/code/Hello.java";int start = fileName.lastIndexOf("/") + 1;int end = fileName.lastIndexOf(".");int index = fileName.lastIndexOf("/") +1;String name = fileName.substring(start, end); //String substring = fileName.substring(index); //截取从inex到最后一个的字符串,包含index  System.out.println(name);

 正则表达式

* 几个和正则相关的String方法:* 正则表达式的目的是为了按照某个格式要求去匹配字符串 *  * 1、boolean  matches(正则):判断当前字符串是否满足某种正则(规则) * 2、String replaceAll(正则,新值):把当前字符串中的复合这个“正则”部分替换为“新值” * 3、String replaceFirst(正则,新值):把当前字符串中的找到的第一个复合这个“正则”部分替换为“新值” * 4、String[] split(正则):按照要求进行拆分 *  *  * 和正则无关的替换方法: * (1)String replace(char oldChar, char newChar) :注意形参是char * (2)String replace(CharSequence target, CharSequence replacement) :形参是字符虚列,就是字符串 */

 

  //str中是否全是数字组成        boolean b = str.matches("\\d+");//原因,在Java \ 也是转义    //boolean b = str.matches("(\\p{Alpha})+"); // + 代表全部,str中是否全是“字母”组成                boolean b = str.matches("(\\p{Lower}|\\p{Upper})+"); //str中字母不区分大小写,包含数字会返回false        System.out.println(b);    String replace = str.replaceAll("\\d+", ""); //把str中的数字全部去掉    String replace = str.replaceFirst("\\d+", ""); //只去掉第一个    String str = "hello;world!java?string";        //按照标点符号拆开        String[] strings = str.split("\\p{Punct}");        for (String string : strings) {            System.out.println(string);        }    }    String str = "hello|world|java|string";        //按照|拆开        String[] strings = str.split("\\|");    String str = "hello.world.java.string";        //按照.拆开        String[] strings = str.split("\\.");    String str = "张三:89;李四:67;王五:90";                //先按照;拆开三个同学        String[] persons = str.split(";");        Student[] all = new Student[persons.length];        for (int i = 0; i < persons.length; i++) {            //在按照:拆开姓名和成绩            String[] split = persons[i].split(":");//                split[0]学生姓名//                split[1]学生成绩                all[i] =  new Student(split[0], Integer.parseInt(split[1]));        }                for (Student student : all) {            System.out.println(student);        }

 

可变字符序列StringBuilder和StringBuffer

* java.lang.String:对象不可变,一旦变就会有新对象 * 字符串的兄弟类:可变字符序列 * java.lang.StringBuffer:线程安全的可变字符序列。旧的。效率相对低。 * java.lang.StringBuilder:线程不安全的可变字符序列。新的JDK1.5。效率更高 *  * StringBuffer和StringBuilder的API是完全兼容,即方法签名一样,不一定的是一个适用于单线程,一个在适用于多线程。 *  * StringBuffer和StringBuilder对象的创建必须通过new,和String的可以直接等于"xxx"不同 *  * StringBuffer和StringBuilder的方法: * (1)append(xx):直接在value中修改,如果value长度不够了,会重写扩容为原来的2倍+2。默认的value长度为16 * (2)insert(int offset, xx):即在字符串缓冲区的[offset]开始插入xx。如果value长度不够,也会扩容。 * (3)delete(int start, int end):删除[start,end)  *    deleteCharAt(int index):删除指定位置的字符  * (4)reverse()  * (5)String toString() * .... *  * String中内部用final char[] value; * StringBuffer和StringBuilder的内部用:char[] toStringCache; *

 

public class TeatStringBuffer {    StringBuilder s = new StringBuilder(20);//如果指定了初始容量,就按指定的来        @Test    public void test1(){        StringBuilder s = new StringBuilder();//默认创建了一个长度为16的char[]数组        s.append("Hello").append("Worlld"); //直接修改的是s的字符串缓冲区对象        System.out.println(s);    }        @Test    public void test2(){        StringBuilder s = new StringBuilder("HelloBeiJing");//如果指定了初始容量,就按指定的来        s.deleteCharAt(0);        s.reverse();        System.out.println(s);                    }
View Code

 

String str = “I” + “love” + “java”;String str = new String();str = str.concat(“I”).concat(“love”).concat(“java”);StringBuffer s = new StringBuffer();s.append(“I”).append(“love”).append(“java”);
在单线程情况下,优先考虑StringBuilder,它效率高。只不过它在多线程情况下,线程不安全,可以使用StringBuffer,比String的拼接效率要高。String对象是不可变的,而StringBuffer和StringBuilder是可变的字符序列。

 

考点:

1)方法的参数传递机制

x.append(y)修改的是x的value,是可以变

y=x;修改的y的地址,这个时候这个y和实参b不是通一个对象了

2)方法的引用传递:

实参给形参的是地址值,如果通过形参修改属性,实参会受影响,但是如果修改形参的地址,和实参就无关了。

public class Exam4 {    public static void main(String[] args) {        StringBuffer a = new StringBuffer("A");        StringBuffer b = new StringBuffer("B");                operate(a, b);                System.out.println(a + "," + b);    }        public static void operate(StringBuffer x,StringBuffer y){        x.append(y);        y = x; //y=AB    }} ===>>AB,B

StringBuilder

内存是堆内存,但共享对象不是共享的,是独享对象---叫多例(多个对象多个实例);用StringBuilder,效率高;它是不会出现线程安全问题的;

public class TestString {    public static void main(String[] args) { //main方法也可以多线程同时访问; 但永远不会出现多线程安全问题        // StringBuilder, StringBuffer        StringBuilder stringBuilder = new StringBuilder(); //        for (int i = 0; i < 10000; i++){            stringBuilder.append(i);        }        System.out.println(stringBuilder);    }}
View Code

 

转载于:https://www.cnblogs.com/shengyang17/p/10063566.html

你可能感兴趣的文章
C# 温故而知新: 线程篇(四)
查看>>
.NET WebAPI生成Excel
查看>>
UI UISearchBar UISearchDisplayController实现搜索条、解析颜色
查看>>
Python流程控制
查看>>
C语言学习(2)-GTK布局
查看>>
vue全局配置组件
查看>>
营救公主(深度优先搜索算法)
查看>>
十五个Web知识的CTF出题套路
查看>>
Sorted Union
查看>>
select/poll/epoll 对比
查看>>
springboot中tomcat找不到jsp页面【转载】
查看>>
线段树 poj 1436
查看>>
telerik的RadCalendar控件学习
查看>>
POJ1258Agri-Net
查看>>
区域实现Android实现图片的裁剪(不调用系统功能)
查看>>
UVALive - 6039
查看>>
内容内核linux内核启动时R2的值来历
查看>>
UITextField弹出键盘挡住输入框问题
查看>>
地址栏显示图标 Shortcut Icon
查看>>
2018-2019 20165235《信息安全系统设计基础》第三周学习总结
查看>>