• 动手动脑4--有关字符串的一些东西


    为何会出现这样的结果?

    s0,s1,s2三个String类型的对象实际上指向的都是"Hello"这个常量,所以s0、s1、s2三者之间用==判断是否指向同一块内存肯定会返回布尔值true,这里的s0、s1、s2就很像C/C++里面的指针(Java官方说是没有指针的,其实Sun公司在写Java这门语言时干脆就把指针给封装成引用这种类型了,比较C++里面利用new字段开辟新空间的那句代码,和Java中利用new字段定义新对象的那句代码,其实是一样的,只不过那个*不用写了),而后面那两个是实实在在定义的两个新的不同的对象,尽管存的值相同,但是==对于两个对象而言比较的是他们指向的空间的地址,所以自然会返回布尔值false

    这又有一个新的例子,和上面的区别就是为什么s1=="ab"会返回false,有人会问s1+="ab",s1="ab",那么两者指向不应该一样吗?

    这个问题有点麻烦,主要就麻烦在s1+="b"这个操作不是在声明s1时完成的,要是和上面那个例子一样直接写String s1 = "a"+"b",那样还会是true。但是为什么分开写就不行呢,这跟String池有关。这个池维护所有不同的实例化后的字符串,比如,可能有a, ab, cde等等。当程序申请一个新的字符串的时候,如果这个字符串已经存在池中,那么这个字符串就会被返回,如果没有,就实例化一个新的,并且把它也放到池中。所以String s1 = "a"+"b",执行到这句时,会自动检查池中有没有"ab"这个串,如果有就将“ab”这个常量的地址交给s1,所以就解释了为什么上面那个例子是true。而这里这个由于分开了,是在s1+="b"这个过程中完成了s1 = new String("ab")这么个隐藏的过程,所以这里是false。至于equals那个方法,这里不讲,下面的例子会重点提到。

    接下来就说说String类中一个重要的方法——equals,用来比较两个字符串的内容是否一样。

    方法的源码:

     1 public boolean equals(Object anObject) {
     2         if (this == anObject) {
     3             return true;
     4         }
     5         if (anObject instanceof String) {
     6             String anotherString = (String) anObject;
     7             int n = value.length;
     8             if (n == anotherString.value.length) {
     9                 char v1[] = value;
    10                 char v2[] = anotherString.value;
    11                 int i = 0;
    12                 while (n-- != 0) {
    13                     if (v1[i] != v2[i])
    14                             return false;
    15                     i++;
    16                 }
    17                 return true;
    18             }
    19         }
    20         return false;
    21     }

     从上面的代码中可以看到,

     (1)String类中的equals首先比较地址,如果是同一个对象的引用,可知对象相等,返回true。

     (2)若果不是同一个对象,equals方法挨个比较两个字符串对象内的字符,只有完全相等才返回true,否则返回false。

     参考一段代码:

    String str = "abc";

    String str1 = str.trim().toUpperCase().concat("defg");

    输出str1,会显示"ABCdefg",trim()的作用是去掉字符串首位的空格,toUpperCase()的作用是将小写字符大写化,而concat(String s)的作用是将参数s加在字符串的后面,由此可以写一个MyCounter类,添加两个方法increase()和decrease(),返回值都是int型(或者利用重载计算多种类型),代码如下:

     1 public class MyCounter{
     2       private int value;
     3       public MyCounter(int value){
     4                this.value =value;
     5       }
     6       public int increase(int val){
     7               value+=val;
     8               return value;
     9       }
    10       public int decrease(int val){
    11               value-=val;
    12               return value;
    13       }
    14       public String toString(){
    15               return String.valueOf(value);
    16       }
    17 }

    MyCounter counter1=new MyCounter(1);
    MyCounter counter2=counter1.increase(100).decrease(2).increase(3);

    System.out.print(counter1);         在主函数中写入这些代码,会输出102

    最后再来说说几个常用的String类中的常用方法:

    public int length():返回值类型为int型,返回当前字符串的有效长度

    public void charAt(int num):num为索引值,返回字符串中下标为num的字符,如果越界会抛出异常

    public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin):截取字符数组,要复制的第一个字符在索引srcBegin处,被复制的最后一个字符是在的索引srcEnd1即要复制的字符总数是srcEnd srcBegin处。字符被复制到子数组的夏令时开始在指数dstBegin和结束于索引:dstbegin + (srcEnd-srcBegin) - 1

    public String replace(char oldChar,char newChar):替换字符,利用newchar替换oldchar,然后返回新的字符串

    UpperCase()和toLoserCase()一个转成大写,一个转成小写

    trim():去掉字符串首尾两端所有的空格

    至于toCharArray(),上源码:

      public char[] toCharArray() {
            // Cannot use Arrays.copyOf because of class initialization order issues
            char result[] = new char[value.length];
            System.arraycopy(value, 0, result, 0, value.length);
            return result;
        }

    将一个字符串转换成一个Char型的字符数组,并且这里面的字符是原封不动的拿进去的,意思就是说,包含一切字符均转换成相应的字符数组。

    ==========================================================================================================================================================================

    End

  • 相关阅读:
    2018.12.1 区块链论文翻译
    2018.11.29 区块链论文翻译
    jshell 一个代码片段测试工具(jdk9后新增的功能)
    java 的var 定义变量有点鸡肋...
    小心Math.abs(-2147483648)的坑
    java获取同级目录下的文件
    java获取formdata里的所有参数
    No enclosing instance of type VolatleTest is accessible. Must qualify the allocation with an enclosing instance of type VolatleTest
    if else太多怎么代替,太难维护?可以使用spring-plugin 插件系统
    设计一个泛型的获取数组最大值的函数.并且这个方法只能接受Number的子类并且实现了Comparable接口
  • 原文地址:https://www.cnblogs.com/messi2017/p/7729872.html
Copyright © 2020-2023  润新知