java源码解析之String类(二)
上一节主要介绍了String类的一些构造方法,主要分为四类
- 无参构造器:String(),创建一个空字符串"",区别于null字符串,""已经初始化,null并未初始化
- 副本构造器:String(String s),简单的赋值,得到的是一个副本,俩个引用指向的是常量池中的同一个String,但是String是不可变的,所有用意不大
- byte类构造器:String(byte[] b),将byte数组转换为String,注意并不是简单的赋值,而是整体copy一份
- char类构造器:String(char[] c),将char数组转换成String,注意并不是简单的赋值,而是整体copy一份
- codepoints构构器:String(int[] i),将超过char表示范围的字符转换为为String
- String缓存流的转换:String(StringBuffer),将字符换缓冲流转换为String
- /*
- * 获得字符串的长度,也就是属性value数组的长度
- */
- public int length() {
- return value.length;
- }
- /*
- * 判断字符串是否为空,也就是判断属性value数组的长度是否等于0
- */
- public boolean isEmpty() {
- return value.length == 0;
- }
- /*
- * charAt方法可以直接获取当前下标对应的字符,这对于判断某个位置的字符值很方便
- * 区别于
- */
- public char charAt(int index) {
- if ((index < 0) || (index >= value.length)) {
- throw new StringIndexOutOfBoundsException(index);
- }
- return value[index];
- }
- /*
- * 返回指定索引处的字符(Unicode代码点)。 codePoint在上一章已经介绍过了,具体就是那些超出byte和char表示方位的字符
- */
- public int codePointAt(int index) {
- if ((index < 0) || (index >= value.length)) {
- throw new StringIndexOutOfBoundsException(index);
- }
- return Character.codePointAtImpl(value, index, value.length);
- }
- /*
- * 返回指定索引之前的字符(Unicode代码点)。
- */
- public int codePointBefore(int index) {
- int i = index - 1;
- if ((i < 0) || (i >= value.length)) {
- throw new StringIndexOutOfBoundsException(index);
- }
- return Character.codePointBeforeImpl(value, index, 0);
- }
- /*
- * 返回此 String指定文本范围内的Unicode代码点数。
- */
- public int codePointCount(int beginIndex, int endIndex) {
- if (beginIndex < 0 || endIndex > value.length || beginIndex > endIndex) {
- throw new IndexOutOfBoundsException();
- }
- return Character.codePointCountImpl(value, beginIndex, endIndex - beginIndex);
- }
- /*
- * 返回此String中的索引,该索引通过codePointOffset代码点从给定的index偏移。
- * index和codePointOffset给出的文本范围内的未配对代理计为每个代码点。
- *
- */
- public int offsetByCodePoints(int index, int codePointOffset) {
- if (index < 0 || index > value.length) {
- throw new IndexOutOfBoundsException();
- }
- return Character.offsetByCodePointsImpl(value, 0, value.length, index, codePointOffset);
- }
- /*
- * 将此字符串复制给dst字节数组,默认为整体复制,其中dstBegin为目标数组dst中的开始位置
- * 此方法为包访问权限,所以我们并没有调用的权限
- */
- void getChars(char dst[], int dstBegin) {
- System.arraycopy(value, 0, dst, dstBegin, value.length);
- }
- /*
- * 将此字符串的额指定位置开始到指定位置结束复制给dst字节数组,其中dstBegin为目标数组dst的开始位置,
- * srcBegin和srcEnd分别为本字符串的开始位置和结束位置
- */
- public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
- if (srcBegin < 0) {
- throw new StringIndexOutOfBoundsException(srcBegin);
- }
- if (srcEnd > value.length) {
- throw new StringIndexOutOfBoundsException(srcEnd);
- }
- if (srcBegin > srcEnd) {
- throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
- }
- System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
- }
- /*
- * 方法已过时
- * 使用平台的默认字符集将此 String编码为字节序列,将结果存储到新的字节数组中,可以指定字符串的开始位置和结束位置,
- * 但结果往往是不正确的,在源码中我们可以看到,仅仅是将字符串的每一位字符强转成字节类型,实际用处很少。
- *
- */
- @Deprecated
- public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin) {
- if (srcBegin < 0) {
- throw new StringIndexOutOfBoundsException(srcBegin);
- }
- if (srcEnd > value.length) {
- throw new StringIndexOutOfBoundsException(srcEnd);
- }
- if (srcBegin > srcEnd) {
- throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
- }
- Objects.requireNonNull(dst);
- int j = dstBegin;
- int n = srcEnd;
- int i = srcBegin;
- char[] val = value; /* avoid getfield opcode */
- while (i < n) {
- dst[j++] = (byte) val[i++];
- }
- }
- /*
- * 指定编码字符集将此 String编码为字节序列,将结果存储到新的字节数组中
- */
- public byte[] getBytes(String charsetName) throws UnsupportedEncodingException {
- if (charsetName == null)
- throw new NullPointerException();
- return StringCoding.encode(charsetName, value, 0, value.length);
- }
- /*
- * 指定编码字符集将此 String编码为字节序列,将结果存储到新的字节数组中
- */
- public byte[] getBytes(Charset charset) {
- if (charset == null)
- throw new NullPointerException();
- return StringCoding.encode(charset, value, 0, value.length);
- }
- /*
- * 使用平台的默认字符集将此 String编码为字节序列,将结果存储到新的字节数组中
- */
- public byte[] getBytes() {
- return StringCoding.encode(value, 0, value.length);
- }
- /*
- * String重写Object类的equals方法,详细阅读源码,我们发现形参是Object类型,那么在实际传参的过程当中
- * 除了String类型,别的引用类型都会返回false,重点注意的是StringBuffer和StringBuild,在实际比较的时候一定要先进行转换
- * equals实际比较的就是字符串的每一位依次进行比较,直到全部比较完毕都没有不一样的才返回true
- */
- public boolean equals(Object anObject) {
- if (this == anObject) {
- return true;
- }
- if (anObject instanceof String) {
- String anotherString = (String) anObject;
- int n = value.length;
- if (n == anotherString.value.length) {
- char v1[] = value;
- char v2[] = anotherString.value;
- int i = 0;
- while (n-- != 0) {
- if (v1[i] != v2[i])
- return false;
- i++;
- }
- return true;
- }
- }
- return false;
- }
- /*
- * 将此字符串与指定的StringBuffer进行 比较内容是否相等
- */
- public boolean contentEquals(StringBuffer sb) {
- return contentEquals((CharSequence) sb);
- }
- private boolean nonSyncContentEquals(AbstractStringBuilder sb) {
- char v1[] = value;
- char v2[] = sb.getValue();
- int n = v1.length;
- if (n != sb.length()) {
- return false;
- }
- for (int i = 0; i < n; i++) {
- if (v1[i] != v2[i]) {
- return false;
- }
- }
- return true;
- }
- /*
- * 将此字符串与指定的CharSequence进行内容比较是否相等
- */
- public boolean contentEquals(CharSequence cs) {
- // Argument is a StringBuffer, StringBuilder
- if (cs instanceof AbstractStringBuilder) {
- if (cs instanceof StringBuffer) {
- synchronized (cs) {
- return nonSyncContentEquals((AbstractStringBuilder) cs);
- }
- } else {
- return nonSyncContentEquals((AbstractStringBuilder) cs);
- }
- }
- // Argument is a String
- if (cs instanceof String) {
- return equals(cs);
- }
- // Argument is a generic CharSequence
- char v1[] = value;
- int n = v1.length;
- if (n != cs.length()) {
- return false;
- }
- for (int i = 0; i < n; i++) {
- if (v1[i] != cs.charAt(i)) {
- return false;
- }
- }
- return true;
- }
- /*
- * 能用一行代价解决的事就不用俩行,三元运算符?:直接解决。其中regionMatches(true, 0, anotherString, 0, value.length)是测试是否相等的函数
- * 第一个参数true代表忽略大小写
- */
- public boolean equalsIgnoreCase(String anotherString) {
- return (this == anotherString) ? true
- : (anotherString != null) && (anotherString.value.length == value.length)
- && regionMatches(true, 0, anotherString, 0, value.length);
- }
java源码解析之String类(二)的更多相关文章
- java源码解析之String类(一)
String是我们接触最多的类,无论是学习中还是工作中,基本每天都会和字符串打交道,从字符串本身的各种拼接.切片.变形,再到和其他基本数据类型的转换,几乎无时无刻都在使用它,今天就让我们揭开Strin ...
- java源码解析之String类(三)
上一节我们主要讲了String类的一些不是很常用的方法,其中需要掌握的如下,我就不再赘述了 public int length() public boolean isEmpty() public by ...
- java源码解析之String类(四)
/* * 返回指定字符第一次出现的字符串内的索引 */ public int indexOf(int ch) { return indexOf(ch, 0); } /* * 返回指定字符第一次出现的字 ...
- java源码解析之String类(五)
/* * 切片函数,非常重要,这里一定要牢记beginIndex是开始位置,endIndex是结束位置,区别于以前学的offset是开始位置,而count或length是个数和长度 * 比如说,new ...
- Java源码解析——集合框架(二)——ArrayBlockingQueue
ArrayBlockingQueue源码解析 ArrayBlockingQueue是一个阻塞式的队列,继承自AbstractBlockingQueue,间接的实现了Queue接口和Collection ...
- java源码解析之Object类
一.Object类概述 Object类是java中类层次的根,是所有类的基类.在编译时会自动导入.Object中的方法如下: 二.方法详解 Object的方法可以分成两类,一类是被关键字fin ...
- Spring源码解析之ConfigurationClassPostProcessor(二)
上一个章节,笔者向大家介绍了spring是如何来过滤配置类的,下面我们来看看在过滤出配置类后,spring是如何来解析配置类的.首先过滤出来的配置类会存放在configCandidates列表, 在代 ...
- [Java源码解析] -- String类的compareTo(String otherString)方法的源码解析
String类下的compareTo(String otherString)方法的源码解析 一. 前言 近日研究了一下String类的一些方法, 通过查看源码, 对一些常用的方法也有了更透彻的认识, ...
- [java源码解析]对HashMap源码的分析(二)
上文我们讲了HashMap那骚骚的逻辑结构,这一篇我们来吹吹它的实现思想,也就是算法层面.有兴趣看下或者回顾上一篇HashMap逻辑层面的,可以看下HashMap源码解析(一).使用了哈希表得“拉链法 ...
随机推荐
- 史上最全最强SpringMVC详细示例实战教程【good】
1)Spring MVC 在调用处理方法之前,在请求线程中自动的创建一个隐含的模型对象. 2)调用所有方法级的 标注了 @ModelAttribute 的方法,并将方法返回值添加到隐含的模型对象中. ...
- hdu 4374 单调队列
求一个最大k连续的子序列和 单调队列 #include<stdio.h> #include<string.h> #include<iostream> using ...
- CSS position财产
CSS在position位置信息要素用于表示属性. 有三个起飞值:static, absolute, relative. 假设元件不显式配置position财产,该元素默认position 值至sta ...
- 用SendNotifyMessage代替PostMessage避免消息丢失(WIN7下消息队列的默认长度是10000,队列满后消息将被丢弃)
大家都知道PostMessage会丢消息,但是消息队列的大小是多少呢,下面做了一个测试. 代码: 1 unit Unit1; 2 3 interface 4 5 uses 6 Windows, M ...
- InitializeComponent无法识别的问题
学习Xamarin官方文档的时候,Xamarin.Forms的开始篇一直在用ContentPage讲解自己一直是创建Page,然后手动修改成继承于ContentPage,然后InitializeCom ...
- BackgroundWorker使用
using System.ComponentModel; private BackgroundWorker worker; worker = new BackgroundWorker(); work ...
- css3如何让div一直循环自转圈,附带:网络请求通知图片一直在转圈实例
css3如何让div一直循环自转圈 代码如下: div{ -webkit-transition-property: -webkit-transform; -webkit-transition-dura ...
- How do you create a DynamicResourceBinding that supports Converters, StringFormat?
原文 How do you create a DynamicResourceBinding that supports Converters, StringFormat? 2 down vote ac ...
- C# Newtonsoft.Json JObject移除属性,在序列化时忽略
原文 C# Newtonsoft.Json JObject移除属性,在序列化时忽略 一.针对 单个 对象移除属性,序列化时忽略处理 JObject实例的 Remove() 方法,可以在 指定序列化时移 ...
- mysql 更改root密码
mysql 更改root密码,有很多种,网上也有很多记录,这里只是做个记录,以后可以看看,只记录两种自己常用的方法. 1.改表法,登录到数据库,切换到:mysql数据库,update user set ...