c++ char 转 string_4.2String类
4.2String类
这一节,我们学习第一个类:String类。String翻译成汉语就是“字符串”,是字符的序列。我们知道,在Java中,默认采用Unicode字符集,因此字符串就是Unicode字符的序列。例如字符串“Java大失叔”,就是由7个Unicode字符‘J’、‘a’、‘v’、‘a’、‘大’、‘失’、‘叔’组成。在JDK中,把字符串抽象成一个类String提供给我们使用。String类在java.lang包中。
4.2.1构造String对象
上面我们说了,想看电视得先买一台电视,电视在出厂的时候厂家会初始化它的状态。想使用String类,得先得到一个String的对象,然后指定属性的初始状态,然后才能使用它。得到对象的过程,叫做构造对象。在Java中,我们用构造器(constructor)来构造实例,构造器其实是一种特殊的方法,用来构造并初始化对象。我们采用在构造器前面加上new关键字来实现,例如:
new 构造器();
我们查看String类的API文档(怎么查这里不再赘述),构造方法截图如下:
发现String类的构造方法有几个特点:
足足有15个构造方法
有的方法上标有Deprecated,这个标签的含义是不推荐使用,将来在新版本中可能会移除
构造方法的名字和类名相同
构造方法的名字和类名相同,这是Java构造器的特点,也是规定。我们挑选其中一个构造方法:String(char[] value)
我们看到,这其实就是用一个char数组来构造一个字符串,那么首先我们得有一个char数组才行,例如我们想要得到一个字符串“Java大失叔,你真棒”。那么代码如下:
char[] a = { 'J', 'a', 'v', 'a', '大', '失', '叔', ',', '你', '真', '棒' };String s = new String(a);System.out.println(s);// 结果输出:Java大失叔,你真棒
事实上,由于String太常用了,Java给我们提供了更加简便的构造方法,直接用双引号将一段字符序列包起来,就得到了一个String的实例:
String s = "Java大失叔,你真棒";
OK,我们得到了一个String对象了,下面我们来使用这个对象。我们可以看到,API中有几十个方法,我们挑选一些常用的演示一下。
4.2.2代码点和代码单元
首先,我们回忆一下关于char和Unicode的知识。Unicode定义了U+0000到U+10FFFF一共1114112个码位(code point),英文直译为代码点。一个代码点表示一个字符。char是用来存放UTF-16编码中的一个代码单元(code unit),即2个字节。平面0的代码点用一个代码单元即一个char就可以表示,其余的代码点需要用2个代码单元即2个char才能表示。
我们知道Stirng是Unicode字符的序列,但是底层的实现实际上是用char构成的。String类提供了一些关于代码点和代码单元相关的方法,请看下面摘抄的几个方法:
修饰和类型 |
方法 |
描述 |
int |
length() |
返回字符串的长度 |
int |
codePointCount(int beginIndex, int endIndex) |
返回beginIndex和endIndex-1之间的代码点的数量。 |
char |
charAt(int index) |
返回index索引处的char |
int |
codePointAt(int index) |
返回index索引处的代码点 |
我们想获得字符的数量(即代码点的数量),需要用codePointCount方法,而length方法返回的是char的数量(即代码单元的数量)。调用对象的方法很简单,用如下形式:
对象.方法();
代码示例如下:
String s = "大失叔喜欢打麻将??????";// System.out.println("字符串s的代码单元数量为:" + s.length());System.out.println("字符串s的代码点数量为" + s.codePointCount(0, s.length()));
输出结果:
字符串s的代码单元数量为:20 字符串s的代码点数量为:14
我们可以看到,对于??????,这6个字符,每个字符占用2个代码单元,所以length方法的结果是20,而codePointCount方法的结果是14。
我们再看看后面2个方法,这应该就相对简单了,一个是返回index处的代码单元,一个是返回index处的代码点。我们直接看代码:
String s = "大失叔喜欢打麻将??????";// int c = s.charAt(8);// 把char赋值给一个int,对应这个代码单元对应的十进制,结果是55356,十六进制为0xD83Cint d = s.codePointAt(8);// 结果是126976,十六进制为0x1F000
4.2.3对象与变量
上面我们看到,创建出来一个String对象,一般我们会赋值给一个变量。那么对象和变量之间有什么关系和区别呢?我们先看几行代码:
String a;String b;a = "大失叔喜欢打麻将";b = a;
这几行代码,会涉及到下面一些行为:
第1、2行,我们定义了2个String类型的变量a和b。这时候Java会在内存中分别分配一块空间给a和b,但是这时候这2块内存空间中没有存放任何值。
第3行,我们把一个字符串赋值给变量a。Java会在内存中分配一块空间,存放这个字符串,然后把这块空间的地址存放到变量a的内存空间中。
第4行,把变量a赋值给b,相当于把变量a内存空间中的地址存放到变量b的内存空间中,这时候a和b同时指向字符串“大失叔喜欢打麻将”对应的内存空间。
我们用一张图示意如下:
我们需要牢牢记住一点:在Java中,任何对象的值都是存放在堆内存中的,而对象类型的变量对应的内存中保存的是对象的内存地址,我们称之为对象引用。因此new操作符返回的结果其实是一个引用。
我们可以显式的把一个对象变量设置为null,这时候该变量的内存存放的将是空值,表明它不引用任何对象。如果我们对一个值为null的变量进行方法调用,程序在运行时则会抛出异常。
4.2.4字符串拼接
在Java中,字符串的拼接有一种很简单的方法,就是用加号(+)连接两个字符串,结果会构造出一个新的字符串对象。我们看代码:
String a = "Java大失叔";String b = "喜欢打麻将";String c = a + b;System.out.println(c);// 结果将输出:"Java大失叔喜欢打麻将"
在这段代码中,堆内存中将会分配3块空间,分别对应字符串"Java大失叔"、"喜欢打麻将"、" Java大失叔喜欢打麻将"。我们用一张图来演示这个过程:
我们还可以将一个字符串和一个非字符串用+连接起来,这时候非字符串对象会被转换为字符串(具体如何转换,后续会详细探讨)。例如:
String a = "Java大失叔卡里只有";int b = 200;String c = "元钱了";System.out.println(a + b + c);// 结果将输出:Java大失叔卡里只有200元钱了
String类的API中还提供了一个方法concat用来拼接字符串,方法摘抄如下:
修饰和类型 |
方法 |
描述 |
String |
concat(String str) |
将str拼接在本字符串后面 |
使用起来也很简单,代码如下:
String a = "Java大失叔";String b = "喜欢打麻将";String c = a.concat(b);System.out.println(c);// 结果将输出:Java大失叔喜欢打麻将
有的时候,需要将很多个字符串拼接成一个大字符串,这时,如果用+的方式,不是很合适了。因为用+的方式,每次都会构建一个新的对象,比较耗时,还占内存,效率比较低。好在Java提供了另外一种方式,就是采用StringBuilder类和StringBuffer类。一般情况下我们都会采用StringBuilder类,因为它的效率略高。而Stringbuffer类是线程安全的,关于线程会在后面专门讨论。这2个类的API几乎完全一样。用StringBuilder非常简单,代码演示如下:
StringBuilder sb = new StringBuilder();// 首先构建StringBuilder对象sb.append("Java");// 然后用append方法添加小字符串sb.append("大失叔");sb.append("太帅了");String s = sb.toString();// 最后调用toString()方法,返回一个字符串对象System.out.println(s);// 结果将输出:Java大失叔太帅了
其实append方法返回的依然是StringBuilder对象,因此还可以采用一种更为简洁的方式:
String s = new StringBuilder().append("Java").append("大失叔").append("太帅了").toString();System.out.println(s);// 结果将输出:Java大失叔太帅了
关于加号、concat、StringBuilder这三者的比较,笔者给出如下结论:
对于拼接少量的字符串,用哪种方式都差不多,加号书写起来更加方便。笔者几乎没用过concat方法。
加号和StringBuilder都可以拼接非字符串类型(可以查看API,有很多个append方法)。
对于需要拼接多个字符串的时候,强烈建议使用StringBuilder。(笔者在早年编写一个网络程序的时候,吃过亏)
4.2.5字符串截取和比较
关于字符串还会经常使用比较和截取的方法,先列出方法如下:
修饰和类型 |
方法 |
描述 |
boolean |
startsWith(String prefix) |
检查字符串是否以指定的前缀prefix开始 |
boolean |
endsWith(String suffix) |
检查字符串是否以指定的后缀suffix结尾 |
String |
trim() |
删除字符串前后的空白,并返回一个新字符串 |
boolean |
equals(Object anObject) |
检测2个字符串是否相等 |
boolean |
equalsIgnoreCase(String anotherString) |
检测2个字符串在忽略大小写的情况下是否相等 |
String |
substring(int beginIndex) |
截取从beginIndex到末尾的字符串并返回 |
String |
substring(int beginIndex, int endIndex) |
截取从beginIndex到endIndex的字符串并返回,不包括endIndex |
我们经常会比较一个字符串是否以某个字符串开头或结尾,代码如下:
String a = "Java大失叔";boolean b1 = a.startsWith("Java");// 结果为trueboolean b2 = a.startsWith("java");// 结果为falseboolean b3 = a.endsWith("叔");// 结果为true
有时候,经过网络传输后的字符串经常前后会带一些空白,眼睛又看不见,很不利于比较,会用trim方法去掉前后的空白:
String a = " Java大失叔 ";String b = a.trim();System.out.println(b);// 结果将输出:Java大失叔
需要注意,这里的空白指的是Unicode编码小于或等于”\u0020”的字符。
对于字符串的截取,用subString方法将非常方便:
String a = "Java大失叔 ";String b = a.substring(4);// 结果是:大失叔String c = a.substring(2, 6);// 结果是:va大失
这里要注意的是,返回的结果字符串是包括beginIndex位置的代码单元,但是不包括endIndex位置的代码单元。
比较2个字符串是否相等,用equals方法,如果相等返回ture,否则返回false。如果想不区分大小写比较是否相等,则可以使用equalsIgnoreCase方法。表达式为:
a.equals(b)
其中,a和b即可以是变量,也可以是字符串常量。
String a = "Java大失叔";String b = "java大失叔";System.out.println(a.equals(b));// 结果为falseSystem.out.println(a.equalsIgnoreCase(b));// 结果为trueSystem.out.println("JAVA大失叔".equalsIgnoreCase(b));// 结果为true
这里需要特别注意,千万不能用==运算符来比较2个字符串是否相等。因为==运算符比较的是2个字符串是否存放在同一个内存位置上。但是事实上,对于2个字符内容完全一样的字符串,是很有可能存放在不同的内存空间的,因此用==比较结果将为false。这个问题Java新手经常会犯。
最后我们很容易发现,String的API中没有提供修改字符串内容的方法。这其实是因为String类被定义为final的(关于final后面也会介绍),我们看一下String的源代码(在Eclipse中,可以很轻松的查看源代码,鼠标移动的任意一个String字符上,按住Ctrl键后,点击鼠标左键):
public final class String implements java.io.Serializable, Comparable<String>, CharSequence
用final修饰一个类后,这个类的对象将不能被修改。
String类提供了50个多个方法,这些方法都很有用,但是我们不可能记住所有的方法名和参数要求,这里还有一个Eclipse的小技巧,当我们敲完变量名加“点”后,Eclipse会自动弹出提示,或者还可以用Ctrl+/自动补全,如下图:
c++ char 转 string_4.2String类相关推荐
- char数组转string_String类和其它数据类型的相互转换
对于上面的这些包装类,除了Character以外,都有可以直接使用字符串参数的构造函数,这也就使得我们将String类转换为这些数据类型变得相当之简单,即: Boolean(String s).Int ...
- java 调用弗雷_JAVA API(一)String类和StringBuffer类
1.String类和StringBuffer类 在程序中经常会用到字符串,所谓的字符串就是指一连串的字符,它是由多个单个字符连接而成的.字符串中可以包含任意字符,这些字符必须包含在一对双引号" ...
- 菜鸟学JAVA之——常用类(StringBuffer、StringBuilder、Comparable、Comparator等)
文章目录 常用类 字符串相关的类 一.String类及常用方法 二.StringBuffer.StringBuilder JDK 8 之前的日期时间API 一.System静态方法 二.Date类 三 ...
- 【String类和标准模板库】
1.string类 2.智能指针模板类 3.标准模板库 4.泛型编程 5.函数对象 6.算法 7.其他库 1.string类 string类是由头文件string支持的,要使用类,关键要知道它的公有接 ...
- 第二次预习——java异常类和常用类 容器
文章目录 一.异常类 1.概念 2.异常类分类 2.1分类 2.2Error与Exception的区别 2.3Java中常见运行时异常 3.try-catch语句 3.1用法 3.2语句 3.3实例 ...
- 《C++中STL引入和string类常用接口+自我实现-》
前言 在这篇博客里将详细说说C++中的STL,通过这篇我们可以学习到什么是STL,以及STL的六大组件,STL具有的缺陷,最后看看string类及面试会让模拟实现string类的操作. 文章目录 前言 ...
- 七:Object:常用类
七:Object:常用类 7.1克隆方法clone() 格式: 类名.clone(); protected Object clone() throws CloneNotSupportedExcepti ...
- java笔记——Java常用类
目录 目录 Java常用类目标 1.1内部类 1.2成员内部类 1.3静态内部类 1.4匿名内部类 2.Object类 2.1getClass()方法 2.2hasCode() 2.3toString ...
- 第11-15章枚举|异常|常用类|集合|泛型
文章目录 第11章 枚举和注解 11.1举例 11.2枚举的二种实现方式 11.3enum 实现接口 11.4注解的理解 11.4基本的 Annotation 介绍 第12章 异常-Exception ...
最新文章
- quartz与c3p0冲突
- 白话Elasticsearch20-深度探秘搜索技术之使用rescoring机制优化近似匹配搜索的性能
- 深入理解 python 中的赋值、引用、拷贝、作用域
- AOP 中必须明白的概念-切入点(Pointcut)
- CNN结构:SPP-Net为CNNs添加空间尺度卷积-神经元层
- Array的sort方法
- 蓝桥杯2017初赛-迷宫-dfs
- python的仿真效果好吗_Python SimPy 仿真系列 (1)
- linphone-android移植
- SimpleDet: 一套简单通用的目标检测与物体识别框架
- Kafka学习之(四)PHP操作Kafka
- Centos7搭建maven私服nexus3,互联网大厂100道Java面试题助你冲关金三银四
- n6 tenda 固件_腾达 Tenda N6 刷 TTDW 说明
- Android ADB 环境变量配置
- android 涨潮动画加载_潮汐apk客户端-潮汐android最新版APP下载v2.0.1.1 免费版-腾牛安卓网...
- 通过ajax获取对象后动态插入文本框
- 内存颗粒位宽和容量_SDRAM内存模组的物理Bank与芯片位宽(高手进阶,终极内存技术指南——完整/进阶版)...
- 数据结构与算法 python版 之 递归三定律
- 常用的几种设计模式详解
- 100道Java并发和多线程面试题
热门文章
- iis只能访问html页面,win2003 IIS6,能访问html页 但是不能访问aspx页解决办法汇总
- oracle判断数据表的字段内容是否为空
- android+mysql+server+error_Lost connection to MySQL server during query错误 | 学步园
- php7.0康乐安装_Linux环境PHP7.0安装
- python文件输出中文_【python】中文的输出,打印,文件编码问题解决方法
- Springboot整合RabbitMq-用心看完这一篇就够了(最新)
- c 和 java 差异_java和C/C++的差异是什么
- 电脑怎么下mcjava版_游戏下载常见问题(苹果、电脑玩家下载须知)
- 涉密计算机格式化维修,涉密计算机的涉密信息被删除或格式化后,通过一定的技术手段仍可以复原,连接互联网易造成泄密。()...
- 【Zabbix】使用dbforbbix 2.2-beta监控Redhat 7.0上的Oracle、Mysql