01_java字符串常量池
58同城的java字符串常量池
面试题代码
public class StringPools58Demo {public static void main(String[] args) {/*(1).str1str1 会有4个对象一个StringBuilder、一个58 ldc、一个tongcheng ldc、String这个时候常量池中没有58tongcheng这个ldc在str1.intern():在jdk7后,会看常量池中是否存在,如果没有,它不会创建一个对象,如果堆中已经这个字符串,那么会将堆中的引用地址赋给它所以这个时候str1.intern()是获取的堆中的* */String str1=new StringBuilder("58").append("tongcheng").toString();System.out.println(str1);System.out.println(str1.intern());System.out.println(str1==str1.intern());//trueSystem.out.println();/*sum.misc.Version类会在JDK类库的初始化中被加载并初始化,而在初始化时它需要对静态常量字段根据指定的常量值(ConstantValue)做默认初始化,此时sum.misc.Version.launcher静态常量字段所引用的"java"字符串字面量就被intern到HotSpot VM的字符串常量池 - StringTable里了str2对象是堆中的str.intern()是返回的是JDK出娘胎自带的,在加载sum.misc.version这个类的时候进入常量池*/String str2=new StringBuilder("ja").append("va").toString();System.out.println(str2);System.out.println(str2.intern());System.out.println(str2==str2.intern());//false}
}
讲解
intern()方法
/*** Returns a canonical representation for the string object.* * A pool of strings, initially empty, is maintained privately by the* class {@code String}.*
* When the intern method is invoked, if the pool already contains a* string equal to this {@code String} object as determined by* the {@link #equals(Object)} method, then the string from the pool is* returned. Otherwise, this {@code String} object is added to the* pool and a reference to this {@code String} object is returned.*
* It follows that for any two strings {@code s} and {@code t},* {@code s.intern() == t.intern()} is {@code true}* if and only if {@code s.equals(t)} is {@code true}.*
* All literal strings and string-valued constant expressions are* interned. String literals are defined in section 3.10.5 of the* The Java™ Language Specification.** @return a string that has the same contents as this string, but is* guaranteed to be from a pool of unique strings.*/
public native String intern();
说明:
(1). 如果不是用双引号声明的String对象,可以使用String提供的intern方法: intern方法会从字符串常量池中查询当前字符串是否存在,若不存在就会将当前字符串放入常量池中
(2). 比如: String myInfo = new String(“I love u”).intern();
也就是说,如果在任意字符串上调用String. intern方法,那么其返回结果所指向的那个类实例,必须和直接以常量形式出现的字符串实例完全相同。因此,下 列表达式的值必定是true:
(“a” + “b” + “c”).intern()== “abc”;
(3). 通俗点讲,Interned String就是确保字符串在内存里只有一份拷贝,这样可以节约内存空间,加快字符串操作任务的执行速度。注意,这个值会被存放在字符串内部池(String Intern Pool)
why
按照代码结果,java字符串答案为false,必然是两个不同的java,那另外一个java在哪里?
有一个初始化的java,在加载sun.misc.Version类的时候,包括一个java字符串。
OpenJDK8底层源码
②. 原因解释一(字节码):
String str1=new StringBuilder(“58”).append(“tongcheng”).toString();
这句话中常量池中是没有58tongcheng的 无ldc

③.原因解释二(深入OpenJDK8底层源码分析):
(sum.misc.Version类会在JDK类库的初始化中被加载并初始化,而在初始化时它需要对静态常量字段根据指定的常量值(ConstantValue)做默认初始化,此时sum.misc.Version .launcher静态常量字段所引用的"java"字符串字面量就被intern到HotSpot VM的字符串常量池 - StringTable里了)



考查点
intern()方法,判读true/false ? 《深入理解java虚拟机》是否读过。
字节跳动两数求和
面试题
提供力扣网址:https://leetcode-cn.com/problems/two-sum/

解法
使用暴力法和哈希解法:
/*题目:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
* */
public class TwoSumDemo {public static void main(String[] args) {int[]nums ={2, 7, 11, 15};int target = 9;//int[]indexCollection=twoSum1(nums,target);int[]indexCollection=twoSum2(nums,target);if(indexCollection!=null){for (int index : indexCollection) {System.out.print(index+" ");}}}//1.暴力法://通过双重遍历数组中所有元素的两两组合,当出现符合的和时返回两个元素的下标public static int[] twoSum1(int[] nums, int target) {for (int i = 0; i < nums.length; i++) {for (int j = i+1; j <nums.length ; j++) {if(target-nums[i]==nums[j]){return new int[]{i,j};}}}return null;}//2.哈希(更优解法)public static int[] twoSum2(int[] nums, int target){Map<Integer,Integer> map=new HashMap<>();for (int i = 0; i < nums.length; i++) {int param=target-nums[i];//2 7if(map.containsKey(param)){return new int[]{map.get(param),i};}map.put(nums[i],i);}return null;}
}
考查点
力扣网站上的算法
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
