Java_________数字与字符串1

 

一:字符串

1、java程序中创建对象的常规方式有4种:

(1)通过new调用构造器创建对象。

(2)通过Class对象的newInstance()方法调用构造器创建java对象

(3)通过java的反序列化机制从IO流中恢复java对象。

(4)通过java对象提供的clone()方法复制一个新的java对象。

此外,对于字符串以及Byte,Short,Int,Long,Character,Float,Double和Boolean这些基本类型的包装类, 

java还允许以直接量的方式来创建java对象,(String str="abc"; Intefer in =5;  )

还可通过简单的算法表达式,连接运算来创建java对象(String str2="abc"+"xyz");

2:关于字符串常量的一些问题:

JVM会使用一个字符串池来保存它们,当第一次使用某个字符串直接量是,JVM会将它放入字符串池进行缓存。在

一般情况下,字符串池中字符串对象不会被垃圾回收,当程序再次需要使用该字符串时,无需重新创建一个新的字符串,而是

直接让引用变量执行字符串池中已有的字符串。

(1)请问:String java=new String("疯狂java");       

上面的语句创建了几个字符串常量。

答案:一个是“疯狂java”这个直接量对应的字符串对象,一个是由new String()构造器返回的字符串对象,

(2)    判断str1和str2是那创建字符串的方式。

public static void main(String[] args) {
    String str1="Hello"; //str1指向字符串缓存池中的“Hello”字符串
    String str2="Hello"; //str2指向字符串缓存池中的“Hello”字符串
    System.out.println(str1==str2);
}

str1和str2两个字符串变量的值都是直接量,它们都指向jvm的字符串池里面的“Hello”字符串。

(3)通过字符串连接表达式来创建字符串对象,故可以将一个字符串连接表达式赋值给字符串常量。

如果这个字符串连接表达式的值可以在编译时确定下来,那么jvm会在编译时计算该字符串变量的值,

并让他指向字符串池中对应的字符串。

public static void main(String[] args) {
    String str1="Hello java的长度:10";
    String str2="Hello "+"java"+"的长度:"+10;
    System.out.println(str1==str2); //true
}

虽然str2的值是一个字符串连接表达式,但是这个字符串连接表达式的值在编译时就确定下来了。

str2中的所有运算数,它们多少字符串直接量,整数直接量,没有变量的参与,没有方法的调用。

因此,jvm可以在编译时就确定该字符串连接表达式的值,可以让该字符串变量指向字符串池中对应的字符串。

(4)如果程序使用了变量,或者调用了方法,那就只能等到运行时才可以确定该字符串连接表达式的值,

也就无法再编译时确定该字符串变量的值,因此无法利用jvm的字符串池。

public static void main(String[] args) {
    String str1="Hello java的长度:10";
    String str2="Hello "+"java"+"的长度:"+"Hello java".length();
    System.out.println(str1==str2);
    int len=10;
    String str3="Hello "+"java"+"的长度:"+len;
    System.out.println(str1==str3);
}

答案:false,false。

str2和str3的值也是字符串连接运算。但是由于str2变量的连接表达式中包含了一个方法的调用,str3字符串连接

表达式中包含了一个len变量,因此str2和str3都不会指向jvm字符串池中对应的字符串。

(5)特殊情况:字符串连接运算符中的所有变量都可执行“宏替换”,那么jvm一样可以在编译时就确定字符串连接表达式的值,

一样会让字符串变量指向JVM字符串池中的对应字符串。

public static void main(String[] args) {
    String str1="Hello java的长度:10";
    final String s1="Hello ";
    String str2=s1+"java"+"的长度:10";
    System.out.println(str1==str2);
    final int len=10;
    String str3="Hello "+"java"+"的长度:"+len;
    System.out.println(str1==str3);
}

答案:true,true。

str2和str3对应的字符串连接表达式中包含了s1和len变量,但由于编译器会对s1和len执行“宏替换”,

jvm同样可以在编译时确定str2和str3变量的值,可以让str2和str3指向字符串池中对应的字符串。

(6)String str="Hello "+"java ,"+"crazyit.org"; 到底创建了几个字符串对象?

答案:只创建了一个字符串对象,str的值可以在编译时确定下来。jvm会在编译时就计算出str的值

为“Hello java ,crazyit.org”,然后将该字符串直接量放入字符串池中,并让str指向该它。

3:、String类是一个典型的不可变类。当一个String对象创建后,该String类里面包含的字符串序列就被固定下来了,

以后永远都不能改变。

(1)

public static void main(String[] args) {
    String str1="Hello"; //(1)
    System.out.println(System.identityHashCode(str1));
    str1=str1+"java";    //(2)
    System.out.println(System.identityHashCode(str1));
    str1=str1+",crazyit.org"; //(3)
    System.out.println(System.identityHashCode(str1));
}

当运行输出str1时,每一次的str1变量对应的字符串序列一直在变化,开始等于“Hello”,第一次连接运算后为“Hello java”

,第二次连接后等于“Hello java,crazyit.org”,看起来是str对应的字符序列发生了变化,str只是一个引用类型的变量,

它并不是真正的String对象,它只是指向String对象。

当程序执行(1)行代码时,str指向一个字符串池中对应的字符串。(执行完(1)行代码后的内存分配)

当执行(2)行代码的连接运算,此时的连接运算会把“Hello”,“java”两个字符串连接起来得到一个新的字符串,并让str指向这个新的的字符串。(执行完(2)后的内存分配)

(str变量原来指向的字符串对象并没有任何改变,它所包含的字符序列依然是“Hello”,只是str变量不在指向它而已。

str变量指向了一个新的String对象,因此看到str变量所引用String对象的字符序列发生了改变。发生改变的不是String对象,而是str变量本身,它改变了指向,指向了一个新的string对象)

重要:(1)“Hello”字符串也许以后永远都不会用到了,但这个字符串并不会被垃圾回收,它将一直存在字符串常量池中,

这就是java内存泄漏的原因之一。

(2)System类的identityHashCode()静态方法来获取str的identityHashCode值,

发生了3次返回的identityHashCode值并不相同的状况,这表明了3次访问str是分别指向3个不同的String对象。

(System提供的identityHashCode()静态方法用于获取某个对象唯一的HashCode值,这个identityHashCode()的返回值与该类是否重写了HashCode()方法无关,只有当两个对象相同时,它们的identityHashCode值才会相同)

4、String类,它代表了序列不可改变的字符串。

需要一个字符串序列会发生改变的字符串,应考虑使用StringBuider或StringBuffer。

(很多资料上推荐使用StringBuffer,那是因为资料都是在JDK1.5问世之前了)

实际上通常优先考虑使用StringBuider。StringBuffer与StringBuilder唯一个区别在于:StringBuffer是线程安全的,

也就是说StringBuffer类中绝大部分方法都增加了synchronized修饰符。对方法增加了sychronized修饰符可以保证该方法线程安全,但会降低该方法的执行效率,在没有多线程的环境下,应该优先使用StringBuilder类来表示字符串。

public static void main(String[] args) {
    StringBuilder str=new StringBuilder("Hello ");
    System.out.println(str);
    System.out.println(System.identityHashCode(str));
    str.append("java");
    System.out.println(str);
    System.out.println(System.identityHashCode(str));
}

str应用变量没有发生改变,它一直指向同一个StringBuilder对象,但是它所指向的StringBuilder所包含的字符序列

发生了变化。输出的str的identityHashCode完全相同。

5、StringBuilder,StringBuffer都代表了字符串序列可变的字符串,其中StringBuffer是线程不安全的版本,

StringBuffer是线程安全的版本。String则代表了字符序列不可变的字符串,但String不需要线程安全,线程不安全两个版本,因为String本身是不可变类,而不可变类总是线程安全的。

 

 

 

二:装箱拆箱

(Java是一个近乎纯洁的面向对象编程语言,但是为了编程的方便还是引入了基本数据类型,

但是为了能够将这些基本数据类型当成对象操作,Java为每一个基本数据类型都引入了对应的包装类型(wrapper class)。)

1:封装类(所有的基本类型,都有对应的类类型。)

2:Number类

Number类

 

3:基本类型转封装类

int i = 5;

Integer it = new Integer(i);//基本类型转换成封装类型

4:封装类型转基本类型

int i = 5;

Integer it = new Integer(i); //基本类型转换成封装类型

int i2 = it.intValue();//封装类型转换成基本类型

5:自动装箱

(1)不需要调用构造方法,通过=符号自动把 基本类型  转换为  类类型  就叫装箱

public static void main(String[] args){
    int i=5;
    Integer i1=i;
    System.out.println(i1);
}

 

6:自动拆箱

(2)不需要调用Integer的intValue方法,通过=就自动转换成  int类型,就叫拆箱

  public static void main(String[] args){
       int i=1;
       Integer it=new Integer(i);
       int i1=it;
       System.out.println(i1);

    }

7:int最大值,int最小值

 public static void main(String[] args){
        System.out.println(Integer.MAX_VALUE);
        System.out.println(Integer.MIN_VALUE);
    }

 

三:字符串转化(数转字,字转数)

1,数字     转  字符串,两种方法。

(1)使用String类的静态方法valueOf。

public static void main(String[] args){
        int i=5;
        String str=String.valueOf(i);
        System.out.println(str);
    }

(2)先把基本类型装箱为对象,然后调用对象的toString。

public static void main(String[] args) {
    int i = 53245;
    Integer it = i;
    String str = it.toString();
    System.out.println(str);
}

2    字符串 转   数字

调用Integer的静态方法parseInt

public static void main(String[] args) {
    String str = "1234";
    int i = Integer.parseInt(str);
    System.out.println(i);
}

3:字符串转换为字符数组array=string.toCharArray();

    public static void main(String[] args){
         String str="123456";
         char array[]=new char[100];
         array=str.toCharArray();//*
        System.out.println("遍历这个字符数组");
         for(int i=0;i<array.length-1;i++){
             System.out.print("  "+array[i]);
         }
    }

4:字符数组转换为字符串(string=new String(array);)

//通过String类型的构造函数将字符数组转换为字符串
    public static void main(String[] args){
         String str=null;
         char array[]={'1','s','f'};
        str=new String(array);//*
        System.out.println("输出字符串: "+str);
    }

5:String和StringBuffer的相互转换

public static void a(){
    //将String类型转换为StringBuffer类型的字符串
    String str="12345";
    StringBuffer strbuf;
    strbuf=new StringBuffer(str);//*
    System.out.println("输出StringBuffer类型:"+strbuf);
}
public static void b(){
    //将StringBuffer类型的字符串转换为String类型
    String str;
    StringBuffer strbuf=new StringBuffer("Hello");
    str=strbuf.toString();
    System.out.println("输出字符串:"+str);
}

三:数学方法

(1)四舍五入round()

float f1=5.4f;
float f2=5.5f;

System.out.println(Math.round(f1));
System.out.println(Math.round(f2));

(2)随机数Math.random()

System.out.println(Math.random());//得到一个0-1之间的随机浮点数(取不到1)
System.out.println((int)( Math.random()*10));//得到一个0-10之间的随机整数 (取不到10)

(3)开方Math.sqrt()

System.out.println(Math.sqrt(9));

(4)次方Math.pow()

System.out.println(Math.pow(2,4));//2的4次方

(5)π Math.PI

System.out.println(Math.PI);

(6)自然常数Math.E

System.out.println(Math.E);

 

 

四:格式化输出

(1)格式化输出

(2)printf和format

public static void main(String[] args) {

    String name = "粉粉";
    int a = 2;
    String grade = "表扬";

    String sentenceFormat = "%s 得到了 %d的%s";
    System.out.printf(sentenceFormat, name, a, grade);
    System.out.println();
    System.out.printf(sentenceFormat, name, a, grade);
}

(3)换行符

(4)总长度,右对齐,补0,千位分隔符,小数点位数,本地化表达

public static void main(String[] args) {

    int year = 2000;
    System.out.format("%d%n", year);//直接打印数字
    System.out.format("%8d%n", year);//总长度是8,默认右对齐。
    System.out.format("%-8d%n", year);//总长度是8,默认左对齐。
    System.out.format("%08d%n", year);//总长度是8,不够补0
    System.out.format("%,8d%n", year * 10000);//千位分隔符
    System.out.format("%.2f%n", Math.PI);//小数点位数
}

 

五:字符(Character类,常见转义)

(1)char对应的封装类Character(装箱拆箱)

public static void main(String[] args) {
    char c='a';
    Character c1=c;//自动装箱
    c=c1;//自动拆箱
 }

(2)Character类中的常见方法

public static void main(String[] args) {
    System.out.println(Character.isLetter('a'));//判断是否为字母
    System.out.println(Character.isDigit('a')); //判断是否为数字
    System.out.println(Character.isWhitespace(' ')); //是否是空白
    System.out.println(Character.isUpperCase('a')); //是否是大写
    System.out.println(Character.isLowerCase('a')); //是否是小写

    System.out.println(Character.toUpperCase('a')); //转换为大写
    System.out.println(Character.toLowerCase('A')); //转换为小写

    String a = 'a'; //不能够直接把一个字符转换成字符串,会出现红线
    String a2 = Character.toString('a'); //将一个字符转换为字符串


 }

(3)常见转义

public static void main(String[] args) {
    System.out.println("使用空格无法达到对齐的效果");
    System.out.println("abc def");
    System.out.println("ab def");
    System.out.println("a def");

    System.out.println("使用\\t制表符可以达到对齐的效果");
    System.out.println("abc\tdef");
    System.out.println("ab\tdef");
    System.out.println("a\tdef");

    System.out.println("一个\\t制表符长度是8");
    System.out.println("12345678def");

    System.out.println("换行符 \\n");
    System.out.println("abc\ndef");

    System.out.println("单引号 \\'");
    System.out.println("abc\'def");
    System.out.println("双引号 \\\"");
    System.out.println("abc\"def");
    System.out.println("反斜杠本身 \\");
    System.out.println("abc\\def");

 }

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值