精华内容
下载资源
问答
  • 问题描述:// 把字符串"192.168.1.1"按照小圆点进行分割分割成"192","168","1","1"四个字符串。String preStr = "192.168.1.1";String[] string = preStr.split("."); // 错误写法。这种写法得到的字符串组长度...

    问题描述:

    // 把字符串"192.168.1.1"按照小圆点进行分割,分割成"192","168","1","1"四个字符串。

    String preStr = "192.168.1.1";

    String[] string = preStr.split("."); // 错误写法。这种写法得到的字符串组长度为0

    String[] string = preStr.split("\\."); //正确写法。对小圆点进行转义

    出现上述情况的原因是:split函数会将参数看作是正则表达式进行处理。"."在正则表达式中表示匹配任意一个字符,经过转义之后,"."才是本身的含义,才能得到正确的分割结果。下面主要探讨上述错误写法中得到的字符串组为什么大小为0。

    下面是split函数源代码(java.util.regex.Pattern.split)

    public String[] split(CharSequence input, int limit) {

    int index = 0;

    boolean matchLimited = limit > 0; // 是否限制匹配个数

    ArrayList matchList = new ArrayList(); // 匹配结果队列

    Matcher m = matcher(input); // 待切割字符(串)匹配对象

    // Add segments before each match found

    while (m.find()) {

    // 如果不限制匹配个数 或者 当前结果列表的大小小于limit-1

    if (!matchLimited || matchList.size() < limit - 1) {

    String match = input.subSequence(index, m.start()).toString(); // 取子串,(分隔串所在的首位)

    matchList.add(match); // 添加进结果集

    index = m.end(); // 获取下一个子串的首字符下标

    } else if (matchList.size() == limit - 1) { // last one,即还剩最后一个名额了

    // 最后一个元素从指针取到字符串结尾

    String match = input.subSequence(index, input.length()).toString();

    matchList.add(match);

    index = m.end();

    }

    }

    // If no match was found, return this

    if (index == 0) // 即没有切分到的意思吧,返回整一串

    return new String[] { input.toString() };

    // 如果不限制匹配个数 或者结果集大小小于限制个数

    if (!matchLimited || matchList.size() < limit)

    // 最后一个元素从指针取到字符串结尾

    matchList.add(input.subSequence(index, input.length()).toString()); // Construct

    // result

    int resultSize = matchList.size();

    if (limit == 0)

    // 如果结果集最后的元素是"",一个一个地删除它们

    while (resultSize > 0 && matchList.get(resultSize - 1).equals(""))

    resultSize--;

    String[] result = new String[resultSize];

    return matchList.subList(0, resultSize).toArray(result);

    }

    代码中注释转自https://www.cnblogs.com/xzhang/p/3995464.html

    正则表达式中“.”表示匹配任意一个字符。对于split函数而言,就是就是以任意字符为分隔符进行分割,那么“192.168.1.1”按照任意字符分割等价于“ccccccccccc”按照“c”进行分割,那么分割结果肯定都是空串。split函数中最后的while循环会将分割之后的字符串组,从后往前清理空字符串,所以“.”在不转义的情况下,分割字符串得到的结果为空。

    代码中,Matcher m = matcher(input)中,m记录下每个分隔符的位置。例如“abc;efg;hig”中,分隔符“;”的位置是3,7。m.start()可以获取到第一个分隔符的索引3,利用函数subSequence(int start, int end)进行分割,所以第一个子串传入参数[start = 0,end = 3],m.end()获取当前匹配到的分隔符之后的位置4;m.find()寻找下一个分隔符位置,m.start()为7,第二个字串[start = 4,end = 7];以此类推。

    对于字符串“192.168.1.1”按照“.”进行分割时,分隔符的位置为0,1,2,3,4,...,10,11,每个子串是[0,0],[1,1][2,2],...,[10,10],[11,11]。对于函数subSequence(int start, int end),end==start时返回空串。所以最后得到的结果也是空串。

    以上是一些简单分析,有不对的地方请大家多指教。

    下面附上相关的函数说明,便于大家理解:

    m.start() //Returns the start index of the previous match.

    m.end()   //Returns the offset after the last character matched.

    m.find()  //Attempts to find the next subsequence of the input sequence that matches the pattern

    展开全文
  • 本章对Java如何实现字符串分割,是基于jDK1.8版本中的String.split()方法。 本文篇幅较长,内容较为复杂涉及到许多小细节,都是我在使用时候以及查阅资料时候遇到的坑,建议反复观看!! 内容中含有源码的解读,...

    Java如何实现字符串的分割

    前言

    本章对Java如何实现字符串的分割,是基于jDK1.8版本中的String.split()方法。

    本文篇幅较长,内容较为复杂涉及到许多小细节,都是我在使用时候以及查阅资料时候遇到的坑,建议反复观看!!

    内容中含有对源码的解读,如果可以建议详细读懂源码,有助于对split的理解使用。

    最后,长文警告,可按需观看!!

    一、JDK-1.8-API文档说明(推荐阅读)

    首先对java-JDK-1.8的文档进行解读,以下是我从文档中截取的两张图片,分别是关于split单参数方法与split双参数方法,如下图:

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

    对以上内容提炼重点:
    • 该方法是将字符串分割的方法,通过给定的String regex作为分割符分割。分割后生成一个字符串数组,该数组中子字符串的排序为他们在原字符串中的顺序。
      如果没有找到对应的分隔符(regex)则返回一个长度为1的字符串数组,仅存放原字符串

    • 对于单个参数的方法有:该方法是调用了限制参数(limit)为0的双参数split方法

    • 对于双参数的方法有:limit是控制模式应用的次数因此限定了输出字符串数组的长度,并给出三种分类:

      • 1)limit>0:模式最多应用n-1次,数组的长度不大于n,数组的最后一个条目将包含超出匹配分隔符的所有输入
      • 2)limit<0:模式将被应用到尽可能多的次数,且数组可以有任何长度
      • 3)limit=0:模式将被应用到尽可能多的次数,且数组可以有任何长度,并且尾随的空字符串将被丢弃

    二、简单的使用

    了解完jdk文档提供的基础使用方法,接下来进行以下简单的一个对于split方法的入门使用,首先是对于单个字符作为分隔符的使用以及对于使用正则表达式分割

    1、单个字符分隔

    /**
      * 输出分隔后的字符数组
      * 为了可以明显的看出空字符串的输出,如遇空字符串则输出为——“空字符串”
      * @param split
      */
        private void printSplit(String[] split) {
            for (String temp : split) {
                //空字符串的话输出--“空字符串”
                if (temp.equals("")) {
                    System.out.println("空字符串");
                } else {
                    System.out.println(temp);
                }
            }
        }
    
    	/**
         * 基础使用1:单个字符-:
         */
        @Test
        public void Test1() {
            string = "boo:and:foo";
            String[] split = string.split(":");
            printSplit(split);
        }
    
        /**
         * 基础使用1:单个字符-o
         */
        @Test
        public void Test2() {
            string = "boo:and:foo";
            String[] split = string.split("o");
            printSplit(split);
        }
    
    
    Test1运行结果:

    在这里插入图片描述

    Test2运行结果:

    在这里插入图片描述

    通过单个字符的分割可以看出,基本使用还是比较简单的,但是在第二个分割字符“o”时产生了一定的问题,就是分割到重复的字符“o”会在中间出现一个空字符串,以及尾部的空字符串居然并没有被分割进去

    2、正则表达式

    /**
      * 基础使用2:正则表达式-1
      */
        @Test
        public void Test3() {
            string = "asd-sdf+sda+sda";
    		//匹配-或者+
            String[] split = string.split("[-\\+]");
            printSplit(split);
        }
    
    /**
      * 基础使用2:正则表达式-2
      */
        @Test
        public void Test4() {
            string = "boo1:a2nd:fo3o";
    		//匹配正整数
            String[] split = string.split("[0-9]*[1-9][0-9]*");
            printSplit(split);
        }
    
    Test3运行结果:

    在这里插入图片描述

    Test4运行结果:

    在这里插入图片描述

    对于正则表达式的分割成功了,证明split中参数String regex是可以支持输入正则表达式进行分割

    三、Java源码分析

    以下源码比较绕,建议是跟着下面的测试代码一边调试一边理解(ps:源码英文已转译)。

    比较难的说明文字后面都有以下都会有一小部分的总结,如果实在看不懂看总结也可以~

    /**
    * 单个参数的方法其实就是调用了双参数的方法,第二个参数limit为0
    */
    public String[] split(String regex) {
    	return split(regex, 0);
    }
    
    public String[] split(String regex, int limit) {
        
        /*英文转译:
        如果正则表达式是
        (1)一个字符的字符串,并且这个字符不是
        正则表达式的元字符".$|()[{^?* + \ \”,或
        (2)两个字符的字符串,第一个字符是反斜杠和
        第二个不是ascii数字或ascii字母。*/
        
        //下面有对于if判断的拆解,因为篇幅占位大,放到本段代码末尾,建议先看   
        char ch = 0;
        if (((regex.value.length == 1 &&
              ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||
             (regex.length() == 2 &&
              regex.charAt(0) == '\\' &&
              (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&
              ((ch-'a')|('z'-ch)) < 0 &&
              ((ch-'A')|('Z'-ch)) < 0)) &&
            (ch < Character.MIN_HIGH_SURROGATE ||
             ch > Character.MAX_LOW_SURROGATE))
         //以上这一大片都是if判断条件↑
        {
            //定义上一个字符串分割结束的位置,起始为0
            int off = 0;
       		//定义下一个分隔符在待分割字符串中的位置,,起始为0
            int next = 0;
            //boolean值,如果limit大于0为true ,小于等于0皆为false
            boolean limited = limit > 0;
            //定义分割后的字符串数组,因为String[]长度固定,不便于使用
            ArrayList<String> list = new ArrayList<>();
            
          /**
            * while判断语句中做了两件事:
            *	1)使用indexof查询off以后下一个ch的位置,并赋值给next
            *	2)如果后续再找不到ch则退出循环
            *
            *if语句中也不简单,首先看【 !limited 】
            *上面limited赋值中可知,如果limit大于0,则【!limited】恒为false
            *					如果limit不大于于0,则【!limited】恒为true
            *翻译为“人话”就是:
            *   如果limit大于0则后续条件才需要判断,否则if条件一直都是true
            *   进一步推论,如果limit不大于0,则else里面的语句块肯定不会执行
            *
            *其次看看第二个条件,【list.size() < limit - 1】:list的长度小于limit-1
            *我们可以做出两种假设:
            *	1)limit无限大,则这第二个条件一定恒为true
            *	2)limit很小,那么只有这种情况才会出现list长度会小于limit的情况,也就是false
            *	那么limit的分界线在哪呢?也就是limit的取值如何才会出现有false的情况
            *	决定性因素肯定就是 原字符串分割出多少子字符串:
            *	若limit是大于能分割出的子字符串,表达式一定为true
            *	若limit是小于能分割出的子字符串个数,那表达式【list.size()=limit-1】则为false,并且进入else语句块。
            *
            *将两个条件整合到一起:也就是只有当limit>0并且小于能分割出子字符串个数时
            *if才会出现false的情况,并且这时【list.size()=limit-1】,进入else语句块
            *
            *if{...}else{...}里面的语句块就比较简单了
            *	通过substring进行分割字符串,并放入list中
            *	然后将off往后移动
            *	else内的语句块也是一样的,不过添加的是最后一个子字符串
            */
            while ((next = indexOf(ch, off)) != -1) {
                if (!limited || list.size() < limit - 1) {
                    list.add(substring(off, next));
                    off = next + 1;
                } else {    // last one
                    //assert (list.size() == limit - 1);
                    list.add(substring(off, value.length));
                    off = value.length;
                    break;
                }
            }
            // If no match was found, return this
            //如果没有找到匹配项,则返回this
            //off如果为0,那么就证明上述那个循环中并未找到匹配项
            if (off == 0)
                return new String[]{this};
    
            // Add remaining segment
            //添加剩余的部分
            //同上,当limit不大于0的时候恒为true
            //只有limit>0而且list长度大于等于limit才为false
            //因为上面循环中list.size()=limit-1,进入else语句块,语句块中会再给list加入一个元素
            
            //可知,这个if判断与上面else语句块两个互补,两个不会同时运行到
            //这个与else语句块作用一致,都是将最后一个子字符串添加入list
            if (!limited || list.size() < limit)
                list.add(substring(off, value.length));
    
            // Construct result
            //构建结果
            
            //如果limit为0,进行特殊处理
            //首先字符串数组长度大于0并且获取最后一个字符数组的字符串长度为0
            //简而言之,前提条件字符数组长度得大于0(小于0还分割个啥)
            //其次寻找最后一个是否是空字符串,如果是,将长度减一,如果不是则退出循环
            int resultSize = list.size();
            if (limit == 0) {
                while (resultSize > 0 && list.get(resultSize - 1).length() == 0) {
                    resultSize--;
                }
            }
            
            //定义字符数组,将list转为String[]
            //因为后面空字符长度被去掉了,于是空字符被省略了
            String[] result = new String[resultSize];
            return list.subList(0, resultSize).toArray(result);
        }
        //如果不符合if的条件就进入这个方法
        return Pattern.compile(regex).split(this, limit);
    }
    
    
    //if条件的拆分
     /*如果正则表达式是
        (1)一个字符的字符串,并且这个字符不是
        正则表达式的元字符".$|()[{^?* + \ \”,或
        (2)两个字符的字符串,第一个字符是反斜杠和
        第二个不是ascii数字或ascii字母。*/
    (
        (
            (
                regex.value.length == 1
                &&
                ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1
                //小细节,这里将ch赋值了,也就是将改字符赋值给了ch
            )
            ||
            (
                regex.length() == 2 
                &&
                regex.charAt(0) == '\\'
                &&
                (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0
                //小细节*2
                &&
                ((ch-'a')|('z'-ch)) < 0
                &&
                ((ch-'A')|('Z'-ch)) < 0
            )
        )
        &&
        (ch < Character.MIN_HIGH_SURROGATE ||ch > Character.MAX_LOW_SURROGATE)
    )
    
    1、源代码的测试代码

    建议进入调试模式配合上面代码同步运行,有利于对代码的解读

        /**
         * 读源码:测试1,单个非特殊字符
         * 结果为并未调用Pattern.compile
         * if判断条件结果为true
         */
        @Test
        public void Test5() {
            string = "boo:and:foo";
            String[] split = string.split(":");
            printSplit(split);
        }
    
        /**
         * 读源码:测试1,两个字符,并且第一个字符为\第二个字符不为数字或者单词
         * 结果为并未调用Pattern.compile
         * if判断条件结果为true
         * 这里需要注意,虽然regex是为\\$但是其实在Java解读中第一个为转义字符
         * 所以传到方法中其实代码解读为\$
         * 你们可以在调试的时候看一下这个入参的值便能发现
         */
        @Test
        public void Test6() {
            string = "boo$and$foo";
            String[] split = string.split("\\$");
            printSplit(split);
        }
    
        /**
         * 读源码:测试3,三个字符
         * if判断条件结果为false
         * 结果为调用了Pattern.compile
         */
        @Test
        public void Test7() {
            string = "boo:and:foo";
            String[] split = string.split("and");
            printSplit(split);
        }
    
    2、源代码运行原理图示

    下图为以":"作为分隔符的运行图示

    在这里插入图片描述

    3、解读完代码后的总结(推荐阅读)
    1. if可以进入的条件为单个字符并且不为正则表达式元字符,或者双字符,第一个为反斜杠并且第二个字符不为数字与字母,如此一来,其实第二个条件就是允许输入正则表达式元字符,其实整个if条件就是如果是单个字符就可以允许输入,但是为了遵循正则表达式的规则才设置了两个字符的条件。

    结论:String.split()这个方法对于单个字符(包括特殊字符,但是需要转义)是自己进行分割的,但是如果是**多个字符,这个方法就会去调用Pattern.compile(regex).split(this, limit);**这个方法

    如果需要多次使用split方法并且都是多个字符作为分隔符,直接使用Pattern.compile(regex).split(this, limit);或许会带来更高的效率

    1. 内部采用substring()进行字符串的分割,然后传入list集合内部,于是如果待分割字符串中分隔符连续出现就会出现分割出空字符串,详情可见上面使用“o”进行分割出现了一个空字符串,会出现substring(n,n) 这种情况结果为空字符串

    2. 如果使用limit =0 的双参数方法,区别于limit <0,split会在生成结果前检查后端的空字符串并将其去掉,这就是为什么limit = 0的时候后面的空字符串会被丢弃

    四、limit参数使用区别

    1、limit=0

    那么模式将被应用尽可能多的次数,数组可以是任何长度,并且结尾空字符串将被丢弃。

    就是会首先运行出全部分割出的子字符串然后再将后面结尾的空格去掉

        /**
         * limit参数区别:=0
         * 输出全部结果,去除结果后面全部空字符数组
         */
        @Test
        public void Test8() {
            string = "boo:and:foo:::";
            String[] split = string.split(":", 0);
            printSplit(split);
        }
    
    Test8运行结果:

    在这里插入图片描述

    2、limit<0

    模式将被应用尽可能多的次数,而且数组可以是任何长度。

    分割出全部子字符串包含有全部分割结果

        /**
         * limit参数区别:<0
         * 输出全部结果
         */
        @Test
        public void Test9() {
            string = "boo:and:foo:::";
            String[] split = string.split(":", -1);
            printSplit(split);
        }
    
    Test9运行结果:

    在这里插入图片描述

    3、limit>0

    模式将被最多应用 n - 1 次,数组的长度将不会大于 n,而且数组的最后一项将包含所有超出最后匹配的定界符的输入。

    分割出的字符串长度只会小于等于limit,当limit小于能分割出的子字符串数量时,这个时候数组长度等于limit

    如果limit大于能分割出的子字符串数量时,数组长度等于子字符串数量,小于limit

        /**
         * limit参数区别:>0 --小于分割出的字符数组长度
         */
        @Test
        public void Test10() {
            string = "boo:and:foo";
            String[] split = string.split(":", 2);
            printSplit(split);
        }
    
        /**
         * limit参数区别:>0 --大于分割出的字符数组长度
         */
        @Test
        public void Test11() {
            string = "boo:and:foo";
            String[] split = string.split(":", 5);
            printSplit(split);
        }
    
    Test10运行结果:

    在这里插入图片描述

    Test11运行结果:

    在这里插入图片描述

    五、易错点(推荐阅读)

    1、分割到第一个字符

    当第一个字符被分割到,则字符数组首个字符串为空

    原因分析:在源码中可以看出,源码使用indexof进行查找下一个分隔符的位置,当找到分隔符为第一个的时候就会将next赋值为0,然后使用substring分割,于是两个参数就变成了subtring(0,0)必然分割出一个空字符串出来

    如果开头的这个空字符串并非想要的理想输出,只能自己手动去除

        /**
         * 易错点:分割到第一个字符
         */
        @Test
        public void Test12() {
            string = "boo$and$foo";
            String[] split = string.split("b", 0);
            printSplit(split);
        }
    
    Test12运行结果:

    在这里插入图片描述

    2、转义字符\

    java中使用\必须再次进行一次转义,例如用“\\”代表“\”,并且正则表达式元字符都必须转义才能作为分隔符

    原因分析:split这个方法其实可以看出还是推荐我们使用正则表达式进行分割的,在写String regex这个参数我建议还是看着正则表达式的书写方法进行书写的

    源码中明确给出说明,正则表达式元字符前面都需要使用\转义——.$|()[{^?*+\

    在这里插入图片描述

    其次,java中\的使用也必须进行转义,在Java中双反斜杠表示一个反斜杠,书写中应该特别注意

    推荐书写方法:先找个正则表达式验证的网站验证正则表达式的书写,然后复制进去java代码中,需要注意的是,在java 1.7之后将带有\的字符串粘贴到双引号中会自动再添加一个\

        /**
         * 易错点:转义字符\
         */
        @Test
        public void Test13() {
            //因为java代码不能直接输入一个反斜杠,必须进行转义,这里的\\表达为\
            string = "boo\\and\\foo";
            //这里\\\\应该拆开看成为\\ \\,前面两个代表一个\后面两个代表一个\
            //实际\\\\表达的含义应该为\\,对应正则表达式的语法\\表达为\
            //所以在Java代码中\\\\在最终处理时候其实表达为\
            String[] split = string.split("\\\\", 0);
            printSplit(split);
        }
    
        /**
         * 易错点:转义字符\
         */
        @Test
        public void Test14() {
            string = "boo+and-foo*boo";
            //这里的+-*都是正则表达式的元字符,都需要使用\转义,然后在Java中再对\转义
            //原正则表达式[\+\-\*]
            String[] split = string.split("[\\+\\-\\*]", 0);
            printSplit(split);
        }
    
    Test13运行结果:

    在这里插入图片描述

    Test14运行结果:

    在这里插入图片描述

    3、正则表达式修饰符不可用

    基于运行测试发现正则表达式的修饰符在split中使用是无效的,使用的时候注意避开

    在这里插入图片描述

        /**
         * 易错点:正则表达式修饰符不可用
         * 理想输出[(boo:),(nd:foo)]
         */
        @Test
        public void Test15() {
            string = "boo:and:foo";
            String[] split = string.split("/[a]/g", 0);
            printSplit(split);
        }
    
    Test15运行结果:

    在这里插入图片描述

    展开全文
  • Java字符串解析

    2021-02-28 18:09:48
    1、字符串不属于基本数据类型(基本数据类型有【byte,int,char,float,double,boolean,short,long】),字符串由单个或多个字符组成,本质上是字符数组,Java中提供两种实现字符串的类,分别是String、StringBuffer类。...

    1、字符串不属于基本数据类型(基本数据类型有【byte,int,char,float,double,boolean,short,long】),字符串由单个或多个字符组成,本质上是字符数组,Java中提供两种实现字符串的类,分别是String、StringBuffer类。

    String类

    字符串的声明:

    1、常量声明方式

    String sName="Bob";

    2、对象声明方式

    String sName=new String("Bob");

    3、由字符数组初始化

    String sName=new String(char[] ch);

    4、由字符数组指定元素个数

    String sName=new String(char[] ch,int index,int length);

    4、指定字符数组的起始位置

    String sName=new String(char[] ch,int begin,int end);

    测试用例:

    public static void main(String []args)

    {

    //常量声明方式

    String sName="Bob";

    System.out.println(sName);//输出Bob

    // 对象声明

    String sName1=new String("Bob");

    System.out.println(sName); //输出Bob

    // 由字符数组声明

    char [] ch=new char []{'a','b','c','d'};

    String sNum=new String(ch);

    System.out.println(sNum); //输出abcd

    // 指定字符数据的起位置和长度,

    String sNum1=new String(ch,1,2);

    System.out.println(sNum1); //输出bc

    // 指定起始位置

    String sNum2=new String(ch,1,3);

    System.out.println(sNum2); //输出bcd

    System.out.println("数组的长度:" + ch.length); //输出4

    int iLen=sNum.length();

    System.out.println("对应字符串长度:" + iLen); //输出4

    }字符串的操作:

    1、字符串的比较

    对于字符串的比较采用如下方法:

    (1)equals():比较两个字符串的内容是否相同,返回值为Boolean类型;

    (2)equalsIgnoreCase:忽略大小写,比较两个字符串的内容是否相同,返回值为Boolean类型。

    (3)compareTo(String anotherString):按照字典表的顺序比较,返回值为int类型。

    注意:在比较字符串的时候,不要使用"=="进行比较,因为"=="比较的是对象,判断两个对象是否为同一个对象,如果内容相同而不是同一个对象,返回的是false,对应的不是同一个内存地址。

    实例:

    public static void main(String []args)

    {

    String sUpper="WELCOME TO CHINA";

    String sLow="Welcome to china";

    String sSame="WELCOME TO CHINA";

    String sLow1="xelcome to china";

    if(sUpper.equals(sSame)){

    System.out.println("使用equlas比较结果:True");

    }

    else{

    System.out.println("使用equals比较结果:False");

    }

    if(sUpper.equalsIgnoreCase(sLow)){

    System.out.println("使用equalsIgnoreCase比较结果:True");

    }

    else{

    System.out.println("使用equalsIgnoreCase比较结果:False");

    }

    int j=sLow1.compareTo(sUpper);

    System.out.println(j);//输出为32

    int i=sLow1.compareTo(sUpper);

    System.out.println(i); //输出为33,由此得知compareTo输出ASIIC码值差值。

    }

    2、字符串的连接,使用concat方法进行操作。该方法可以连续连接若干个字符串,返回值也是一个字符串

    实例:

    public static void main(String []args)

    {

    String sUpper="WELCOME TO CHINA";

    String sLow="Welcome to china";

    String sConcat=sUpper.concat(sLow);

    System.out.println(sConcat);//输出WELCOME TO CHINAWelcome to china

    String sConcatMore=sUpper.concat(sLow).concat("多个concat");

    System.out.println(sConcatMore);

    }3、字符串的复制,主要有copyValueOf()方法实现,它有两个重载方法,分别提供部分复制和全部复制。

    copyValueOf(char[] ,int offset,int length)

    copyValueOf(char [])

    public static void main(String []args)

    {

    String sLow="Welcome to china";

    char [] ch=new char[sLow.length()];//开辟字符串数组大小

    for(int i=0;i

    ch[i]=sLow.charAt(i);

    }

    System.out.println(ch);//字符输出的值,输出Welcome to china

    String sCopyALL=String.copyValueOf(ch);

    System.out.println(sCopyALL);//输出复制字符串,结果Welcome to china

    String sCopyPart=String.copyValueOf(ch,2,3);

    System.out.println(sCopyPart);//输出部分复制字符串,结果lco,

    //由此说明copyValueOf(char[],起始位置,长度)

    }

    4、字符串替换,采用replace()方法:

    replace(char,char)              //将第一个字符替换为第二个字符

    replaceAll(String,String)//将字符串全部替换

    replaceFirst(String,String)//将字符串中第一个与参数1相同的字符串替换为参数2对应的字符串。

    实例:

    public static void main(String []args)

    {

    String sLow="Welcome to china";

    String sReplaceChar=sLow.replace('W','H');

    System.out.println(sReplaceChar); //输出替换字符的结果:Helcome to china

    String sReplaceAll=sLow.replaceAll("china","nanjing");

    System.out.println(sReplaceAll);//输出替换字符的结果:Welcome to nanjing

    String sReplaceFirst=sLow.replaceFirst("c","HJK");

    System.out.println(sReplaceFirst);//输出替换字符的结果:WelHJKome to china

    }5、分割字符串,分割字符串返回的是字符串数组,采用split()方法

    /*

    split函数的参数要求必须是字符串类型,不能使字符类型,以字符串来分割

    */

    public static void main(String []args)

    {

    String sLow="Welcome to china";

    System.out.println("原句:"+sLow);

    String [] sPlitArray=sLow.split(" ");

    for(int i=0;i

    {

    System.out.println("第"+i+"部分:"+sPlitArray[i]);

    }

    /*

    ---------- 运行 ----------

    原句:Welcome to china

    第0部分:Welcome

    第1部分:to

    第2部分:china

    输出完成 (耗时 0 秒) - 正常终止

    */

    }

    StringBuffer

    StringBuffer对象的字符串长度是可变的,尽管用String定义的常量可以用函数去操作,但是会产生更多的中间变量,所以还是不宜使用,对于要经常修改的字符串,我们可以定义成StringBuffer类型的,方便修改使用。StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。

    构造方法摘要

    StringBuffer()

    构造一个其中不带字符的字符串缓冲区,其初始容量为 16 个字符。

    StringBuffer(CharSequence seq)

    public java.lang.StringBuilder(CharSequence seq) 构造一个字符串缓冲区,它包含与指定的 CharSequence 相同的字符。

    StringBuffer(int capacity)

    构造一个不带字符,但具有指定初始容量的字符串缓冲区。

    StringBuffer(String str)

    构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容。

    StringBuffer常用方法:

    1、append()众多从在方法,可以接受任何类型数据。

    2、insert()方法一样。

    3、int capacity()返回当前容量

    4、char charAt(int index),返回指定位置的字符。

    5、StringBuffer delete(int start,int end),删除指定的字符串

    6、 void ensureCapacity(int minimumCapacity)确保容量至少等于指定的最小值。

    7、int indexOf(String str) 返回第一次出现的指定子字符串在该字符串中的索引。

    8、int indexOf(String str, int fromIndex)从指定的索引处开始,返回第一次出现的指定子字符串在该字符串中的索引。

    9、int lastIndexOf(String str)返回最右边出现的指定子字符串在此字符串中的索引。

    10、int lastIndexOf(String str, int fromIndex)

    返回最后一次出现的指定子字符串在此字符串中的索引

    11、void setCharAt(int index, char ch) 将给定索引处的字符设置为 ch。

    12、 StringBuffer reverse()将此字符序列用其反转形式取代。

    13、String substring(int start)返回一个新的 String,它包含此字符序列当前所包含的字符子序列。

    注意:String对象分配内存根据实际字符串长度,而StringBuffer分配内存时多开辟16个缓冲内存,所以使用capacity获取的为实际内存+16,而求字符串长度length()时,返回字符串长度。

    public static void main(String []args)

    {

    StringBuffer sb = new StringBuffer();

    System.out.println("原:" + sb);

    sb.append("welcome to china");

    System.out.println("append:" + sb);

    sb.insert(7,"KK");

    System.out.println("insert:" + sb);

    int iCapacity = sb.capacity();

    System.out.println("capacity:" + iCapacity);

    int iLen = sb.length();

    System.out.println("length:" + iLen);

    char ch = sb.charAt(2);

    System.out.println("charAt:" + ch);

    int iIndex = sb.indexOf("e");

    System.out.println("indexOf:" + iIndex);

    String sSubstring = sb.substring(5,15);

    System.out.println("substring:" + sSubstring);

    System.out.println("reverse:" + sb.reverse());

    }

    /*

    ---------- 运行 ----------

    原:

    append:welcome to china

    insert:welcomeKK to china

    capacity:34

    length:18

    charAt:l

    indexOf:1

    substring:meKK to ch

    reverse:anihc ot KKemoclew

    输出完成 (耗时 0 秒) - 正常终止

    */

    展开全文
  • 一、方法1、通过indexOf和substring这两个方法实现字符串分割实现逻辑:利用indexOf找出分割的字符在字符串中的位置,根据分割字符的位置切割字符串,再将分割好的字符串放进结果集。实现代码如下:/*** @...

    一、方法

    1、通过indexOf和substring这两个方法实现字符串分割

    实现逻辑:

    利用indexOf找出分割的字符在字符串中的位置,根据分割字符的位置切割字符串,再将分割好的字符串放进结果集。

    实现代码如下:

    /*** @Description: 通过indexof分割字符串

    * @Param: [str, regx]

    *@return: java.lang.String[]

    * @Author: YinYichang

    * @Date: 2018/7/18*/

    public staticString[] splitByIndex(String str, String regx) {//字符串截取的开始位置

    int begin = 0;//字符串截取的结束位置

    int limit = 0;//截取分割得到的字符串

    String splitStr = "";

    ArrayList result = new ArrayList();while (str.indexOf(regx) != -1) {//设置要截取的位置

    limit =str.indexOf(regx);

    splitStr=str.substring(begin, limit);//设置截取后的字符串

    str = str.substring(limit + 1, str.length());

    result.add(splitStr);

    }if (!StringUtil.isBlank(str)) {

    result.add(str);

    }

    String[] strs= newString[result.size()];returnresult.toArray(strs);

    }

    2、通过charAt和substring这两个方法实现字符串分割

    实现逻辑:

    同上,通过charAt方法找出字符所在字符串中的位置,再实现如同方法1的逻辑即可得到分割后的字符串结果集。

    实现代码如下:

    /*** @Description: 通过charAt分割字符串

    * @Param: [str, regx]

    *@return: java.lang.String[]

    * @Author: YinYichang

    * @Date: 2018/7/18*/

    public static String[] splitByCharAt(String str, charregx) {//字符串截取的开始位置

    int begin = 0;//截取分割得到的字符串

    String splitStr = "";

    ArrayList result = new ArrayList();int length =str.length();//计数器

    int i = 0;for (i = 0; i < length;i++) {if (str.charAt(i) ==regx) {

    splitStr=str.substring(begin, i);

    result.add(splitStr);

    str= str.substring(i + 1, length);

    length=str.length();

    i= 0;

    }

    }if (!StringUtil.isBlank(str)) {

    result.add(str);

    }

    String[] strs= newString[result.size()];returnresult.toArray(strs);

    }

    3、通过java自带的split方法分割字符串

    4、通过StringTokenizer对字符串进行分割

    通过这种方法分割字符串的使用频率比较少,这种分割需要创建新的对象(对内存造成不必要的开支),虽然该方法提供了提取分割结果的方法,但是也比较麻烦并没有数组那么简单。

    /*** @Description: 通过StringTokenizer分割字符串, 该方

    * 法分割后将结果封装并提供相关方法提取(很少用到)

    * @Param: [str, regx]

    *@return: StringTokenizer

    * @Author: YinYichang

    * @Date: 2018/7/18*/

    public staticStringTokenizer splitByStringTokenizer(String str, String regx) {

    StringTokenizer stringTokenizer= newStringTokenizer(str, regx);returnstringTokenizer;

    }

    二、性能测试

    由于StringTokenizer很少用到就不测试了,主要测试两种自定义的分割方法和java自带的方法。

    测试代码如下:

    String str = "a,b,c,d,e,f,g";

    System.out.println("测试代码循环10000次。。。,结果如下:");long length = 10000;//indexof字符串分割测试

    long begin =System.currentTimeMillis();for (int i = 0; i < length; i++) {

    String[] strs= SplitStr.splitByIndex(str, ",");

    }long end =System.currentTimeMillis();

    System.out.println("indexof分割字符串返回数组用时:"+(end -begin));//charAt字符串分割测试

    begin =System.currentTimeMillis();for (int i = 0; i < length; i++) {

    String[] strs= SplitStr.splitByCharAt(str, ',');

    }

    end=System.currentTimeMillis();

    System.out.println("charAt分割字符串返回数组用时:"+(end -begin));//split字符串分割测试

    begin =System.currentTimeMillis();for (int i = 0; i < length; i++) {

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

    }

    end=System.currentTimeMillis();

    System.out.println("split分割字符串用时:"+(end - begin));

    测试结果:

    922fd94ee65debf16280bef39d0ba7be.png

    f3f4e7a33bc2b7b42b5c7002cc30bdd0.png

    03644a4c2df1d6a73531f6115de850bb.png

    以上测试结果,分别对三种方法循环测试1000次、10000次和100000次,由结果可以看出利用charAt分割字符串的效率是最高的。

    其实,查看split方法的实现代码后发现,split采用的分割方式是和自定义的第一种方式类似的,可以看出中两者的差距不是特别大。

    代码优化任重道远,如有问题希望给与指正!

    展开全文
  • java字符串分割方法

    2021-11-17 22:37:51
    java 分割字符串split()方法 实现功能 编写一个将字符串分段的类,传入:需分段的字符串 与 字符个数(以此个数进行分段),输出:按指定字符个数进行分段后的若干字符串(汉字算单个字符)。 功能实现要求分析 ...
  • java实现 字符串解析

    2021-04-23 11:46:03
    public class StringAnalytical { // 字符串解析,将字符串转根据分割符换成字符串数组 private String[] stringAnalytical(String string, char c) { int i = 0; int count = 0; if (string.indexOf(c) == -1) ...
  • Java中的字符串分割 .

    千次阅读 2021-03-01 06:38:12
    Java中的我们可以利用split把字符串按照指定的分割符进行分割,然后返回字符串数组,下面是string.split的用法实例及注意事项:java.lang.string.splitsplit 方法将一个字符串分割为子字符串,然后将结果作为字符串...
  • JAVA字符串按分隔符号字符串分割

    千次阅读 2021-02-26 15:59:18
    有些字符串分割需要注意了..如下例子:public class Split {public static void main(String[] args) {String str1 ="1,2,3,4,5";String str2 ="1,2,3,4,";String str3 ="1,,2,3,";String str4=",,,,";System.out....
  • Java分割字符串

    2021-03-16 00:41:33
    java.lang.String的split()方法, JDK 1.4 or laterpublicString[]split(Stringregex,int limit)示例代码public classStringSplit {public static voidmain(String[] args) {String sourceStr = "1,2,3,4,5";...
  • Java字符串分割

    2021-04-10 13:53:11
    Java 实例 - 字符串分割以下实例使用了 split(string) 方法通过指定分隔符将字符串分割为数组:JavaStringSplitEmp.java 文件public class JavaStringSplitEmp {public static void main(String args[]){String str ...
  • java拆分字符串使用string类的spilt方法,针对某个分隔符来分割一个字符串,示例如下: public class StringSplit { public static void main(String[] args) { String sourceStr = "1,2,3,4,5";//一个字符串 String...
  • 阿里面试官一般都是P7/P8岗,标到普通互联网公司相当于就是技术专家那种类型!他们对于没有经验的毕业生面试问的比较浅一点,大多数问题问的集合、锁、JVM调优,线程池、spring方面也会问源码、然后是分库分表、...
  • 前缀、中缀、后缀表达式及其相互转化的Java实现 一.中缀表达式转换为前缀.后缀表达式 给个中缀表达式:a+b*c-(d+e) 首先根据运算符的优先级给所有运算单位加括号:((a+(b*c))-(d+e)) 将运算符号移动到对应括号的前面 ...
  • 方法1:采用String的split,验证代码如下:import java.util.Arrays;public class TestSplit {public static void main(String[] args) {String orignString = new String("5,8,7,4,3,9,1");String[] testString = ...
  • Java分割字符串遇到的问题,含有"[]"、"{}"、""、"."不能分割 因为"." 、""、“|”、"[","{“是特殊字符,需要转义,”\." 、"\"、"\|"、"[" 、"{" 。 比如: CRV[本田]分割成CRV和[本田] String name="CRV[本田]"; ...
  • java中,经常会对字符串进行分割,使用split方法把字符串按照指定的分割进行分割,然后返回字符串数组,下面是string.split的用法实例及注意事项:public class StringSplit {public static void main(String[] ...
  • 我们在日常开发时会经常遇到将一个字符串按照指定的字符进行分割。这时,我们往往会想到使用str.split(","),进行处理得到分割后的数组。然而, 使用split()方法在分割特殊的字符时是需要转移的。如小数点“.”下面...
  • 一.Java字符串类基本概念在JAVA语言中,字符串数据实际上由String类所实现的。Java字符串类分为两类:一类是在程序中不会被改变长度的不变字符串;二类是在程序中会被改变长度的可变字符串。Java环境为了存储和维护...
  • 给你一个由若干 0 和 1 组成的字符串s,请你计算并返回将该字符串分割成两个子字符串(即左子字符串和右子字符串, 子字符串允许为空)所能获得的最大得分。 已知分割字符串的得分规则如下: 左子字符串中:0得2分,1...
  • 分离字符串字符串依所设定的条件予以分离是很常见的操作,例如指令的分离、文本文件的数据读出等。以后者而言,当在文本文件中存储以下的数据时,在读入文件后,将可以使用String的split()来协助每一行的数据分离...
  • Java字符串分割(转)

    千次阅读 2021-03-01 06:37:02
    java.lang.String的split()方法, JDK 1.4 or laterpublicString[]split(Stringregex,int limit)示例代码public class StringSplit {public static void main(String[] args) {String sourceStr = "1,2,3,4,5";...
  • I have the String a="abcd1234" and i want to split this into String b="abcd" and Int c=1234This Split code should apply for all king of input like ab123456 and acff432 and so on.How to split this kind...
  • 展开全部这个映射关系可以用map来做如果全是数字的话(没有A、B)那么用字符串数组来做映e5a48de588b662616964757a686964616f31333365663432射还更好importjava.util.HashMap;importjava.util.Map;publicclassTest{...
  • 经常在网上各大版块都能看到对于java字符串运行时内存分配的探讨,形如:String a = "123",String b = new String("123"),这两种形式的字符串是存放在什么地方的呢,其实这两种形式的字符串字面值"123"本身在运行时...
  • 首先读取XML文件内的某个节点的属性值,这个已经在Java实现——Dom4j读写XML文件中详细介绍过了。那么毋庸置疑第一步就是理清如何将一个文件夹内的全部内容一起复制到指定的新的文件夹下。后面这个FileUtils工具类类...
  • 展开全部根据java根据指定的字符,分割字符串的方法是:e69da5e...字符串分割--java中String.split()用法:1、“.”和“|”都是转义字符,必须得加"\\";如果用“.”作为分隔的话,必须是如下写法:String.split("\\....
  • Java中的我们可以利用split把字符串按照指定的分割符进行分割,然后返回字符串数组,下面是string.split的用法实例及注意事项:java.lang.string.splitsplit 方法将一个字符串分割为子字符串,然后将结果作为字符串...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 341,015
精华内容 136,406
关键字:

java对字符串进行分割

java 订阅