见CDDN/kkopophttp://blog.csdn.net/kkopopo/article/details/20207495
String s1 =
""
;
String s2 =
null
;
System.out.println(
"----"
+s1+
"****"
);
//结果----****s1.length()结果是0
System.out.println(
"----"
+s2+
"****"
);
//结果----null****s2.length()抛异常java.lang.NullPointerException
String s1 =
"abc"
;
//s1是一个类类型变量,"abc"是一个对象
//字符串最大的特点:
一旦被初始化就不可改变(final常量的特性)【放在常量池中 】
String tom = "I am student"; 这个是字符串常量,存储在常量池中String jerry = "I am student"; 因为在常量池中已有,就不创建新的,直接从常量池中调用,所以一样tom == jerry ---------true;tom.equals(jerry)-----true;//******************************************//String tom = new String("I am student");String jerry = new String("I am stundet");tom == jerry--------false//new产生先对象 ,不相同tom.equals(jerry)---true//
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public
class
StringDemo {
public
static
void
main(String[] args) {
String s1 = "abc" ;
String s2 = new String( "abc" );
//s1和s2有什么区别?
//s1在内存中有一个对象。
//s2在内存中有两个对象。(可能是1个对象)下面有解析
System.out.println(s1==s2);
//false
System.out.println(s1.equals(s2));
//true,String类复写了Object类中equals方法,
//该方法用于判断字符串是否相同。
}
}
|
说到java中堆、栈和常量池,首先还是看看他们各自存放的数据类型吧!
堆:存放所有new出来的对象;
栈:存放基本类型的变量数据和对象的应用,对象(new出来的对象)本身并不存在栈中,而是存放在堆中或者常量池中(字符串常量对象存放在常量池中);
常量池:存放基本类型常量和字符串常量。
对于栈和常量池中的对象可以共享,对于堆中的对象不可以共享。
栈中的数据大小和生命周期是可以确定的,当没有引用指向数据时,这个数据就会自动消失。
堆中的对象的由垃圾回收器负责回收,因此大小和生命周期不需要确定,具有很大的灵活性。
<一>字符创String
而对于字符串来说,其对象的引用都是存储在栈中的.
如果是编译期已经创建好(即指用双引号定义的)的就存储在常量池中,如果是运行期(new出来的对象)则存储在堆中。
对于equals相等的字符串,在常量池中是只有一份的,在堆中则有多份。
String str1="abc";//编译期就创建好了,存在常量池中
String str2="abc";
String str3="abc";
String str4=new String("abc");//运行期new出来的
String str5=new String("abc");
对于浅蓝色箭头,通过new操作产生一个字符串(“abc”)时,
会先去常量池中查找是否有“abc”对象,如果没有则在常量池中创建一个此字符串对象,
然后堆中再创建一个常量池中此“abc”对象的拷贝对象,
所以,对于String str=new String("abc"),如果常量池中原来没有"abc"则产生两个对象,否则产生一个对象。
<二>基本类型和基本类型的常量
变量和引用变量--------变量和引用存储在栈中
常量:-------------存储在常量池中
int a1 = 1, a2 = 1, a3 = 1;
public static final int INT1 = 1;
public static final int INT2 = 1;
public static final int INT3 = 1;
<三>成员变量和局部变量
对于成员变量和局部变量来说,
成员变量是方法外部,类得内部定义的变量;
局部变量就是方法或语句块内部定义的变量,注意,局部变量必须初始化。
局部变量(形式参数)的数据存于栈内存中,并且它(局部变量)随方法的消失而消失。
我们的程序里不可避免大量使用字符串处理,避免使用String,应大量使用StringBuffer,
因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象,请看下列代码;
- String s = "Hello";
- s = s + " world!";
- String s = "Hello";
- s = s + " world!";
在这段代码中,s原先指向一个String对象,内容是”Hello”,
然后我们对s进行了+操作,那么s所指向的那个对象是否发生了改变呢?
答案是没有。这时,s不指向原来那个对象了,而指向了另一个String对象,内容为”Hello world!”;
原来那个对象还存在于内存之中,只是s这个引用变量不再指向它了。
通过上面的说明,我们很容易导出另一个结论,
如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销。
因为String对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个String对象来表示。
这时,应该考虑使用StringBuffer类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。
并且,这两种类的对象转换十分容易。
2.创建功能方法---------------****笔试面试有****
1.1
int
length()
//数组中也有但是属性arr.length,这个是方法
1.2
char
charAt()
// str.chatAt(4)=='c';不是""是''
//sop(str.charAt(4);//当访问到字符串中不存在的角标时会发生StringIndexOutOfBoundsException。
1.3
int
indexOf(
int
ch)
//ch在字符串中第一次出现的位置
int
indexOf(
int
ch,
int
fromIndex)
//从fromIndex指定位置开始,获取ch在字符串中出现的位置
//str.indexOf('m',3));//如果没有找到,返回-1.
int
indexOf
(String str)
int
indexOf(String str,
int
fromIndex)
int
lastIndexOf(
int
ch)
//反向索引一个字符出现位置,注意字符的角标固定无论正向反向
2.1
boolean
contains()**
//特殊之处:indexOf(str):可以索引str第一次出现位置,如果返回-1.表示该str不在字符串中存在。
//所以,也可以用于对指定判断是否包含。
//if(str.indexOf("aa")!=-1)
//而且该方法即可以判断,有可以获取出现的位置。
2.2
boolean
isEmpty()
2.3
boolean
startsWith(str)
2.4
boolean
endsWith(str)
2.5
boolean
equals(str)
//复写了Object类中的equals方法。
2.6
boolean
equalsIgnoreCase()
//判断内容是否相同,并忽略大小写。
用户登录
3.1
构造方法:将字符数组转成字符串
String(Byte[])//默认字符集String( Byte[ ],charsetName)//制定字符集,把字节转换成String
String(
char
[])
String(
char
[],offset,count)
//将字符数组中的一部分转成字符串。
静态方法:
static
String copyValueOf(
char
[])
//将返回指定数组中表示该字符序列的String
static
String copyValueOf(
char
[] data,
int
offset,
int
count)
static
String valueOf(
char
[]):
3.2
char
[] toCharArray():
// ** 将字符串转成字符数组
String s1 =
"zxcvbnm"
;
char
[] chs = s1.toCharArray();
3.3
String(
byte
[])
String(
byte
[],offset,count):将字节数组中的一部分转成字符串。
3.4
byte
[] getBytes():
//把String转化成字节数组byte[],和toCharArray()不同byte
[] getBytes(charsetName):
//带字符集
3.5
static
String valueOf(
int
)
static
String valueOf(
double
)
//形式1:3+"";
//形式2:String.valueOf(3);// 特殊:字符串和字节数组在转换过程中,是可以指定编码表的 。//形式3:Integer.toString( 34 ); //将整数34变成“34”
4.1
String replace(oldchar,newchar);//与StringBuffer的返回值类型不同.
//StringBuffer replace(int start, int end, String str)
String s =
"hello java"
;
String s1 = s.replace(
'q'
,
'n'
);
//如果要替换的字符不存在,返回的还是原串。
String s1 = s.replace(
"java"
,
"world"
);
sop(
"s="
+s);
//s不变,因为字符串一旦初始化就不可以改变
sop(
"s1="
+s1);
//hello world
5.1
String[] split(regex);
String s =
"zhagnsa,lisi,wangwu"
;
String[] arr = s.split(
","
);
//切割符不会出现在数组中
6.1
String substring(begin);
从指定位置开始到结尾。如果角标不存在,会出现字符串角标越界异常。
String substring(begin,end);
//end是角标值,不是个数包含头,不包含尾。s.substring(0,s.length());
7.1
String toUpperCase();
String toLowerCase();
7.2
String trim();
//去除字符串两边的空格,字符串中间的空格不会去除
7.3
int
compareTo(string);
//返回值是ASCLL值得差值
String s1 =
"a1c"
;
String s2 =
"aaa"
;
sop(s1.compareTo(s2));
//返回值是-48=49('1')-97('a')
3.String函数练习
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
1
,模拟一个trim方法,去除字符串两端的空格。
思路:
1
,判断字符串第一个位置是否是空格,如果是继续向下判断,直到不是空格为止。
结尾处判断空格也是如此。
2
,当开始和结尾都判断到不是空格时,就是要获取的字符串。
//===================================================================
2
,将一个字符串进行反转。将字符串中指定部分进行反转,
"abcdefg"
;abfedcg
思路:
1
,曾经学习过对数组的元素进行反转。
2
,将字符串变成数组,对数组反转。
3
,将反转后的数组变成字符串。
4
,只要将或反转的部分的开始和结束位置作为参数传递即可。
//===================================================================
3
,获取一个字符串在另一个字符串中出现的次数。
"abkkcdkkefkkskk"
思路:
1
,定义个计数器。
2
,获取kk第一次出现的位置。
3
,从第一次出现位置后剩余的字符串中继续获取kk出现的位置。
每获取一次就计数一次。
4
,当获取不到时,计数完成。
//===================================================================
4
,获取两个字符串中最大相同子串。第一个动作:将短的那个串进行长度一次递减的子串打印。
"abcwerthelloyuiodef"
"cvhellobnm"
思路:
1
,将短的那个子串按照长度递减的方式获取到。
2
,将每获取到的子串去长串中判断是否包含,
如果包含,已经找到!。
//===================================================================
对字符串中字符进行自然顺序排序。
思路:
1
,字符串变成字符数组。
2
,对数组排序,选择,冒泡,Arrays.sort();
3
,将排序后的数组变成字符串。
"vcz1bdAa+cs"
-->abccdsvz
//===================================================================
作业:
"12 0 99 -7 30 4 100 13"
要求对字符串中的数值进行排序。生成一个数值从小到大新字符串。
"-7 0 4 12 13 30 99 100"
//===================================================================
|
1,长度是可变化的。数组也是容器,但长度固定2,可以 直接操作多个数据类型。3,最终会通过toString方法变成字符串。
1,存储。StringBuffer append():将指定数据作为参数添加到已有数据结尾处。StringBuffer insert(index,数据):可以将数据插入到指定index位置。
12345678StringBuffer sb =
new
StringBuffer();
StringBuffer sb1 = sb.append(
34
);
sop(
"sb==sb1:"
+(sb==sb1));
//true,脸盆原理(蒸馒头发面,加上面,再加上水,面盆没换)
//******************************************
StringBuffer sb =
new
StringBuffer();
sb.append(
"abc"
).append(
true
).append(
34
);
//方法调用列,对象调用完方法返回的还是对象本身
sop(sb.toString());
//abctrue34
sb.insert(
1
,
"qq"
);
//aqqctrue34
2,删除。StringBuffer delete(start,end):删除缓冲区中的数据,包含start,不包含end。StringBuffer deleteCharAt(index):删除指定位置的字符。
1234StringBuffer sb =
new
StringBuffer(
"abcde"
);
sb.delete(
1
,
3
);
//包含头不包含尾部
sb.delete(
0
,sb.length());
//
**
清空缓冲区。
sb.deleteCharAt(
2
);
//一个形式sb.delete(2,3);
3,获取。char charAt(int index)int indexOf(String str)int lastIndexOf(String str)int length()String substring(int start, int end) ; //此方法返回的还是String类型,不是StringBuffer4,修改。StringBuffer replace(start,end,string);void setCharAt(int index, char ch) ;// 这个比较特殊,返回的是空
123StringBuffer sb =
new
StringBuffer(
"abcde"
);
sb.replace(
1
,
4
,
"java"
);
//结果ajavae
sb.setCharAt(
2
,
'k'
);
//结果abkde
5,反转。StringBuffer reverse();// 自己可以写//练习二:将字符串反转。
思路:
1,将字符串变成数组。
2,对数组反转。
3,将数组变成字符串。
6, 将缓冲区中指定数据存储到指定字符数组中。void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
123StringBuilder sb =
new
StringBuilder(
"abcdef"
);
char
[] chs =
new
char
[
6
];
sb.getChars(
1
,
4
,chs,
1
);/从
1
到
4
的字符串存到chs中去,从chs的
1
角标开始的
5,StringBuilder
将 StringBuilder 的实例用于多个线程是不安全的。如果需要这样的同步,则建议使用 StringBuffer。JDK1.5 版本之后出现了StringBuilder.StringBuffer是线程同步.<------- (安全的,因为有锁)StringBuilder是线程不同步。
单线程StringBuilder效率高;以后开发,建议使用StringBuilder,对于多线程,可以自己加锁
**********************************************************************************************************************************************************************************************java的所有升级大体围绕这三个因素:1,提高效率。2,简化书写。3,提高安全性。
封装成类后的一些属性值:
12//整数类型的最大值。
sop(
"int max :"
+Integer.MAX_VALUE);//MIX_VALUE
byte Byte short short int Integer long Long float Float double Double char Character boolean Boolean
6.1.基本数据类型转成字符串
1.1,String str = 基本数据类型+“”;1.2 ,Integer.toString( 34 ); //将整数34变成“34"1.3,String.valueOf(3);//特殊:字符串和字节数组在转换过程中,是可以指定编码表的。
********************************************************************6.2.字符串转成基本数组类型
12345int
a = Integer.parseInt(
"123"
);
Integer i =
new
Integer(
"123"
);
int
num = i.intValue();
//先包装成对象,在调用方法转换double
b = Double.parseDouble(
"12.23"
);
boolean
b = Boolean.parseBoolean(
"true"
);
对于Char型本身就是String的组成单位,不用转换课直接使用一些方法
**************************************************************************
6.3十进制转成其他进制static String toBinaryString();
toHexString();toOctalString();
123sop(Integer.toBinaryString(
6
));
//结果110
sop(Integer.toHexString(
60
));
//结果3c
sop(Integer.toOctalString(
60
));
//结果74
***************************************************************
6.4其他进制转成十进制。parseInt(string,radix);
1234567891011parseInt(
"0"
,
10
) 返回
0
parseInt(
"473"
,
10
) 返回
473
parseInt(
"-0"
,
10
) 返回
0
parseInt(
"-FF"
,
16
) 返回 -
255
parseInt(
"1100110"
,
2
) 返回
102
parseInt(
"2147483647"
,
10
) 返回
2147483647
parseInt(
"-2147483648"
,
10
) 返回 -
2147483648
parseInt(
"2147483648"
,
10
) 抛出 NumberFormatException
parseInt(
"99"
,
8
) 抛出 NumberFormatException
parseInt(
"Kona"
,
10
) 抛出 NumberFormatException
parseInt(
"Kona"
,
27
) 返回
411787
7,基本数据类型对象包装类新特性
7.1
1234Integer x =
new
Integer(
"123"
)
Integer y =
new
Integer(
123
);
System.out.println(x==y);
//false
System.out.println(x.equals(y));
//true,重载只比较数值
7.27.4********
1234567//Integer x = new Integer(4);
Integer x =
4
;
//4是对象,自动装箱。//new Integer(4)
//注意:x的值除了为整数,还可以是null,小心空指针异常,是runtime异常会停掉
x = x +
2
;
//x+2: x进行自动拆箱。变成成了int类型。和2进行加法运算。
//再将和进行装箱赋给x。
//代码如下x = x.intValue() + 2;
12345678Integer m =
128
;
Integer n =
128
;
sop(
"m==n:"
+(m==n));
//结果false
Integer a =
127
;
Integer b =
127
;
sop(
"a==b:"
+(a==b));
//结果为true。因为a和b指向了同一个Integer对象。
//因为当数值在byte范围内容,对于新特性,如果该数值已经存在,则不会在开辟新的空间