Java学习12(String)
Posted Zephyr丶J
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java学习12(String)相关的知识,希望对你有一定的参考价值。
Java学习12
搞了半天最后还是做项目了,好好加油干吧,争取弄出来我也就安心了
String
1.Java中随便使用双引号括起来的都是String对象,例如:“abc”、“def”“hello world”
2.Java中规定,双引号括起来的字符串,不可变
为啥不可变:
我看过源代码,String类中有一个byte[]数组,byte数组是用final修饰的,因此数组一旦创建长度不可变,并且被final修饰的引用一旦指向某个对象以后,不可再指向其他对象,所以String不可变!
那为啥StringBuffer/StringBuilder是可变的?
我看过源代码,它们内部实际上一个byte[]数组,这个byte[]数组没有被final修饰,它们的初始化容量我记得应该是16,当存满之后会进行扩容,底层调用了数组拷贝的方法,System.arraycopy()...是这样扩容的。所以它们适合于频繁的字符串拼接操作
3.JDK当中双引号括起来的字符串,例如“abc”都是直接存储在方法区的“字符串常量池”当中的(因为字符串在是实际的开发中使用的太频繁,为了执行效率,所以把字符串放到了方法区的字符串常量池中)
4.String s = new String("xy"); //xy存储在字符串常量池中,在堆中创建了一个String对象,其中存储了xy的内存地址,在栈中创建了变量s,其中保存的是String对象的内存地址
String s1 = “abc”; s1里面保存的不是“abc”字符串,保存的是“abc”字符串对象的内存地址
5. String s1="hello";
String s2="hello";
System.out.println(s1==s2) //由于hello存储在方法区的字符串常量池中,所以hello对象只有一个,s1和s2中存储的地址是一样
Stirng对象的比较不能用“==”,应该用String中重写equals方法
(****)垃圾回收器是不会释放常量的
6.String类中的常用构造方法和方法
public class StringTest {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2); //true
String s3 = new String("xyz");
String s4 = new String("xyz");
System.out.println(s3 == s4); //false
System.out.println(s3.equals(s4)); //true
// 构造方法测试
byte[] bytes = {97,98,99};
String s5 = new String(bytes); //将byte数组转换为字符串
System.out.println(s5); //abc
//String(字节数组,数组元素下标起始位置,长度);将字节数组一部分转换为字符串
String s6 = new String(bytes,1,2);
System.out.println(s6); //bc
char[] chars= {'a','d','c'};
String charStr = new String(chars);
String charStr2 = new String(chars,1,2);
System.out.println(charStr); //adc
System.out.println(charStr2); //dc
//方法charAt 找出第几个位置的字符
char c1 = "abcdef".charAt(2);
System.out.println(c1); //c
//方法compareTo
int result1 = "abc".compareTo("abc"); //前后一致
System.out.println(result1); //0
int result2 = "abcd".compareTo("abcz"); //前小后大 4-26=-22
System.out.println(result2);
int result3 = "abcf".compareTo("abce"); //前大后小
System.out.println(result3); //1
//方法boolean contains(CharSequence s) 判断前面的字符串是否包含后面的字符串
System.out.println("helloWorld".contains("World"));
//方法boolean endsWith(String suffix) 判断字符串是否以后面的字符串结尾
//方法boolean equalsIgnoreCase(String anotherString) 忽略大小写比较两个字符串
//方法byte[] getBytes() 将字符串转换成byte数组
byte[] bytes1 = "abcedf".getBytes();
for(int i = 0;i < bytes1.length;i++)
System.out.print(bytes1[i]+" "); //97 98 99 101 100 102
//int indexOf(String str) 判断某个子字符串第一次出现在当前字符串的索引
//int lastIndexOf(String str) 判断某个子字符串最后一次出现在当前字符串的索引
//方法 boolean isEmpty() 判断字符串是否为空
//int length() 字符串的长度;判断数组长度是length属性,判断字符串长度是length方法
//String replace(CharSequence target, CharSequence replacement)
//String的父接口就是CharSequence 该方法是替换原有字符串的内容
String newString = "http://baidu.com".replace("http://","https://");
System.out.println('\\n'+newString);
//String[] split(String regex) 以后面的参数拆分字符串,放在一个String数组中
System.out.println(newString.split("//"));
//boolean startsWith(String prefix) 判断字符串是否以某个字符串开始
//String substring(int beginIndex) 从参数位置截取字符串
//String substring(int beginIndex, int endIndex) 起始位置包括,结束位置不包括
System.out.println("http://baidu.com".substring(7,10)); //bai
//char[] toCharArray() 将字符串转换为char数组
//String toLowerCase() 转换为小写
//String toUpperCase() 转换为大写
//String trim() 去除字符串前后空白,中间不能去
//String中只有一个方法是静态的,不需要new对象,这个方法叫做valueOf
//作用是将非字符串 转换为 字符串
String x = String.valueOf(true);
System.out.println(x); //true
String y = String.valueOf(new Customer());
System.out.println(y);
//到此,println输出的时候,是将所有给的数据转换成字符串再输出
}
}
class Customer{
@Override
public String toString() {
return "我爱学习";
}
}
StringBuffer
在实际开发中,如果需要对字符串频繁拼接,因为java中的字符串是不可变的,每一次拼接都会产生新字符串,这样会占用很大的方法区内存,造成内存空间的浪费
如果要频繁进行字符串拼接,建议使用StringBuffer
以后进行字符串的拼接,使用StringBuffer中的append()方法
append方法在底层进行追加的时候,如果byte数组满了,会自动扩容
StringBuffer/StringBuilder初始化容量16.
频繁进行字符串拼接不建议使用“+”
如何优化StringBuffer的性能?
在创建StringBuffer的时候尽可能给定一个初始化容量。
最好减少底层数组的扩容次数,预估计一下,给一个大一点的初始化容量
关键点:给一个合适的初始化容量,可以提高程序的执行效率
StringBuilder
使用StringBuilder也可以进行字符串的拼接
区别:
StringBuffer中的方法都有:synchronized修饰,表示StringBuffer在多线程环境下运行是安全的,
StringBuilder没有synchronized修饰,表示在多线程环境下是非安全的
基础类型对应的8个包装类
8种包装类型属于引用数据类型,父类是Object
为什么要提供8种包装类型?
因为8种数据类型不够用
基本数据类型 包装类型
byte java.lang.Byte(父类Number)
short java.lang.Short(父类Number)
int java.lang.Integer (父类Number)
long java.lang.Long(父类Number)
float java.lang.Float(父类Number)
double java.lang.Double(父类Number)
boolean java.lang.Boolean(父类Object)
char java.lang.Character(父类Object)
Integer
Number是一个抽象类,Number中有intValue、longValue、floatValue...六种拆箱方法
Integer i = new Integer(123); //装箱,将基本数据类型包装成引用数据类型
int x = i.intValue(); //拆箱,将引用数据类型转变为基本数据类型
自动装箱: Integer x = 100;//int自动转换为Integer
自动拆箱: int y = x; // Integer自动转换为int
z=x+1; // 会将x自动转换成基本数据类型进行计算
有了自动拆箱之后,Number中的方法就用不着了!
Java5之后,自动装箱和自动拆箱为了方便编程
(*****)特殊情况:
java中为了提高程序的执行效率,将-128到127之间所有的包装对象提前创建好,放到了一个方法区的“整数型常量池”当中,
目的是只要这个区间的数据不需要new了,直接从整数型常量池取出来
Integer类加载的时候,会初始化整数型常量池:256个对象 (池就是缓存cache)
缓存优点:效率高
缓存缺点:耗费内存
Integer x = new Integer(100); //出现横线表示已经过时了
Integer y = new Integer("123"); //将字符串转换成int
//Integer z = new Integer("中国"); //数字格式化异常:NumberFormatException
System.out.println(x+" "+y); //100 123
Integer a = new Integer("中文");
//编译没问题,运行报错:java.lang.NumberFormatException
常用方法:static int parseInt(String s);将字符串转换为int
static String toHexString(int i); //将十进制转换为十六进制字符串
static String toOctalString(int i); //将十进制转换为八进制字符串
static String toBinaryString(int i); //将十进制转换为二进制字符串
static Integer valueof(int i); //int-->Integer
static Integer valueof(String s); //String-->Integer
//see ghost
Integer a = 128;
Integer b = 128;
//java中为了提高程序的执行效率,将-128到127之间所有的包装对象提前创建好,
//放到了一个方法区的“整数型常量池”当中,目的是只要这个区间的数据不需要new了,
//直接从整数型常量池取出来
//原理:x中保存的对象内存地址和y中保存的对象内存地址是一样的,没有在堆中创建对象
Integer x = 5;
Integer y = 5;
System.out.println(a==b);
System.out.println(x==y);
//static int parseInt(String s)
//网页上文本框中输入的100实际上是字符串,后台数据库需要将其转换为数字100
int retValue = Integer.parseInt("123");
System.out.println(retValue+100); //223
int i = 100;
String s = i + "";
System.out.println(s); //100
已学经典异常
空指针异常:NullPointerException
类型转换异常: ClassCastException
数组下标越界异常:ArrayIndexOutOfBoundException
数字格式化异常:NumberFormatException
special:
int i=100;
String s=i+“”;(将整数转换成字符串)
三种类型转换
以上是关于Java学习12(String)的主要内容,如果未能解决你的问题,请参考以下文章
201621123037 《Java程序设计》第9周学习总结
java.lang.NullPointerException: Attempt to invoke virtual method ‘int android.database.sqlite异常(代码片段
Failed to convert property value of type ‘java.lang.String‘ to required type ‘int‘ for property(代码片段