相关疑难解决方法(0)

什么是Java String interning?

什么是Java中的String Interning,何时应该使用它,为什么?

java string string-interning

219
推荐指数
5
解决办法
10万
查看次数

将字符串与==进行比较,这些字符串在Java中声明为final

我有一个关于Java中的字符串的简单问题.以下简单代码段仅连接两个字符串,然后将它们与之进行比较==.

String str1="str";
String str2="ing";
String concat=str1+str2;

System.out.println(concat=="string");
Run Code Online (Sandbox Code Playgroud)

比较表达式concat=="string"返回false那么明显(I明白之间的差值equals()==).


当这两个字符串被声明时final,

final String str1="str";
final String str2="ing";
String concat=str1+str2;

System.out.println(concat=="string");
Run Code Online (Sandbox Code Playgroud)

比较表达式concat=="string",在这种情况下返回true.为什么会final有所作为?它是否必须与实习生池做某事或我只是被误导?

java string final

217
推荐指数
4
解决办法
1万
查看次数

何时在String文字上使用intern()

我看到很多这样的遗留代码:

class A {
    public static final String CONSTANT = "value".intern();
    ...
}
Run Code Online (Sandbox Code Playgroud)

我没有看到intern()的任何原因,因为在Javadoc中可以读取:"所有文字字符串和字符串值常量表达式都被实现." 是否有一些这样的意图,也许是在过去的语言修订版中?

java string string-interning

38
推荐指数
3
解决办法
5407
查看次数

Java中字符串实习的奇怪行为

代码如下:

String s = new String("1");
s.intern();
String s2 = "1";
System.out.println(s == s2);

String s3 = new String("1")+new String("1");
s3.intern();
String s4 = "11";
System.out.println(s3 == s4);
Run Code Online (Sandbox Code Playgroud)

上面代码的输出是:

false
true
Run Code Online (Sandbox Code Playgroud)

我知道s并且s2是不同的对象,因此结果的计算结果为false,但第二个结果的计算结果为true.有人能告诉我区别吗?

java string

15
推荐指数
2
解决办法
1127
查看次数

为什么使用String实习方法?

正如在本文中所解释的那样,我们应该在字符串常量上使用字符串的实际方法发布字符串文字是自动合并但是对于使用new构造的对象不是,因此使用该实习方法.但即使我们使用实习方法,也会创建一个新对象,那么实习方法的用途是什么?

String s = "Example";

String s1 = new String("Example"); // will create new object

String s2 = new String("Example").intern(); // this will create new object
 // but as we are calling intern we will get reference of pooled string "Example"
Run Code Online (Sandbox Code Playgroud)

现在

System.out.println(s == s1); // will return false
System.out.println(s == s2); // will return true
System.out.println(s1 == s2); // will return false
Run Code Online (Sandbox Code Playgroud)

那么实习方法的用途是什么?

编辑

我理解实习生方法的工作,但我的问题是为什么有实习方法?因为要调用intern方法我们必须使用new创建字符串对象,这将创建新的字符串实例!

String s3 = new String("Example"); // again new …
Run Code Online (Sandbox Code Playgroud)

java

12
推荐指数
1
解决办法
6076
查看次数

Java中新String("X")和新String("X")+ new String("Y")之间字符串初始化的差异

public static void main(String[] args) {
    String s1 = new String("aa");
    s1.intern();
    String s2 = "aa";
    System.out.println(s1 == s2);

    //wrong in JDK1.6 but true in JDK1.8
    String str1 = new String("str") + new String("01");
    str1.intern();
    String str2 = "str01";
    System.out.println(str1 == str2);

}
Run Code Online (Sandbox Code Playgroud)

我用JDK1.8运行上面的代码,我认为结果会得到两个"falses",因为在我看来,很明显s1和str1位于堆中,而s2和str2是在字符串中实现的游泳池,但我得到了"假"和"真实".问题来了:是什么导致"真实"?


以上是原始问题.现在要确定这个问题远不是这些被称为重复的问题,我想谈谈我的新发现:代码的第二部分使用JDK1.6获得"错误"结果,而使用JDK1.8获得"真实"结果.一些博客称,在JDK1.7发布后,intern()的行为发生了变化.

如果池不包含与此String对象相等的字符串,则此String对象将不会添加到池中,而是将对此String对象的引用添加到池中.这意味着池中的引用将被分配给位于其他位置的字符串对象(如堆),并且下一次文本字符串的初始化等于早期的字符串对象也将被分配给字符串对象.这正好描述了代码part2关于"真实"结果.

这个理论确实可以用来解释上面代码的结果.但很明显,该理论不属于intern()doc所包含的内容,这在JDK6/8 API中几乎相同.


现在的问题是:对JDK1.6和JDK 1.8中相同代码的不同结果有没有更好的解释?我上面提到的理论究竟是真正发生的吗?

java

9
推荐指数
1
解决办法
696
查看次数

Java的String.intern()的目的是什么?

我知道有两种方法可以在Java中创建String:

String a = "aaa";
String b = new String("bbb");
Run Code Online (Sandbox Code Playgroud)

第一种方式,Java肯定会在字符串池中创建一个String对象并a引用它.(假设"aaa"之前不在游泳池里.)

使用第二种方法,将在堆中创建一个对象,但是jvm还会在字符串池中创建一个对象吗?

在这篇关于Java字符串池的问题中,@ Jesper说:

如果你这样做:

String s = new String("abc");
Run Code Online (Sandbox Code Playgroud)

然后在池中将有一个String对象,一个代表文字"abc",>的对象,并且将有一个单独的String对象,而不是在池中,它包含池对象的>内容的副本.

如果这是真的,那么每次使用new String("bbb");,在池中创建一个对象"bbb",这意味着通过上面的任何一种方式,java将始终在池中创建一个字符串对象.然后intern()用于什么?在文档http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#intern()中,它说:

调用实习方法时,如果池已经包含等于此字符串对象的字符串(由equals(Object)方法确定),则返回池中的字符串.否则,将此String对象添加到池中,并返回对此String对象的引用.

这意味着有些情况下池中没有字符串,这可能吗?哪一个是真的?

java string

7
推荐指数
2
解决办法
2210
查看次数

Java - 如何有效地存储大量的String数组

我正在尝试使用Java高效加载大型CSV格式的文件(通常为200-600mb)(内存更少,访问速度更快).目前,该程序正在使用字符串数组列表.之前使用Lua程序处理此操作,该程序使用每个CSV行的表和用于保存每个"行"表的表.

以下是内存差异和加载时间的示例:

  • CSV文件 - 232mb
  • Lua - 内存中549mb - 加载157秒
  • Java - 内存中1,378mb - 加载12秒

如果我没记错的话,Lua表中的重复项存在作为对实际值的引用.我怀疑在Java示例中,List正在保存每个重复值的单独副本,这可能与更大的内存使用量有关.

以下是CSV文件中数据的一些背景知识:

  • 每个字段由一个字符串组成
  • 每行内的特定字段可以包括一组字符串中的一个(例如,字段3可以是"红色","绿色"或"蓝色").
  • 内容中有许多重复的字符串.

以下是加载数据可能需要的一些示例:

  • 搜索所有尝试与给定String匹配的字符串并返回匹配的字符串
  • 在GUI表中显示匹配项(可通过字段排序).
  • 更改或替换字符串.

我的问题 - 是否有一个集合需要更少的内存来保存数据但仍然提供了轻松快速地搜索/排序数据的功能?

java csv lua

5
推荐指数
1
解决办法
5759
查看次数

为什么intern方法不会在java中返回相等的String

public static void main (String[] args) {

    String s1 = new String("hello");
    String s2 = new String("hello");
    s1.intern();
    s2.intern();        
    System.out.println(s1 == s2); // why this returns false ?


}
Run Code Online (Sandbox Code Playgroud)

根据我的理解,第一次调用实习方法应该创建一个带有单个字符串的"字符串实习池" "hello".第二次调用实习方法没有做任何事情(因为"hello"字符串已经存在于池中).现在,当我说s1 == s2我希望JVM比较"hello"字符串实习池中的字符串并返回时true.

java

5
推荐指数
1
解决办法
220
查看次数

字符串Concat具有相同的参考?

这是我的代码,我现在对此输出的字符串池和堆存储非常困惑.

public class String1 {
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        String str = "abcd";
        String str1 = "" ;

        str1=str1+"abcd";

        if(str.equals(str1))
            System.out.println("True");
        else
            System.out.println("False");

        if(str == str1)
            System.out.println("True");
        else
            System.out.println("False");
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我正在创建String str并将存储在字符串池中(如果我出错了,请纠正我!).现在,在str1使用字符串连接后,"abcd"它们都具有相同的值.所以,我认为strstr1应该在String池中有相同的引用,所以,第二个if语句应该打印true但是打印false.

那么,我的问题为什么str和str1没有得到相同的参考?

java string concat

4
推荐指数
1
解决办法
177
查看次数

从System.in读取的两个相同的字符串是否会存储在公共内存位置?

假设我们有这样的程序:

import java.io.*;

public class ReadString {

   public static void main (String[] args) {

      //  prompt the user to enter their name
      System.out.print("Enter your name: ");

      //  open up standard input
      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

      String userName = null;
      String userNameCopy = null;

      //  read the username from the command-line; need to use try/catch with the
      //  readLine() method
      try {
         userName = br.readLine();
         System.out.print("Enter your name once again: ");
         userNameCopy = br.readLine();
      } catch (IOException ioe) { …
Run Code Online (Sandbox Code Playgroud)

java

3
推荐指数
1
解决办法
89
查看次数

java如何将引号中的任何内容识别为字符串对象?

如果我写:

String s = new String("abc");
Run Code Online (Sandbox Code Playgroud)

它创建一个类型String为"abc"的对象.如果我写:

String s = "abc";
Run Code Online (Sandbox Code Playgroud)

这也会创建一个值为"abc"的对象.如何在不遇到新关键字的情况下创建对象.

如果我写:

s.append("def");
Run Code Online (Sandbox Code Playgroud)

它创建了另外两个字符串对象:

a. "abcdef"  
b. "def"
Run Code Online (Sandbox Code Playgroud)

因此,在遇到双重引号内的任何内容时,都会创建一个新String对象.这是怎么发生的?

java string

0
推荐指数
2
解决办法
553
查看次数

在Java中,`String s ="lol";`创建两个对象?

我听说你执行时会创建两个对象String s = new String("lol");.为字符串常量池创建一个对象s,在堆上创建一个对象.

那么,当我们执行以下操作时是否创建了2个对象?String s = "lol";对象创建是否相同?

编辑:

创建了多少个对象: String s1 = new String("lol1");

以及多少: String s2 = "lol2";

java string

-2
推荐指数
1
解决办法
128
查看次数

标签 统计

java ×13

string ×8

string-interning ×2

concat ×1

csv ×1

final ×1

lua ×1