字符串介绍

String类是java.lang包中的一个类,是我们日常中使用的非常多的一个类,它不是基础数据类型,底层实现是字符数组来实现的:

/** The value is used for character storage. */
private final char value[];

String类是由final修饰的,所以是无法被继承的,一旦创建了String对象,我们就无法改变它的值。因此,它是线程安全的,可以安全地用于多线程环境中。

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

下面我们通过几道面试题来学习String

如何创建一个字符串

一般来说有三种:

  • 通过new关键字通过构造方法去创建
  • 通过双引号“”
  • 通过字符串连接符+和其余字符串进行拼接创建

说说这几种的区别

  1. 当通过new关键字调用无参构造时,仅仅在JVM的堆内存中创建了一个对象

  2. 通过""创建对象的时候,如果字符串常量池存在该字符串,直接返回该字符串对象在字符串常量池的地址,否则创建一个新的字符串对象并存储在字符串常量池。

String s = new String("a") 创建了几个对象

当通过new关键字传入双引号字符串参数时,会先去把该双引号的字符串放入字符串常量池,然后遇到new以后会在堆中再次创建一个字符串对象,这里是创建了两个对象。

+ 的实现原理

String s1 = null;
String s2 = "abc";
System.out.println(s1 + s2);

借这道面试题来聊一下+的原理,这道题的答案是”nullabc“,也许会有些奇怪,但是当你了解了+的原理后也许就不会感到奇怪了,我们使用javap命令去看一下编译器那里把+编译成了什么?

我们在图中被红色框柱的部分可以看出,+的执行的过程其实就是先把 String转换成了StringBuilder后调用append方法完成拼接后再调用toString方法完成字符串的拼接。所以上面的代码也可以转换为

StringBuilder s1 = new StringBuilder(String.valueOf(null));
StringBuilder s2 = new StringBuilder("abc");
s1.append(s2).toString();

关于StringBuilder和StringBuffer

StringBufferStringBuilder 二者都继承了 AbstractStringBuilder ,底层都是利用可修改的char数组(JDK 9 以后是 byte数组)。两者的区别是StringBuilder是线程不安全的,而StringBuffer是线程安全的。性能上来说,StringBuilder要高于StringBuffer

在单线程情况下,如有大量的字符串操作情况,不能使用String来拼接而是使用,避免产生大量无用的中间对象,耗费空间且执行效率低下(新建对象、回收对象花费大量时间)。这时就需要用到我们的StringBuilder

而在多线程情况下,应当使用StringBuffer来保证线程的安全~

判空

在日常的开发中,我们经常会遇到判断字符串是否为空的需求,这里安利几个工具类中的写法:

// 来自apache下的lang3包中的StringUtils
import org.apache.commons.lang3.StringUtils
.... //这里是判断是否为null或为空
String s;
StringUtils.isNotEmpty(s); //这里是用于判断是否为null或为空,或空格,Tab这样的占用符
StringUtils.isNotBlank(s);

是否相等

关于两个字符串是否相等,我用的最多的是java.util包下的Objects类中的方法 ,实现方法如下:

public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}

用法也很简单:

Objects.equals(a,b);

公众号

Java 基础(四):数组的更多相关文章

  1. Java基础(四) StringBuffer、StringBuilder原理浅析

    StringBuilder与StringBuffer作用就是用来处理字符串,但String类本身也具备很多方法可以用来处理字符串,那么为什么还要引入这两个类呢? 关于String的讲解请看Java基础 ...

  2. Java基础-反转数组

    /** java基础,如何将一个数组反转,思考方法采用使用临时变量的情况下,将第一个元素与第二个元素进行反转,需要定义两个索引,一个记录数组的第一个元素与最后一个元素,将其两两交换* */public ...

  3. Java基础之 数组详解

    前言:Java内功心法之数组详解,看完这篇你向Java大神的路上又迈出了一步(有什么问题或者需要资料可以联系我的扣扣:734999078) 数组概念 同一种类型数据的集合.其实数组就是一个容器. 数组 ...

  4. java基础(十) 数组类型

    1. 数组类简介   在java中,数组也是一种引用类型,即是一种类. 我们来看一个例子,理解一下数组类: public static void main(String[] args) { Class ...

  5. java 基础概念 -- 数组与内存控制

    问题1: Java在声明数组的过程中,是怎样分配内存的? 在栈内存中 建一个数组变量,再在堆内存中 建一个 数组对象.至于详细的内存分配细节,还得看 该初始化是 数组动态初始化 还是 数组静态初始化. ...

  6. Java基础:数组的声明,循环,赋值,拷贝。

    数组的声明 一般有两种形式的声明: int[] a; int a[]; 这两种声明都没错,但是大多数都使用第一种声明,因为变量名是独立的,不带任何符号. 声明一个数组,并没有将a真正的初始化为一个数组 ...

  7. java 基础 四种权限修饰符

    /** * Java有四种权限修饰符: * public > protected > (default) > private * 同一个类 YES YES YES YES * 同一个 ...

  8. Java基础四(switch、数组、)

    1.流程控制语句switch2.数组3.随机点名器案例 ###01switch语句解构 * A:switch语句解构 * a:switch只能针对某个表达式的值作出判断,从而决定程序执行哪一段代码. ...

  9. 黑马程序员——JAVA基础之数组

    ------- android培训.java培训.期待与您交流! ---------- 数组: 数组的定义: 数组是相同类型数据的集合, 描述的是相同类型的若干个数据按照一定的先后顺序排列组合而成,其 ...

  10. Java基础总结--数组

    ---数组的定义---组织存储一组数据1.存放相同类型数据的集合--就是一种容器本质上变量也是一种容器--区别就是只存储了一个数据的容器--面对容器,而不是分散的数据eg.买一盘鸡蛋--蛋托其实就是容 ...

随机推荐

  1. git获取公钥和私钥以及常用的命令

    Git简单生成公钥和私钥的方法 Git安装完之后,需做最后一步配置.打开git bash,分别执行以下两句命令 git config --global user.name “用户名” git conf ...

  2. JDBC原理之层次结构

    目录 JDBC的层次结构 前言 Collection角色 Statement角色 ResultSet角色 JDBC工作的基本流程 JDBC的层次结构 前言 JDBC API提供了以下接口和类: Dri ...

  3. hadoop datanode 启动正常,但master无法识别(50030不显示datanode节点)

    start-all.sh 启动 坑爹 找不出错 试了各种办法,重新formaet 查看 集群ID是否相同.都无效 日志也没看到错 按官网方法手动一步步启,问题照旧 master节点,yarn name ...

  4. async样例

    function iniProcessDetail(isjob) { var cursor = logColl.find({}).sort({ip: 1}); var insertbolk = []; ...

  5. Python:扫描目录下的所有文件

    扫描目录下的所有文件并返回文件的绝对路径 def fileListFunc(filePathList): fileList = [] for filePath in filePathList: for ...

  6. Linux主机下如何查询自己使用的公网IP

    curl http://members.3322.org/dyndns/getip 可以解析出自己是使用哪个公网IP访问外网的

  7. ssm框架下怎么批量删除数据?

    ssm框架下批量删除怎么删除? 1.单击删除按钮选中选项后,跳转到js函数,由函数处理 2. 主要就是前端的操作 js 操作(如何全选?如何把选中的数据传到Controller中) 3.fun()函数 ...

  8. makefile(3)函数

    前言 学习make和makefile的主要目的是分析大型项目的源代码的关系,上一节我们讲述了makefile 中的变量,本节主要学习一下 makefile 中的函数,首先函数肯定可以分为几部分: 内置 ...

  9. iptables学习02-nat表应用

    nat表应用实验 第一步 准备工作 A机器两块网卡ens33(192.168.2.106).再添加一块自定义网卡ens37(192.168.100.1),添加到LAN内网区段(自定义名字,写什么无所谓 ...

  10. Alberto Del Bimbo:为什么说研究员要有想象力?

    ​ Del Bimbo:为什么说研究员要有想象力?" title="Alberto Del Bimbo:为什么说研究员要有想象力?"> ​ 说到科研,与日本式的&q ...