Java基础_06_基本数据类型和字符串

13 篇文章 0 订阅


_____基本数据类型和字符串_____


基本数据类型包装类

为了方便对基本数据类型进行限定(最大最小值等等)和各种操作,建立了基本数据类型包装类,对应如下:

byte	Byte
short	Short
char	Character
int		Integer
float	Float
long	Long
double	Double
下面我们以Integer为具体事例来讲解:

自动装箱与拆箱:

在JDK1.5版本以前,int和Integer的转换是这样的
//Integer转换成int
Integer in = new Integer(1);
int i = in.intValue();
//int转换成Integer
int i = 1;
Integer in = Integer.valueOf();
JDK1.5版本以后就简化了这些操作,基本数据类型实现了自动装拆箱
//Integer转换成int
Integer in = new Integer(1);
int i = in;//内部还是intValue()实现
//int转换成Integer
int i = 1;
Integer in = i;//内部还是valueOf()实现
有人会问为什么是用valueOf()而不是new Integer(),如下:
class Demo {
	public static void main(String[] args) {
		Integer i1 = 4;
		Integer i2 = 4;
		out("i1==i2:"+(i1==i2));

		Integer i3 = Integer.valueOf(4);
		Integer i4 = Integer.valueOf(4);
		out("i3==i4:"+(i3==i4));

		Integer i5 = new Integer(4);
		Integer i6 = new Integer(4);
		out("i5==i6:"+(i5==i6));

		out("i1==i3:"+(i1==i3));
		out("i3==i5:"+(i3==i5));
	}

	public static void out(Object o) {
		System.out.println(o);
	}
}
/*
结果:
i1==i2:true
i3==i4:true
i5==i6:false
i1==i3:true
i3==i5:false
*/
所以我们可以推断:
Integer in = Integer.valueOf(1);
Integer in = 1;

是等价的。

但是Double却不是这样
class Demo {
	public static void main(String[] args) {
		Double d1 = Double.valueOf(4);
		Double d2 = Double.valueOf(4);
		out("d1==d2:"+(d1==d2));

		Long l1 = Long.valueOf(4);
		Long l2 = Long.valueOf(4);
		out("l1==l2:"+(l1==l2));

		Short s1 = Short.valueOf("4");
		Short s2 = Short.valueOf("4");
		out("s1==s2:"+(s1==s2));
	}

	public static void out(Object o) {
		System.out.println(o);
	}
}
/*
结果:
d1==d2:false
l1==l2:true
s1==s2:true
*/
这里就要讲解下基本数据类型中整型的缓存机制了,以Integer为例:

Integer的缓存机制:

在说缓存机制前,我们先看一个现象:
class Demo {
	public static void main(String[] args) {
		Integer i1 = -128
		Integer i2 = -128
		out("i1==i2:"+(i1==i2));

		Integer i3 = -129
		Integer i4 = -129
		out("i3==i4:"+(i3==i4));
	}

	public static void out(Object o) {
		System.out.println(o);
	}
}
/*
i1==i2:true
i3==i4:false
*/
为什么会存在这样的现象呢?
首先我翻阅了下Integer的源码,找到如下两段:
private static class IntegerCache {  
    static final int low = -128;  
    static final int high;  
    static final Integer cache[];  
    ......
}
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}
很显然Integer定义了一个缓存内部类,而且low就是缓存的最小值,于是超过这个值就不再是缓存数组里面的对象了,就会建立一个新的对象,这就是导致以上现象的原因,那缓存的最大值呢?我们接着看 IntegerCache内部类中的静态初始化代码块:
static {
    // high value may be configured by property
    int h = 127;
    String integerCacheHighPropValue =
        sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
    if (integerCacheHighPropValue != null) {
        try {
            int i = parseInt(integerCacheHighPropValue);
            i = Math.max(i, 127);
            // Maximum array size is Integer.MAX_VALUE
            h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
        } catch( NumberFormatException nfe) {
            // If the property cannot be parsed into an int, ignore it.
        }
    }
    high = h;

    cache = new Integer[(high - low) + 1];
    int j = low;
    for(int k = 0; k < cache.length; k++)
        cache[k] = new Integer(j++);

    // range [-128, 127] must be interned (JLS7 5.1.7)
    assert IntegerCache.high >= 127;
}
很显然,最大值是从javaVM虚拟机配置中取出来的,但是最小为127,你可通过运行时设置参数来控制它
class Demo {
	public static void main(String[] args) {
		Integer i1 = 127;
		Integer i2 = 127;
		out("i1==i2:"+(i1==i2));

		Integer i3 = 128;
		Integer i4 = 128;
		out("i3==i4:"+(i3==i4));
	}

	public static void out(Object o) {
		System.out.println(o);
	}
}
/*
E:\Mark\JavaBase\02>java Demo
i1==i2:true
i3==i4:false

E:\Mark\JavaBase\02>java -Djava.lang.Integer.IntegerCache.high=250 Demo
i1==i2:true
i3==i4:true
*/

常用方法:

1.与字符串之间的转换:

//数字转换成字符串
String s = 1 + "";
String s = Integer.toString(1);
//字符串转换成数字
int i = Integer.valueOf("1");//返回int
int i = parseInt("1");//返回Integer

2.进制转换:

Integer.toBinaryString(int i)//返回二进制表示的字符串
Integer.toHexString(int i)//返回十六进制表示的字符串
Integer.toOctalString(int i)//返回八进制表示的字符串


字符串String类

字符串不属于基本数据类型,是对象。
打开String源代码:
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

    /** Cache the hash code for the string */
    private int hash; // Default to 0

    public String() {
        this.value = new char[0];
    }
}
由此可见String内部其实是封装了一个final修饰的char数组,而且没有提供获取value的方法,所以String对象一旦创建就是 不可变的。
先来看看如何创建String对象:
class Demo {
	public static void main(String[] args) {
		//第一种
		String s1 = "a";
		String s2 = "a";
		out("s1==s2:"+(s1==s2));

		//第二种
		String s3 = String.valueOf('a');
		String s4 = String.valueOf('a');
		out("s3==s4:"+(s3==s4));

		//第三种
		String s5 = new String("a");
		String s6 = new String("a");
		out("s5==s6:"+(s5==s6));
	}

	public static void out(Object o) {
		System.out.println(o);
	}
}
/*
s1==s2:true
s3==s4:false
s5==s6:false
*/
上面就是常见的三种创建方式,但是与Integer的不同在于,显然
String s1 = "a";
String s3 = String.valueOf('a');
并不等价,但是仍然存在缓存一说,这是因为 字符串常量池的原因。
在使用第二种方式创建字符串数组源代码如下:
public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}
而所以的基本数据类型toString()方法都是通过 return new String(char[] ch)来返回,等同于第三中方式,而new是在堆内存中新建一个对象,所以不地址不相同
第一种方式是先在栈中创建一个对String类的对象引用变量str,然后通过符号引用去字符串常量池里找有没有"abc",如果没有,则将"abc"存放进字符串常量池,并令str指向”abc”,如果已经有”abc” 则直接令str指向“abc”。所以第一种利用了常量池来进行缓存,相同字符串地址相同。

String的常见方法:

先申明:String str = "abcd";

1.取得字符串中指定位置的值:

</pre><pre name="code" class="java">str.charAt(1);
//返回'b'

2.按字典顺序比较:

str.compareTo("aBcd");
str.compareToIgnoreCase("aBcd");//无视大小写比较
str.compareTo("abcdef");
/*
32 //若顺序比较到不一样的字符返回差值
0
-2 //若最短的比较完后都相等,那么就返回长度差
*/

3.前缀后缀:

str.startWith("ab")//判断是否以"ab"打头
str.endsWith("de")//判断是否以"de"结尾
/*
true
false
*/

4.比较内容是否相等:

str.equals("abc")//判断是否字符串内容是否相同
str.equalsIgnoreCase("AbcD");//忽视大小写
/*
false
true
*/

5.查找内容:

str.indexOf("bc");//(向右)顺序查找"bc"在str中第一次出现时的索引位置,没有返回-1
str.indexOf("bc",2);//从索引位置2开始顺序查找
str.lastIndexOf("bc");//(向左)反向查找"bc"在str中第一次出现时的索引位置,没有返回-1
str.lastIndexOf("bc",1);//从索引位置1开始反向查找
str.lastIndexOf("bc",0);//从索引位置0开始反向查找
/*
1
-1
1
1
-1
*/

6.替换:

str.replace('a','F');//替换str中所有的a为F
/*
Fbcd
*/

7.拆分:

String s = "deas dea as de";
s.split(" ");//返回String数组,以" "拆分,长度为4

8.裁剪字符串:

"unhappy".substring(2) returns "happy"
"Harbison".substring(3) returns "bison"
"emptiness".substring(9) returns ""

9.大小写转换:

str.toLowerCase();//全转换成小写,返回"abcd";
str.toUpperCase();//全转换成大写,返回"ABCD";

10.去除前后空白:

" abc ".trim() returns "abc"


StringBuffer和StringBuilder类

因为String对象一旦初始化就不可改变,所以才进行大量的字符串操作时,难免产生大量的临时数据,所以出现了StringBuilder和StringBuffer,其内部的char数组是可变长度的,两个类的唯一区别在于StringBuffer是线程安全的,我们下面以StringBuilder为例:

1.创建:

StringBuilder sb = new StringBuilder();//可以不指定初始值
StringBuilder sb = new StringBuilder(String str);//也可以指定初始值

2.拼接:

sb.append("aa");//也可以添加基本数据类型
sb.toString();//"aa"
sb.append("bcd");
sb.toString();//"aabcd"

3.删除:

sb.delete(int start, int end);//删除指定索引范围内的数据,包含start不包含end
StringBuilder sb = new StringBuilder("aabcd");
sb.delete(1,2);
sb.toString();//"abcd"
其他方法都与String类似...
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值