JDK源码学习之String

一、概述

     平时工作中可能使用最多的就是String字符串了,所以我们有必要深入的了解一下String的实现。

二、类头

    public final class String implements java.io.Serializable, Comparable<String>, CharSequence

final说明String不可被继承,可序列化,实现了Comparable接口(具体比较逻辑见源码),所以我们可以直接使用Collections.sort(List<String>)对字符串进行排序,默认调用自己的方法来做比较,如果达不到你想要的要求就要自己编写比较器实现Comparator接口,然后调用Collection.sort(List,Comparator)来实现定制排序,方便灵活。

CharSequence is a readable sequence of char  values. This interface provides uniform, read-only access to many different kinds of char sequences.CharSequence 是 char 值的一个可读序列。此接口对许多不同种类的 char 序列提供统一的只读访问。

三、内部属性

   private final char value[];//char数组用来存放String内部的char
    private final int offset;//偏移量,标示了截取value数组的开始位置

    private final int count;//记录字符串中字符的个数
    private int hash; // Default to 0

    private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0];//作用不清楚,请高手不吝赐教

    public static final Comparator<String> CASE_INSENSITIVE_ORDER  = new CaseInsensitiveComparator();//重写的比较器,比较忽略大小写时使用
四、常见方法

   常用的构造器

     public String(String original) //通过String来构造新字符串

     public String(char value[])//通过字符数组来构造,新的字符串里面的char数组是重新生成的,没有指向传入数组

     public String(byte bytes[], String charsetName)//通过byte数组,跟字符编码来初始化String

     public String(byte bytes[])//使用默认编码解析bytes数组,window为GBK,Linux为UTF-8

     public String(StringBuffer buffer)//使用SB来初始化 

     String(int offset, int count, char value[]) {//包级私有构造函数,外面调用不了,注意这里新生成的字符串的字符数组指向了传入的value
          this.value = value;//这里有潜在内存泄露危险,下面会看到。
          this.offset = offset;
          this.count = count;
    }

     

      常用的方法

     

      查找方法:

      public int codePointAt(int index)//通过序列找到对应字符的Unicode编码

      public char charAt(int index) //通过索引找到对应字符

      public int indexOf(int ch)//找到对应首次出现的字符序号,没有返回-1

      public int lastIndexOf(int ch) //找到最后出现ch的位置,没有找到返回-1

             


     比较方法   

         public boolean equalsIgnoreCase(String anotherString)//忽略大小写比较

    

public boolean equals(Object anObject) {//判断是否相同,判断的依据是内容完全相同
      if (this == anObject) {
      return true;
     }
      if (anObject instanceof String) {
         String anotherString = (String)anObject;
         int n = count;
         if (n == anotherString.count) {
         char v1[] = value;
         char v2[] = anotherString.value;
         int i = offset;
        int j = anotherString.offset;
       while (n-- != 0) {
           if (v1[i++] != v2[j++])
         return false;
       }
        return true;
      }
   }
 return false;
    }


public int compareTo(String anotherString) {//比较方法,策略是从头比较,找到第一个不同的返回差值
int len1 = count;
int len2 = anotherString.count;
int n = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
if (i == j) {
   int k = i;
   int lim = n + i;
   while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
   return c1 - c2;//不同长度,按照首次不一致char值来比较大小的
}
k++;
   }
} else {
   while (n-- != 0) {
char c1 = v1[i++];
char c2 = v2[j++];
if (c1 != c2) {
   return c1 - c2;
}
   }
}
return len1 - len2;
    }


    

public int compareToIgnoreCase(String str) {//忽略大小写比较字符串
        return CASE_INSENSITIVE_ORDER.compare(this, str);//自己实现了比较器
    } 


    截取方法:

    

public String substring(int beginIndex) {//得到指定索引开始的子串
return substring(beginIndex, count);
    }

   public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
   throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > count) {
   throw new StringIndexOutOfBoundsException(endIndex);
}
if (beginIndex > endIndex) {
   throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
}
return ((beginIndex == 0) && (endIndex == count)) ? this :
   new String(offset + beginIndex, endIndex - beginIndex, value);//重新生成一个字符串,这里新生成的字符串使用的原有字符串的字符数组,本意是通过复用提高效率,但是在原串很大的情况下,新截取的是很小的一部分,会产生垃圾数据,导致内存泄露。建议截取之后再重新

new String(s.toCharArray)。
    } 


替换分割:

   

 public String replaceAll(String regex, String replacement) {//该方法经常使用的话并且正则表达式不经常改变,建议把Pattern对象提取出来,

//重复使用,来提高效率,同理其他替换方法。
          return Pattern.compile(regex).matcher(this).replaceAll(replacement);
    }

      public static Pattern compile(String regex) {
        return new Pattern(regex, 0);//调用compile方法每次都会重新生成一个pattern类
    }

  public String[] split(String regex) {//按照正则表达式分割,注意如果想要截取. 或者|,需要\\.和\\|,另外如果想要截取条件多个可以and|or两个都截取
        return split(regex, 0);
    }


 

其他方法

public char[] toCharArray() {//获得String的char数组,得到的是新的数组
 char result[] = new char[count];
 getChars(0, count, result, 0);
 return result;
    }

public native String intern();//本地方法,去字符串池里找是否存在该字符串,有直接返回,没有添加到字符串池中,默认池中数据时在编译时写入,该方法提供动态添加池中数据功能

public String concat(String str) {//字符串连接方法,如果低于3个一下字符串连接可以使用,效率高,过多的字符串连接应该使用SB系列
 int otherLen = str.length();
 if (otherLen == 0) {
     return this;
 }
 char buf[] = new char[count + otherLen];
 getChars(0, count, buf, 0);
 str.getChars(0, otherLen, buf, count);
 return new String(0, count + otherLen, buf);
}


五、总结

    String字符串对象是不可变对象,线程安全,不需要同步。

    为提高效率,jvm会创建缓冲池,存放编译期间的字符串,来达到复用目的,通过intern方法可以动态添加。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
牙科就诊管理系统利用当下成熟完善的SSM框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的Mysql数据库进行程序开发。实现了用户在线查看数据。管理员管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等功能。牙科就诊管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 管理员在后台主要管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等。 牙医列表页面,此页面提供给管理员的功能有:查看牙医、新增牙医、修改牙医、删除牙医等。公告信息管理页面提供的功能操作有:新增公告,修改公告,删除公告操作。公告类型管理页面显示所有公告类型,在此页面既可以让管理员添加新的公告信息类型,也能对已有的公告类型信息执行编辑更新,失效的公告类型信息也能让管理员快速删除。药品管理页面,此页面提供给管理员的功能有:新增药品,修改药品,删除药品。药品类型管理页面,此页面提供给管理员的功能有:新增药品类型,修改药品类型,删除药品类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值