字符串、日期

  • 字符串(String)
    • 字符串常量池(String Constant Pool)
    • 字符串的初始化
    • intern 方法
    • 字符串的常用方法(截取)
  • 可变字符串(StringBuilder)
    • StringBuilder 的 append 原理
  • 日期
    • Date
    • SimpleDateFormat
    • Calendar
      • 打印格式化(很少用)

Java笔记目录可以点这里:Java 强化笔记

字符串(String)

Java 中用 java.lang.String 类代表字符串:

  • Java 9 以前,底层使用 char[] 存储字符数据
    从 Java 9 开始,底层使用 byte[] 存储字符数据
  • 所有字符串字面量(比如 "abc" )都是 String 类的实例
  • String 对象一旦创建完毕,它的字符内容不可以修改

首先来看一段代码:并思考一下这段代码的输出是否与你想的不一样。

public class Main {public static void main(String[] args) {String s = "555";s += "555";s = "666";test(s);System.out.println(s); // 666}static void test(String str) {str += "555";}
}

String s = "555";s += "555";s = "666" 等操作都会在堆空间开辟一块新的内存空间,因为 String 是不可变字符串,每次要修改栈空间的变量sstr的值,只能改变它的指针指向,令指针指向堆空间新的内存。

我们知道,成员变量、函数形参等都是开辟在栈空间的(因为随时可能销毁),而上面代码中的 sstr 实际上在栈空间不是同一块布局,test 方法修改的是 str 的指向的值,所以 s 的值不会变。

字符串常量池(String Constant Pool)

Java 中有个字符串常量池(String Constant Pool,简称 SCP)

  • 从 Java 7 开始属于堆空间的一部分(以前放在方法区)

当遇到字符串字面量时,会去查看 SCP

  • 如果 SCP 中存在与字面量内容一样的字符串对象 A 时,就返回 A
  • 否则,创建一个新的字符串对象 D,并加入到 SCP 中,返回 D
String s1 = "mj"; // SCP中不存在字符串对象"mj"
String s2 = "mj"; // SCP中存在字符串对象"mj", 直接返回SCP中的"mj"
// 因此上面两个字符串对象是同一个对象
System.out.println(s1 == s2); // true

字符串的初始化

在 C语言里,字符数组就是字符串;在 Java 中,String 底层是由 char[] 组成的,但是他们不完全是一个东西。

利用 Java 的断点调试功能来验证上图:右半部分中的表示不是真实的内存地址,但是可以理解为标识不同则内存地址不同,相同则内存地址相同。可以看到 s1s2s3s4css5s6 的标识都是不同的;但是 s1s2s3s4 指向的value 的标识都是30,与上图展示的一致;s5s6 指向的value 的标识都是31。

intern 方法

A.intern 方法的作用:

  • 如果 SCP 中存在与 A 内容一样的字符串对象 C 时,就返回 C
  • 否则,将 A 加入到 SCP 中,返回 A
int a = 1, b = 2, c = 3;
String s1 = String.format("%d%d%d", a, b, c);
String s2 = String.format("%d%d%d", a, b, c);
// 去常量池中寻找"123", 发现没有, 就将s1的值"123"放入常量池
String s3 = s1.intern(); // s3、s1都指向了常量池中的"123"
String s4 = s2.intern(); // 返回常量池的"123"
String s5 = "123"; // s5指向常量池中的"123"System.out.println(s1 == s2); // false
System.out.println(s1 == s3); // true
System.out.println(s1 == s4); // true
System.out.println(s1 == s5); // true

字符串的常用方法(截取)

// 去除左右的空格: "123  456"
" 123  456  ".trim();// 转为大写字母: "ABC"
"abc".toUpperCase();
// 转为小写字母: "abc"
"ABC".toLowerCase();// 是否包含某个字符串: true
"123456".contains("34");
// 是否以某个字符串开头: true
"123456".startsWith("123");
// 是否以某个字符串结尾: true
"123456".endsWith("456");// 将字符串分隔为数组: [1, 2, 3, 4]
"1_2_3_4".split("_");// 比较字符串的大小: <
"abc".compareTo("adc");
// 忽略大小写比较字符串的大小: <
"abc".compareTo("ADC");String s1 = "abc";
String s2 = new String("abc");
// 查看字符串的内容是否相等: true
s1.equals(s2);
// 忽略大小写查看字符串的内容是否相等: true
"abc".equalsIgnoreCase("ABC");// 字符串的替换
String str = "hello123";
// 由于String是不可变字符串, 必须用变量接收
str = str.replace("123", "666"); // hello666

穿插个知识点,Eclipse 中 抽取代码块的快捷键:先选中代码块,ALT + SHIFT + M

字符串截取

String str = "abcdea";
// 字符串的截取区间: [2, 4)
str.substring(2, 4);  // cd
str.substring(2);     // cdeastr.indexOf("a");      // 0
str.lastIndexOf("a"); // 5
str.indexOf("z");     // -1

可变字符串(StringBuilder)

在进行大量字符串的改动操作时(比如拼接、替换)

  • 使用 String 会非常消耗内存、降低程序性能
  • 使用 StringBuilder 可以节省内存、提高程序性能
String s1 = "";
s1 += "123";
s1 += "456";StringBuilder s2 = new StringBuilder();
s2.append("123").append("456");

StringStringBuilder 性能对比:50000 次字符串拼接操作

public static void main(String[] args) {testString();    // 2511mstestStringBuilder(); // 2ms
}static void testString() {long begin = System.currentTimeMillis();String str = "";for (int i = 0; i < 50000; i++) {str += i;}long end = System.currentTimeMillis();System.out.println("String ->" + (end - begin) + "ms");
}
static void testStringBuilder() {long begin = System.currentTimeMillis();StringBuilder str = new StringBuilder();for (int i = 0; i < 50000; i++) {str.append(i);}long end = System.currentTimeMillis();System.out.println("StringBuilder ->" + (end - begin) + "ms");
}
String -> 2511ms
StringBuilder -> 2ms

StringBuilder 的常用方法有:appendinsertdeletereplacereverse等;

注意:

  • StringBuilder 并不是 String 的子类 或者 父类
  • StringBuilderString 都实现了 CharSequence 接口

StringBuilder 的 append 原理

StringBuilder 的原理类似动态数组 ArrayList:底层会自动扩容;

源码中可以看到扩容的算法:(value.length << 1) + 2 即 新容量是原来容量的 2 倍 + 2

日期

Date

java.util.Date 是开发中经常用到的日期处理类(注意:不是 java.sql.Date

  • 包含了年、月、日、时、分、秒等信息
// date1 代表当前时间
Date date1 = new Date();
// System.currentTimeMillis 表示 1970-01-01 00:00:00 GMT 到现在时间的毫秒数
// date2 也代表当前时间
Date date2 = new Date(System.currentTimeMillis());
// date3 代表 1970-01-01 00:00:00 GMT
Date date3 = new Date(0);// Mon Apr 20 13:44:49 CST 2020
System.out.println(date1);
// Mon Apr 20 13:44:49 CST 2020
System.out.println(date2);
// Thu Jan 01 08:00:00 CST 1970
System.out.println(date3);

System.currentTimeMillis 返回的是从 1970-01-01 00:00:00 GMT 开始到现在经历的毫秒数

  • 1970-01-01 00:00:00 GMT、1970-01-01 08:00:00 CST 代表的是同一个时间

    • GMT(Greenwich Mean Time):格林尼治时间
    • CST(China Standard Time UT+8:00):中国标准时间

Date 常用方法:

Date d1 = new Date();
Date d2 = new Date();// 设置毫秒数, d1比d2早(d2经历的时间比d1大)
d1.setTime(1000);
d2.setTime(2000);// 获取毫秒数
d1.getTime(); // 1000
d2.getTime(); // 2000// 比较时间
d2.after(d1);  // true
d1.before(d2); // true
d1.compareTo(d2); // -1(d2经历的时间比d1大)

SimpleDateFormat

java.text.SimpleDateFormat 常用来进行日期的格式化处理

SimpleDateFormat fmt = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
// 利用日期对象生成字符串
String str = fmt.format(new Date());
// 2020年04月20日 13:57:13
System.out.println(str); // 解析字符串为日期对象
Date date = fmt.parse(str);
// Mon Apr 20 13:57:13 CST 2020
System.out.println(date);

SimpleDateFormat 的模式字母:

Calendar

java.util.Calendar 也是开发中经常用到的日期处理类

  • 功能比 Date 更加丰富,Date 中很多过期的方法都迁移到了 Calendar

示例:目前是 2020年4月20日 星期一 下午 14:16:33

// 表示当前时间
Calendar c = Calendar.getInstance();
c.getTime(); // Mon Apr 20 14:16:33 CST 2020c.get(Calendar.YEAR); // 年: 2020// 月(取值范围[0, 11], 0是1月, 11是12月)
c.get(Calendar.MONTH); // 3// 一月中的第几天(取值范围[1, 31])
c.get(Calendar.DAY_OF_MONTH); // 20// 一周中的第几天(取值范围[1, 7], 1是星期天, 2是星期一...,7是星期六)
c.get(Calendar.DAY_OF_WEEK); // 2// 一年中的第几天(取值范围[1, 366])
c.get(Calendar.DAY_OF_YEAR); // 111c.get(Calendar.HOUR);   // 时: 2
c.get(Calendar.MINUTE); // 分: 16
c.get(Calendar.SECOND); // 秒: 33
c.get(Calendar.MILLISECOND); // 毫秒: 330

Calendar 的常用方法:

Calendar c = Calendar.getInstance();
// 设置时间为 2019年7月6日
c.set(2019, 06, 06);
// 2019年7月11日
c.add(Calendar.DAY_OF_MONTH, 5);
// 2019年9月11日
c.add(Calendar.MONTH, 2);// 设置Date对象
c.setTime(new Date());
// 获得Date对象
c.getTime();// 设置毫秒数
c.setTimeInMillis(System.currentTimeMillis());
// 获得毫秒数
c.getTimeInMillis();

打印格式化(很少用)

// 获取当前时间
Calendar c = Calendar.getInstance();
Date date = new Date();System.out.format("%tB %te, %tY%n", date, date, date); // 四月 20, 2020
System.out.format("%tl:%tM %tp%n", c, c, c); // 2:24 下午
System.out.format("%tD%n", c); // 04/20/20

【Java 基础】字符串(String、StringBuilder),日期(Date、SimpleDateFormat、Calendar)相关推荐

  1. java基础-字符串String

    今天要介绍的知识点为String,也叫字符串.这是个应用的比较广泛并且充满神奇色彩的知识点.为什么说神奇呢?因为它涉及了好些个看起来高深莫测的概念.并且,这个知识点其实已经属于java中引用类型的知识 ...

  2. Java基础之String,StringBuilder,StringBuffer三者的区别

    Java基础之String,StringBuilder,StringBuffer三者的区别 目录 运行速度方面 线程安全方面 小结 1. 运行速度方面 运行速度,在这方面运行速度快慢为:StringB ...

  3. bytes数组转string指定编码_好程序员Java学习路线分享Java基础之string

    好程序员Java学习路线分享Java基础之string 好程序员Java培训 先来讲一下字符串 字串符分类: 不可变字符串:----String.字符串本身不能发生改变,与指向字符串的引用无关. St ...

  4. Java基础:String类

    相关阅读 Java基础:String类 Java字符串格式化 Java基础:正则表达式 1. 概述 字符串是由多个字符组成的一串数据(字符序列),字符串可以看成是字符数组. 在实际开发中,字符串的操作 ...

  5. Java基础之String深入解析

    Java基础之String深入解析 以下是本文目录大纲 生成地方和地址指向,intern()方法 String可否被继承? 1. 生成地方和地址指向,intern()方法 先看代码 String s1 ...

  6. Java常量字符串String理解

    Java常量字符串String理解 以前关于String的理解仅限于三点: 1.String 是final类,不可继承 2.String 类比较字符串相等时时不能用" == ",只 ...

  7. 新手小白学JAVA 日期类Date SimpleDateFormat Calendar

    1. Date日期类 类 Date 表示一个特定的瞬间,精确到毫秒 1.1 Date的构造函数 Date() 分配一个 Date 对象,以表示分配它的时间(精确到毫秒) Date(long date) ...

  8. [JAVA基础类库] String类 ○ StringBuffer类 ○ StringBuilder类

    引言 字符串就是一连串的字符序列,Java提供了String.StringBuffer和StringBuilder三个类来封装对字符串,并提供了系列方法来操作字符串对象. String类是不可变类的: ...

  9. Java基础篇(04):日期与时间API用法详解

    本文源码:GitHub·点这里 || GitEE·点这里 一.时间和日期 在系统开发中,日期与时间作为重要的业务因素,起到十分关键的作用,例如同一个时间节点下的数据生成,基于时间范围的各种数据统计和分 ...

  10. Java基础 时间相关类小结[Timestamp,Date,Calendar]

    Java基础 时间相关类[Timestamp,Date,Calendar] 前言 一.Timestamp(时间戳) 二.Date(日期) 三.Calendar(日历) 四.Timestamp.Date ...

最新文章

  1. 包 java中导入awt_Java 查找并高亮显示PDF文本
  2. Pycharm 修改tab缩进快捷键
  3. 微信小程序 遇到问题1
  4. HDFS修改副本数并生效
  5. jQuery给输入框绑定键盘事件
  6. Boost:双图bimap与property地图的测试程序
  7. Opencv--cvSetImageROI和cvResetImageROI的使用
  8. js 值类型和引用类型
  9. 微信客户端电脑版_【电脑】微信客户端数据自动删除工具 再也不用担心电脑内存了...
  10. Bzoj2882 工艺
  11. 火狐浏览器怎么支持html5,支持HTML5/CSS技术火狐浏览器8
  12. Hibernate validator 官网前言中文版
  13. Java file outside of source root
  14. 基于VUE和Node.js的医院挂号预约管理系统
  15. 代号SXH-JS-1
  16. css强制换行和超出隐藏实现(单行和多行)
  17. U盘数据被格式化怎么办,U盘格式化数据如何恢复?
  18. 使用tkinter实现猜数字游戏
  19. python爬虫天猫商品数据及分析(4)
  20. Talib技术因子详解(四)

热门文章

  1. 在React和Vue中支持服务器端呈现
  2. 为什么感觉每年手机都在升级CPU,但始终都会卡顿?
  3. 听力技巧-4大难点讲析
  4. 利用MFC向导生成单文档应用程序框架
  5. SqlServer中 查询语句 case when 用法
  6. 【[Violet]樱花】
  7. 057 Java中kafka的Producer程序实现
  8. 【bzoj1604】[Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 旋转坐标系+并查集+Treap/STL-set...
  9. 【记录】PS立体透明字效果
  10. script中的event和for的意思