您好,登录后才能下订单哦!
小编这次要给大家分享的是JDK9中如何实现String压缩和字符编码,文章内容丰富,感兴趣的小伙伴可以来了解一下,希望大家阅读完这篇文章之后能够有所收获。
简介
String的底层存储是什么?相信大部分人都会说是数组。如果要是再问一句,那么是以什么数组来存储呢?相信不同的人有不同的答案。
在JDK9之前,String的底层存储结构是char[],一个char需要占用两个字节的存储单位。
据说是JDK的开发人员经过调研了成千上万的应用程序的heap dump信息,然后得出了一个结论:大部分的String都是以Latin-1字符编码来表示的,只需要一个字节存储就够了,两个字节完全是浪费。
据说他们用了大数据+人工智能,得出的结论由不得我们不信。
于是在JDK9之后,字符串的底层存储变成了byte[]。
底层实现
先看下java9之前的String是怎么实现的:
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { //The value is used for character storage. private final char value[]; }
再看下java9中String的实现和一些关键的变量:
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /** The value is used for character storage. */ @Stable private final byte[] value; private final byte coder; @Native static final byte LATIN1 = 0; @Native static final byte UTF16 = 1; static final boolean COMPACT_STRINGS; static { COMPACT_STRINGS = true; }
从代码我们可以看到底层的存储已经变成了byte[]。
再看一下coder变量,coder代表编码的格式,目前String支持两种编码格式LATIN1和UTF16。
LATIN1需要用一个字节来存储。而UTF16需要使用2个字节或者4个字节来存储。
而COMPACT_STRINGS则是用来控制是否开启String的compact功能。默认情况下COMPACT_STRINGS功能是开启的。
如果我们想关闭COMPACT_STRINGS功能则可以使用-XX:-CompactStrings参数。
ps:下面看下jdk8日期格式化的实例代码
package time; import java.time.*; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.Calendar; import java.util.Date; /*** * 总结: java.util.Date和 SimpleDateFormat 都是非线程安全的 * 1. LocalDate * 2. LocalTime * 3. LocalDateTime * 4. DateTimeFormatter * 5. ChronoUnit */ public class Java8Date { public static void main(String[] args) { /** #0. Calendar * 区别于calendar的month: canlendar中:[] * 1. LocalDate的年月日直接是日期中的值; * 2. date.getMonthValue() 和 c.get(Calendar.MONTH) 有区别: c:0表示1月 */ Calendar c = Calendar.getInstance(); // 测试日期:2019-04-02 System.out.println(c.get(Calendar.YEAR)); // 2019 System.out.println(c.get(Calendar.MONTH)); // 3(0=1月) System.out.println(c.get(Calendar.DAY_OF_MONTH)); //2 // #1. LocalDate 2019-04-02 : 今日日期: LocalDate.now() System.out.println("=-==-==-==-==-==-==-==-==-==-=="); LocalDate date = LocalDate.now(); System.out.println(date); // 2019-04-02 // #2. year month day: 年月日获取 System.out.println("=-==-==-==-==-==-==-==-==-==-=="); int year = date.getYear(); // 2019 int month = date.getMonthValue();// 4 int day = date.getDayOfMonth(); // 2 System.out.println(year + "-" + month + "-" + day); // 2019-4-2 // #3. 构造日期: 给定年月日 System.out.println("=-==-==-==-==-==-==-==-==-==-=="); LocalDate dt1 = LocalDate.of(2019, 3, 8); LocalDate dt2 = LocalDate.of(2019, 3, 8); // #4. 日期比较: equals // true: 内部是比较的 year-year month-month day-day System.out.println(dt2.equals(dt1)); // #5. 周期性日期, 比如: 判断用户的生日 System.out.println("=-==-==-==-==-==-==-==-==-==-=="); // 生日:0308 MonthDay uBirth = MonthDay.of(3, 8); MonthDay dtMD = MonthDay.from(dt1); // dt1 是不是 用户u的生日:true System.out.println("dt1==用户u的生日:" + dtMD.equals(uBirth)); // #6. 获取当前时间 [HH:mm:ss.SSS] System.out.println("=-==-==-==-==-==-==-==-==-==-=="); LocalTime time = LocalTime.now(); System.out.println(time); // #7. 增减时间 plus/minus System.out.println("=-==-==-==-==-==-==-==-==-==-=="); // dt1=2019-03-08 LocalDate dt1Plus2d = dt1.plusDays(2); LocalDate dt1Plus2y = dt1.plusYears(2); LocalDate dt1Plus2m = dt1.plusMonths(2); System.out.println(dt1Plus2d); // 2019-03-10 System.out.println(dt1Plus2y); // 2021-03-08 System.out.println(dt1Plus2m); // 2019-05-08 // dt1=2019-03-08 LocalDate plus1w = dt1.plus(1, ChronoUnit.WEEKS); LocalDate plus1d = dt1.plus(1, ChronoUnit.DAYS); LocalDate plus18y = dt1.plus(18, ChronoUnit.YEARS); LocalDate minus1y = dt1.minus(1, ChronoUnit.YEARS); System.out.println(plus1w); // 2019-03-15 System.out.println(plus1d); // 2019-03-09 System.out.println(plus18y); // 2037-03-08 System.out.println(minus1y); // 2018-03-08 // #8. 日期dt1 早于/晚于 minus1y System.out.println("=-==-==-==-==-==-==-==-==-==-=="); // dt1=2019-03-08 minus1y=2018-03-08 System.out.println(dt1.isAfter(minus1y)); // true System.out.println(dt1.isBefore(minus1y)); // false // #9. 计算日期差 System.out.println("=-==-==-==-==-==-==-==-==-==-=="); // dt1=2019-03-08 dt20190402 LocalDate dt20190402 = LocalDate.of(2019, 4, 2); Period btPeriod = Period.between(dt1, dt20190402); Period btPeriod2 = Period.between(dt1, dt20190402); System.out.println(btPeriod); // P25D System.out.println(btPeriod.getMonths()); // 0 System.out.println(btPeriod.getDays()); // 25 // 25 可见是标量, 不是矢量, 只计算差数 System.out.println(btPeriod2.getDays()); // #10. 时间戳Instant->java.util.Date[getTime()==toEpochMilli()] System.out.println("=-==-==-==-==-==-==-==-==-==-=="); Instant now = Instant.now(); // 2019-04-02T08:48:46.755Z Date dtNow = Date.from(now); // Tue Apr 02 16:48:46 CST 2019 long millisInstant = now.toEpochMilli(); long millisDate = dtNow.getTime(); System.out.println(millisInstant); // 1554195038598 System.out.println(millisDate); // 1554195038598 // #11# ** 日期格式化 System.out.println("=-==-==-==-==-==-==-==-==-==-=="); DateTimeFormatter pattern1 = DateTimeFormatter.ofPattern("yyyyMMdd-HH:mm:ss,SSS"); DateTimeFormatter pattern2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); /** * 命题:--> 将 "20190215-22:10:30,333" 日期 * 格式化为 "yyyyMMdd-HH mm:ss.SSS" 字符串 * @.1. 字符串转对象LocalDateTime * @.2. LocalDateTime对象转字符串 */ String strDt = "20190215-22:10:30,333"; // @.1. LocalDateTime dateTime = LocalDateTime.parse(strDt, pattern1); String fmtDtString = dateTime.format(pattern2); // @.2. System.out.println(dateTime); // 2019-02-15T22:10:30.333 System.out.println(fmtDtString); // 2019-02-15 22:10:30 System.out.println("=-==-==-==-==-==-==-==-==-==-=="); } }
看完这篇关于JDK9中如何实现String压缩和字符编码的文章,如果觉得文章内容写得不错的话,可以把它分享出去给更多人看到。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。