我无法理解Java Constant Pool for Integer的工作原理.
我理解字符串的行为,因此能够证明自己与Integer Constants的情况相同.
所以,对于整数
Integer i1 = 127;
Integer i2 = 127;
System.out.println(i1==i2); // True
Run Code Online (Sandbox Code Playgroud)
&
Integer i1 = new Integer(127);
Integer i2 = new Integer(127);
System.out.println(i1==i2); // False
Run Code Online (Sandbox Code Playgroud)
直到这里,一切都在我的脑海里.
我无法消化的是,当我从127增加整数时,它的行为有所不同.这种行为在127之后发生变化,下面是代码片段
Integer i1 = 128;
Integer i2 = 128;
System.out.println(i1==i2); // False. WHY?????
Run Code Online (Sandbox Code Playgroud)
有人可以帮我理解吗?
public class Comparison {
public static void main(String[] args) {
String s = "prova";
String s2 = "prova";
System.out.println(s == s2);
System.out.println(s.equals(s2));
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
true
true
Run Code Online (Sandbox Code Playgroud)
在我的机器上.为什么?不应该==比较对象引用相等?
我了解到它来自魔鬼,==而不是测试字符串相等String.equals(),因为每个String都是对它自己的对象的引用.
但如果我使用类似的东西
System.out.println("Hello" == "Hello");
Run Code Online (Sandbox Code Playgroud)
它打印真实.
为什么?
好吧,这是愚蠢的,但wtf还在继续?
我在servlet中有一个String变量,它接受一个参数的值,并根据该值我做一个测试来做某事,但是if没有用.问题是什么?
String action = request.getParameter("action");
System.out.println("Action: " + action);
// I put 2 ifs to be sure, but not even one is working
if(action.equals("something"))
{
System.out.println("hey");
}
if(action.trim() == "something")
{
System.out.println("hey");
}
Run Code Online (Sandbox Code Playgroud)
在控制台上,System.out.println向我显示action的值是"某事"
Action: something
Run Code Online (Sandbox Code Playgroud) 我们知道,String().intern()如果字符串池中尚不存在,则在字符串池中添加字符串值.如果存在,则返回该值/对象的引用.
String str = "Cat"; // creates new object in string pool with same character sequence.
String st1 = "Cat"; // has same reference of object in pool, just created in case of 'str'
str == str1 //that's returns true
String test = new String("dog");
test.intern();// what this line of code do behind the scene
Run Code Online (Sandbox Code Playgroud)
我需要知道,当我打电话给test.intern()这个实习方法会做什么?
在字符串池中添加带有不同引用的"dog"或在字符串池中添加test对象引用(我认为,情况并非如此)?
我试过这个
String test1 = "dog";
test == test1 // returns false
Run Code Online (Sandbox Code Playgroud)
我只是想确保,当我调用test.intern()它时,在String池中创建具有相同值的新对象?现在我有两个值为"dog"的对象.一个直接存在于堆中,另一个存在于String池中?
List<String> list = new ArrayList<>();
for (int i = 0; i < 1000; i++)
{
StringBuilder sb = new StringBuilder();
String string = sb.toString();
string = string.intern()
list.add(string);
}
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,调用 string.intern() 方法后,什么时候会清除堆中创建的 1000 个对象(sb.toString)?
编辑 1:如果不能保证可以清除这些对象。假设 GC 还没有运行,使用 string.intern() 本身是否已经过时了?(在内存使用方面?)
在使用 intern() 方法时,有什么方法可以减少内存使用/对象创建?
java memory garbage-collection memory-management heap-memory
哪一个更好
System.out.println("hello world");
Run Code Online (Sandbox Code Playgroud)
要么
String s="hello world";
System.out.println(s);
Run Code Online (Sandbox Code Playgroud) 我们可以完全禁用字符串的实习.它可能不是真的有用,但只是一个想法.我可以想到至少有一点可以提供帮助,即在jvm调整期间,控制perm gen的大小.
例如,如果我给出一个OSGI框架,任何人都可以添加任意数量的自己的捆绑包,每个捆绑字符串实习可以完全搞砸我的调整参数.(当然我知道我们应该对给定的固定发行版进行调整,但仍然......)
有什么想法吗!!
我有一个来自分析提供商的大型数据集。
它以 JSON 格式到达,我将其解析为散列,但由于集合的大小,我的内存使用量激增。几乎所有的东西都以字符串开头(一些值是数字),当然,虽然键被重复了很多次,但许多值也被重复了。
所以我在想,为什么不象征所有(非数字)值呢?
我发现了一些潜在问题的讨论,但我认为对 Ruby 进行全面描述会很好,因为这些问题似乎取决于实习过程的实现(符号化字符串时会发生什么)。
我发现这是在谈论 Java: 使用 java.lang.String.intern() 是好习惯吗?
(除了对最后一点有一些争论。)
那么,谁能详细解释一下什么时候不要在 Ruby 中实习字符串?
我目前正在用java编写一些代码,这些代码是一个项目的小框架,它围绕着一个包含数十亿条目的数据库.我希望保持高级别,并且从数据库中重新获得的数据应该可以轻松用于统计推断.我决定在这个项目中使用Map接口.
一个核心概念是在处理可读代码的单个数据集(我指的是数据库中的列)时将属性("数据库中的列")映射到值("单元"):我使用枚举对象(名为"属性") )对于属性类型,这意味着映射<Attribute, String>,因为数据元素都是String(也不是很大,最多40个字符左右).有15列,所以有15个枚举,地图只有很多或更少的条目.
所以看起来,我有时会有大量的Map对象浮动,但有效载荷相对较小(15-).我的目标是,与实际有效负载相比,由于实现内存开销,不会使内存爆炸.(拉伸目标:对cpu使用做同样的事情;])
到目前为止,我并不熟悉Java Collections的所有不同实现,当我今天遇到问题时,我查看了迄今为止最受欢迎的'HashMap',并且不满意那里有多少内存开销被宣布.我确信,对于标准实现而言,有许多实现没有随Java一起提供.谷歌搜索我的案子没有带来太大的结果,所以我问你:
你知道我的用例的Map的良好实现(低入口数,低值大小,可枚举键,......)
我希望我的用例清晰明确,并为您的输入感到焦虑=)非常感谢!
伸展答案目标,绝对可选,只有你有时间和知识:集合的其他实现适合于:
在我们继续之前: 我知道我们应该使用.equals()来比较内容.我现在只是谈论以下场景中的实际参考是否相同...
假设我们有以下内容:
String str1 = "str";
String str2 = "string";
String str3 = "ing";
String str4 = str1 + str3;
str1 = str4;
String str5 = "string";
System.out.println(str1==str2);//false
Run Code Online (Sandbox Code Playgroud)
我认为它应该是真的,因为在String池中,对"string"的引用应该是相同的,因为str1和str2现在都是"string".它应该是真的,但最终是假的.
System.out.println(str1.intern()==str2.intern());//true
Run Code Online (Sandbox Code Playgroud)
我试过这个,这次回归真实.然后我尝试了:
System.out.println(str1==str5);//false
System.out.println(str2==str5);//true
Run Code Online (Sandbox Code Playgroud)
还 的System.out.println( "STR" + "ing"的== "串"); //真
是不是应该来自String池?有人可以帮忙解释一下吗?
java ×10
string ×4
performance ×2
collections ×1
constants ×1
heap-memory ×1
integer ×1
math ×1
memory ×1
permgen ×1
ruby ×1
symbols ×1