String操作

首先,我们要先了解常量池的概念,常量池在java中用于保存在编译期已确定的,存在于已编译的class文件中的一份数据。它包括了关于类,方法,接口等中的常量,也包括字符串常量,如String s = “str”这种申明方式;当然也可扩充,执行器产生的常量也会放入常量池,故认为常量池是JVM的一块特殊的内存空间。

问题一: 
String是最基本的数据类型吗? 
基本数据类型包括byte、int、char、long、float、double、boolean和short。 
java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类,或者用StringBuffer类。前者效率高,后者支持线程同步。

问题二:

final String str1 = "aaa";    
final String str2 = "bbb";    
String str3 = "aaabbb";    
String str4 = str1 + str2;    
System.out.println(str3 == str4);//true 

解析: 
因为str1与str2都定义成了常量,在编译时就已经确定,编译时就会将变量替换为常量,等同于 str4 = “aaa”+”bbb”,因此不产生新的对象。

问题三:

String s = new String("abc");   
String s1 = "abc";   
String s2 = new String("abc");   

System.out.println(s == s1);   
System.out.println(s == s2);   
System.out.println(s1 == s2);

解析: 
第一句执行后内存中有两个对象,而不是一个。一个由new String(“abc”)中的”abc”在字符串常量池生成一个值为”abc”的对象;第二个由new在堆里产生一个值为”abc”的对象,该对象完全是String Pool里的”abc”的一个拷贝。变量s最后指向堆中产生的”abc”对象;

第二句执行时,变量s1先去String Pool找是否有值为”abc”的对象,很显然在上一步中java已经在String Pool里生成一个”abc”对象了,所以s1直接指向String Pool中的这个”abc”;

第三句中又有一个new,首先会去字符串常量池中找“abc”,若能找到则直接获取地址,不再创建新的常量。在java中凡遇到new时,都会在堆里产生一个新的对象。因此,该句执行后堆里又多了一个”abc”对象,这与执行第一句后生成的”abc”是两个不同的对象,s2最后指向这个新生成的对象。 
因此,执行后面的打印语句的结果是三个false 。

问题四:

String hello = "hello";   
String hel = "hel";   
String lo = "lo";   
System.out.println(hello == "hel" + "lo");   
System.out.println(hello == "hel" + lo); 

解析: 
前三句在String Pool里分别产生“hello”、“hel”、“lo”三个常量字符串对象。 
当做第一个加法连接时,+号两边都是常量字符串,”hel” + “lo”在编译时就变成了“hello”,java就会将两者拼起来后到String Pool里找与之相等(用equals)的字符串,若存在则将其地址返回;不存在则在String Pool里新建一个常量对象,其值等于拼接后的字符串,并将其地址返回。

而第二个+号两边有一个是变量,此时,java会在堆里新建一个对象,其值是两字符串拼接后的值,此时返回的地址是堆中新对象的地址。 
所以,第一句做+连接后返回String Pool中“hello”的地址,显然与变量hello的地址相等; 第二句返回的是堆中地址,显然与变量hello的地址不等;

问题五:类似于问题四:

public class Test { 
   public static void main(String[] args) { 
       final String str1 = "HelloWorld";
       final String str2 = "Hello" + "World"; 
       System.out.println(str1 == str2);//true 
       final String str3 = "Hello" + String.valueOf("World"); 
       System.out.println(str1 == str3);//false   
  }
 }

解析: 
str3需要通过valueOf方法调用之后才能确定。而不是在编译时确定。

问题六: 
在Java中String是不可变的和无法改变的,有什么好处? 
1,可以使用字符串池来存储字符串,提高存储效率。 
2,增加安全性,在存储一些敏感信息,如数据库用户名,密码等是,黑客不能改变它的值。java的类加载器加载类时,字符串的不变性可以确保正确的类被加装。 
3,由于String是不可变的,它是安全的,在多线程环境下,我们不需要任何同步。

问题七:

使用两种方法把这个字符串中的单词首字母转为大写:String str = “hello java and android!”

    @Test
    public void test1(){
        String str = "hello java and android!";
        //这是一种方式
        String[] strs=str.split(" ");
        String st="";
        for (int i = 0; i < strs.length; i++) {
            String name = strs[i];
            st+=name.substring(0, 1).toUpperCase()+name.substring(1);
            st+=" ";
        }
        System.out.println(st);
        //另一种方式
        char[] array = str.toCharArray();
        
        array[0]=(char)((int)array[0]-32);
        for (int i = 0; i < array.length; i++) {
            if(' '==array[i]){
                array[i+1]=(char)((int)array[i+1]-32);
            }
        }
        String sts = new String(array);
        System.out.println(sts);
    }

问题八、String是线程安全的吗?

String是不可变类,一旦创建了String对象,我们就无法改变它的值。因此,它是线程安全的,可以安全地用于多线程环境中。

问题九、intern的使用和原理

 
 

解释参考:https://www.cnblogs.com/wxgblogs/p/5635099.html

问题10、字符串包含问题

给定两个分别由字母组成的字符串str1和字符串str2,字符串str2的长度比字符串str1短,请问,如何最快地判断字符串str2中所有字母是否都在字符串str1里?例如,字符串str1为“ABCD”,str2为“AC”,则返回true,因为字符串str2中的字母A和B都在字符串str1中,但如果str2为“AE”,则返回false,因为字符串str2中的字母E不在字符串sstr1中。

    @Test
    public void test4(){
        String s2 ="abcd";
        String s1="ac";
        String[] split = s1.split("");
        for (int i = 0; i < split.length; i++) {
            if(!s2.contains(split[i])){
                System.out.println("不包含");
            }
        }
        System.out.println("包含");
    }

另一种:

public static boolean stringContain(String str1,String str2) {

//将字符串转为字符数组

char[] a = str1.toCharArray();

char[] b = str2.toCharArray();

//进行循环比较

for (int i = 0; i < b.length; ++i) {

int j;

//如果a[j]等于b[i],则跳出本次循环,反之j+1

for (j = 0; (j < a.length) && (a[j] != b[i]); ++j) ;

if (j >= a.length) { return false; } } return true;

}

问题11、输出字符串的所有组合

输入一个字符串,输出该字符串中字符的所有组合。举个例子,如果输入abc,它的组合有a、b、c、ab、ac、bc、abc。

https://blog.csdn.net/qq_35246620/article/details/53263806

问题12、输出字符串中第一个不重复的字符

在一个字符串中找到第一个只出现一次的字符。例如,输入“abaccdeff”,则输出b。

 https://blog.csdn.net/qq_35246620/article/details/53270801

    @Test
    public void test5(){
        String s2 ="abaccdeff";
        String end="";
        for (int i = 0; i < s2.length(); i++) {
            end=s2.substring(i, i+1);
            String all = s2.replaceAll(end, "");
            if((s2.length()-all.length())==1){
                System.out.println(end);
                return ;
            }
        }
    }

问题 13、输出字符串的全排列

输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a、b、c所能排列出来的所以字符串abc、bac、bca、cab和cba。

https://blog.csdn.net/qq_35246620/article/details/53240670

问题14、最长公共子串

求两个字符串的最长公共子串,例如str1=“123china”,str2=“23hit”,则其最长公共子串为“23”。

https://blog.csdn.net/qq_35246620/article/details/53195381

Java数字格式化输出时前面补0 

 int youNumber = 1;      
    // 0 代表前面补充0      
    // 4 代表长度为4      
    // d 代表参数为正数型      
    String str = String.format("%04d", youNumber);      
    System.out.println(str); // 0001 

15、intern方法(下面的题在周志明第三版虚拟机书中,第二章)

intern是一个本地方法,它的作用是如果字符串常量池中已经包含一个等于此String对象的字符串,则返回常量池中这个字符串的String对象的引用;否则,会将此String对象包含的字符串添加到常量池中,并且返回此String对象的引用。

public static void main(String[] args) {
    String str1 = new StringBuilder("SB").append("java").toString();

    System.out.println(str1);
    System.out.println(str1.intern());
    System.out.println(str1 == str1.intern());

    String str2 = new StringBuilder("ja").append("va").toString();

    System.out.println(str2);
    System.out.println(str2.intern());
    System.out.println(str2 == str2.intern());

    /**
    运行结果:
     * SBjava
     * SBjava
     * true
     * java
     * java
     * false
     */
}
 除了java,其他字符串都是true
* 按照代码结果,java字符串为false,必然是两个不同的java,那另外一个java是怎么加载进来的?
* 原因:有一个初始化的java字符串(jdk出娘胎自带的),在加载sun.misc.Version这个类的时候进入常量池

 

        String str1 = new StringBuilder("SB").append("java").toString();

        System.out.println(str1);
        System.out.println(str1.intern());
        System.out.println(str1 == str1.intern());
        String str3 = new StringBuilder("SB").append("java").toString();

        System.out.println("---");
        System.out.println(str3 == str1);
        System.out.println(str3.intern() == str1);
        System.out.println(str3.intern() == str3);
        System.out.println(str3 == str1.intern());
        System.out.println("---");

SBjava
SBjava
true
---
false
true
false
false
---

 

 

 

 

 

   
还待补充!!!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值