一,String类讲解
java.lang.String:是字符串类型
1,字符串一旦创建不可再改变。“abc”字符串对象一旦创建,不可再改变成“abcd”。
2,提升字符串的访问效率:在程序中使用了“缓存技术”。所以在java中所有使用“双引号”括起
来的字符串都会在“字符串常量池”中创建一份。字符串常量池在方法区中被存储。
3,在程序执行过程中,如果程序用到某个字符串,例如“abc”,那么程序会在字符串常量池中去
搜索该字符串,如果没有找到则在字符串常量池中新建一个“abc”字符串,如果找到就直接拿过来用。
(字符串常量池是一个缓存区,为了提高访问字符串的效率)。
public class StringTest{
public static void main(String[] args){
//创建一个“abc”字符串对象,该对象的内存地址,让S1变量保存
//S1是一个引用,S1指向“abc”对象
String s1="abc";
//可以让S1重新指向吗?S1是局部变量,S1前边没有final,所以S1可以重新指向,但是“def”字符串本身不可变。
s1="def";
//在字符串常量池中新建一个“Hello”字符串对象,该对象不可改变。
String s2="Hello";
String s3="Hello";//从字符串常量池中直接拿出来用。
System.out.println(s2==s3);//true
//比较两个字符串是否相等,不能用“==”;用”equals“方法
String s4=new String("abc");
String s5=new String("abc");
System.out.println(s4.equals(s5));
//以下程序执行结束之后,会在字符串常量池中创建3个字符串对象。
“aaa”;“bbb”;“aaabbb”;
String s6="aaa";
String s7="bbb";
String s8=s6+s7;
}
}
二,创建字符串对象的区别?
1,String s1="abc";只会在字符串常量池中创建一个“abc”字符串对象。
String s2=new String("Hello");会在字符串常量池中创建一个“Hello”字符串对象,
并且会在堆内存中再创建一个字符串对象。
第二种方式比较浪费内存,常用的是第一种方式。
public class StringTest{
public static void main(String[] args){
String s1="abc";
String s2=new String("Hello");
}
}
三,String类
面试题
public class StringTest{
public static void main(String[] args){
//判断以下程序创建了几个对象?3个,堆中2个,方法区1个。
String s1=new String("Hello");
String s2=new String("Hello");
}
}
使用String的时候,我们注意的问题:尽量不要做字符串频繁的拼接操作,因为字符串
一旦创建不可改变,只要频繁拼接,就会在字符串常量池中创建大量的字符串对象,给垃圾
回收器带来问题。
四,String常用的方法
1,String字符串常用构造方法
public class StringTest3{
public static void main(Sting[] args){
// 1种
String s1="abc";
// 2种
String s2=new String("abc");
// 3种
byte[] bytes={97,98,99,100};
String s3=new String(bytes);
System.out.println(s3);//abcd String已经重写Object中toStri
// 4种
String s4=new String(bytes,1,2);
System.out.println(s4);
// 5种
char[] c1={'我','是','中','国','人'};
String s5=new String(c1);
System.out.println(s5);//我是中国人
// 6种
String s6=new String(c1,2,2);
System.out.println(s6);//中国
}
}
2,String字符串常用方法上
public static void main(String[] args){
// 1种:char charAt(int index) 返回指定索引处的char值。
char c1="abcdef".charAt(2);
System.out.println(c1);//c
// 2种:boolean endsWith(String endStr) 测试此字符串是否以指定的后缀结束。
System.out.println("HelloWorld.java".endsWith("java"));//true
System.out.println("HelloWorld.java".endsWith("txt"));//false
// 3种:boolean equalsIgnoreCase(String anotherString); 将此String与另一个String比较,不考虑大小写。
System.out.println("abc".equalsIgnoreCase("ABC"));//true
// 4种:byte[] getBytes[];//使用平台的默认字符集将此String编码为byte序列,并将结果存储到一个新的byte数组中。
byte[] bytes="abc".getBytes();
for(int i=0;i<bytes.length;i++){
System.out.println(bytes[ i ]);// 97 98 99
}
// 5种:int indexOf(String str); 返回指定字符串在此字符串中第一次出现处的索引。
System.out.println("http://192.168.1.100:8080/oa/logth.com".indexOf("/oa"));//25
// 6种:int indexOf(String str,int fromIndex); 返回指定子字符串在此字符串第一次出现处的索引从指定的索引开始。
System.out.println("javaoraclec+javavb".indexOf("java",1));//13
// 7种:int lastIndexOf(String str) 返回指定字符串在此字符串中最右边出现处的索引
System.out.println(""javaoraclec+javavb".lastIndexOf("java");//13
// 8种:int lastIndexOf(String str,int fromIndex); 返回指定子字符串在此字符串中最后一次出现处的索引,从指定
的索引开始反向搜索;
// 9种:int length(); 返回此字符串的长度。
System.out.println("abc".length());//数组是length属性,String是length()方法;
// 10种:String replaceAll(String regex,String replacement); 使用给定的replacement替换此字符串所有匹配
给定的正则表达式的子字符串。
System.out.println("javaorclec++javavb".replaceAll("java","mysql")); //这个程序时4个字符串 结果:mysqloraclec++mysqlvb
// 11种 :String[] split(String regex); 根据给定正则表达式拆分此字符串
String myTime="2008,08,08";
String[] ymd=myTime.split(",");
for(int i=0;i<ymd.length;i++){
System.out.println(ymd[ i ]);
}
// 12种:boolean startsWith(String prefix); 测试此字符串是否以指定的前缀开始。
System.out.println("/System/login.action",startsWith("/"));true
// 13种:String substring(int beginIndex); 截取新的字符串,返回一个新的字符串,它是此字符串的一个子字符串。
System.out.println("/oa/length.action".substring(3));// /length.cation
// 14种:String substring(int beginIndex,int endIndex); 返回一个新的字符串,它是此字符串的一个子字符串。
System.out.println("/oa/length.action".substring(4,9)); //length
// 15种:char[] toCharArray(); //将此字符串转换为一个新的字符串数组。
char[] c1="我是中国人".toCharArray();
for(int i=0;i<c1.length;i++){
System.out.println(c1[ i ]);
}
// 16种:String toLowerCase(); 转换为小写
System.out.println("ABCDEF".toLowerCase());
// 17种:String toUpperCase(); 转换为大写
System.out.println("abcdef".toUpperCase());
// 18种:String trim(); //返回字符串的副本,忽略前导空白和尾部空白
System.out.println(" a bcd e ".trim());// a bcd e
// 19种static String valueOf(Object obj); 返回Object参数的字符串表示形式。
Object o=null;
System.out.println(o);//不会,因为并不是直接调用toString方法,string.valueOf(Object)这个方法对空值进行处理了。
System.out.println(String.value(o));//底层调用就是这个
//System.out.println(o.toString());//会出现空指针。
}
五,StringBuffer和StringBuilder
1,StringBuffer和StringBuilder是什么?
是一个字符串缓冲区。
2,工作原理
预先在内存中申请一块空间,以容纳字符序列,如果预留的空间不够用,则进行自动扩容,
以容纳更多字符序列。
3,StringBuffer StringBuilder String最大的区别?
String是不可变得字符序列,存储字符串常量池中。
StringBuffer底层是一个char数组,但是该char数组是可变的。并且可以自动扩容。
4,StringBuffer和StringBuilder的默认初始化容量是16.
5,如何优化StringBuffer和StringBuilder呢?
最好在创建StringBuffer之前,预测StringBuffer的存储字符数量,然后再创建StringBuffer的时候
采用指定初始化容量的方式创建StringBuffer,为减少底层数组的拷贝,提高效率。
public class Test1{
public static void main(String[] args){
//创建字符串缓冲区对象
StringBuffer sb=new StringBuffer(); //16
//可能向StringBuffer中追加字符串
String[] ins={"体育","音乐","睡觉","美食"};
//推荐字符串频繁拼接使用StringBuffer或者StringBuilder
for(int i=0;i<ins.length;i++){
if(i==ins.length-1){
sb.append(ins[ i ]);
}else{
sb.append(ins[ i ]);
sb.append(",");
}
}
System.out.println(sb);
}
}
六,StringBuffer和StringBuilder的区别?
StringBuffer是线程安全的。(可以在多线程的环境下使用不会出现问题)。
StringBuilder是非线程安全的,(在多线程环境下使用可能出现问题)。
七,包装类型
java中八种基本数据类型对应的包装类型:
基本数据类型 包装类型
byte java.long.Byte;
short java.long.Short;
int java.long.Integer;
long java.long.Long;
float java.long.Float;
double java.long.Double;
boolean java.long.Boolean;
char java.long.Character;
思考:java中提供的八种基本数据类型不够用吗?为什么java中还要提供对应的包装类型呢?
答:方便。
public class Integer01{
public static void main(String[] args){
//基本数据类型
byte b=10;
//引用类型
Byte b1=new Byte(b);
m1(b1);//10 byte已经将Object中的toString方法重写
}
//需求:规定m1方法可以接收java中任何一种数据类型。
//m1方法如果想接收byte类型的数据,可以将byte类型先包装成java.lang.byte;再传递参数。
public static void m1(Object o){
System.out.println(o);
}
}
八,Integer类
以java.lang.Integer;类型为例,讲解八种类型。
1,
public class IntegerTest2{
public static void main(String[] args){
//获取int类型的最大值和最小值
System.out.println("int最小值:"Integer.MIN_VALUE);
System.out.println("int最大值:"Integer.MAX_VALUE);
//以int推byte
System.out.println("byte最小值:"Byte.MIN_VALUE);
System.out.println("byte最大值:"Byte.MAX_VALUE);
创建Integer类型对象
Integer i1=new Integer(10);//int--->Integer
Integer i2=new Integer("12")//String--->Integer
System.out.println(i1);//10
System.out.println(i2);//12
//以下程序
//编译可以通过。但是运行的时候会报异常,数字格式化异常。虽然可以将字符串转换成Integer
类型,但是该字符串也必须是“数字字符串”。
//Integer i3=new Integer("abc");//NumberFormatException
}
}
2,关于Integer中常用的方法
public class IntegerTest3{
public static void main(String[] args){
//int--->Integer
//基本数据类型--->引用类型
Integer i1=new Integer(10);
//Integer--->int
int i2=i1.intValue();
System.out.println(i2+1);//11
//重要:static int parseInt(String s)
//String--->int
int age=Integer.parseInt("25");
System.out.println(age+1);//26
//"abc"这个字符串必须是"数字字符串"才行。
//int price=Integer.parseInt("abc");//NumberFormatException
//重要:static double parseDouble(String s);
double price=double.parseDouble("3.0");
System.out.println(price+1.0);//4.0
//将int类型的十进制转换成2进制
String s1=Integer.toBinaryString(10);
System.out.println(s1);//1010
//将int类型的十进制转换成16进制
String s2=Integer.toHexString(10);
System.out.println(s2);//a
//将int类型的十进制转换成8进制
String s3=Integer.toOctalString(10);
System.out.println(s3);//12
//int--->Integer
Integer i3=Integer.ValueOf(10);
//String--->Integer
Integer i4=Integer.ValueOf("10");
System.out.println(i3);//10
System.out.println(i4);//10
}
}
3,Integer int String
三种类型相互转换
public class IntegerTest4{
public static void main(String[] args){
//1, int--->Integer
Integer i1=Integer.ValueOf(10);
//2 , Integer--->int
int i3=i1.intValue();
//3, String--->Integer
Integer i2=Integer.ValueOf("10");
//4,Integer--->String
String s1=i2.toString();
//5, String--->int
int i4=Integer.parseInt("123");
//6, int--->String
String s2=10+"";
}
}
九,自动装箱和自动拆箱
1,自动装箱(auto_boxing)和自动拆箱(auto_unboxing)。
以上特性适合JDK1.5版本之后的。包括1.5
public class IntegerTest5{
public static void main(String[] args){
//JDK1.5之前的
//int--->Integer(装箱)
integer i1=new Integer(10);
//Integer--->int(拆箱)
int i2=i1.intValue();
//JDK1.5之后的
Integer i3=10;//自动装箱
int i4=i3;自动拆箱
System.out.println(i3);//10
System.out.println(i4);//11
//JDK1.5之后
m1(321);//自动装箱。
System.out.println(m2(10,5)+1);//自动装箱
}
public static void m1(Object o){
System.out.println(o);
}
public static void m2(Integer i1,Integer i2){
return i1-i2;//自动装箱
}
}
2,深入自动装箱和深入自动拆箱:
A,自动装箱和自动拆箱是程序编译阶段的一个概念,和程序运行无关。
B,自动装箱和自动拆箱主要目的是方便程序员编码。
public class IntegerTest6{
public static void main(String[] args){
Integer i1=new Integer(10);
Integer i2=new Integer(10);
//这里不会有自动拆箱
System.out.println(i1==i2);//false
//比较两个Integer类型的数据是否相等,不能用"==",Integer已经重写了Object中的equals方法。
System.out.println(i1.equals(i pp 2));//true
//重点:
Integer i3=128;
Integer i4=128;
System.out.println(i3==i4);//false
//注意以下程序:
//如果数据是在(-128~127)之间,java中引入了一个“整型常量池”在方法区中,
该整型常量池只存储-128~127之间的数据。
Integer i5=127;//这个程序不会在堆中创建对象,会直接从整型常量池中拿。
Integer i6=127;
System.out.println(i5==i6);//true
Integer i7=-128;
Integer i8=-128;
System.out.println(i7==i8);//true
Integer i9=-129;
Integer i10=-129;
System.out.println(i9==i10);//false
}
}
十,获取当前系统时间秒数
1,
public class DateTest{
public static void main(String[] args){
Long now=System.currentTimeMillis();
System.out.println(now);
}
}
2,
import java.util.Date;
import java.text.SimpleDateFormat;
public class DateTest1{
public static void main(String[] args){
//获取系统当前时间
Date nowTime=new Date();
System.out.println(nowTime);
//以上程序说明java.util.Date;已经重写了Object中的toString方法。只不过重写的方法是英文。
//所以引入"格式化"日期。
//java.util.Date--->String
/*
y 年
M 月
d 日
H 小时
m 分
s 秒
S 毫秒
*/
//创建日期格式化对象
SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss SSS");
//开始格式化(Date--->String)
String strTime=sdf.format(nowTime);
System.out.println(strTime);
}
}
3,
获取特定日期
import java.util.Date;
import java.text.SimpleDateFormat;
public class DateTest2{
public static void main(String[] args)throws Exception{
String strTime="2008年08日08 08:08:08 888";
//将String日期转换成日期类型Date
//String--->Date
//创建日期格式化对象
SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss SSS");//格式不能改,和上面一样
//将字符串转换成日期类型
Date t=sdf.parse(strTime);
System.out.println(t);
}
}
4,
获取当前时间的前10分钟
Date d=new Date(long millis);
import java.util.Date;
import java.text.SimpleDateFormat;
public class DateTest3{
public static void main(String[] args){
//1000是从1997-1-1 00:00:00 000的毫秒数
Date t1=new Date(1000);
//Date--->String
SimpleDateFormat sdf=new SimpleDateFormat("yyyy,MM,dd HH:mm:ss SSS");
//北京时间要快8小时
System.out.println(sdf.format(t1));
//获取当前系统时间的前10分钟
Date t2=new Date(System.currentTimeMillis()-100米60米10);
System.out.println(sdf.format(t2));
System.out.println(sdf.format(new Date()));
}
}
十一,日历Calendar
import java.util.Calendar;
import java.util.Date;
import java.text.*;
public class DateTest4{
public static void main(String[] args){
//获取系统当前的日历
Calendar c=Calendar.getInstance();
//查看当前日历的星期“几”;
int i=c.get(Calendar.DAY_OF_WEEK);
System.out.println(i);//3 (中国星期日,外国人看作第1天);
System.out.println(c.get(Calendar.DAY_OF_MONTH));//31
//获取2008,8, 8是星期几?获取2008,8, 8的日历?
String strTime="2008,08,08";
Date d=new SimpleDateFormat("yyyy,MM,dd").parse(strTime);
c.setTime(d);
//获取星期几?
System.out.println(c.get(Calendar.DAY_OF_WEEK));//6
}
}
十二,数字化DecimalFormat
1,关于数字格式化:java.text.DecimlFormat;
数字格式化元素:
# 任意数字
, 千分位
. 小数点
0 不够补0
import java.text.DecimalFormat;
public class NumberTest1{
public static void main(String[] args){
//创建数字格式化对象
//需求:加入千分位
DecimalFormat df=new DecimalFormat("###,###");
//开始格式化
//Number--->String
System.out.println(df.format(1234567));//"1,234,567";
//需求:加入千分位,保留2位小数
DecimalFormat df1=new DecimalFormat("###,###.##");
System.out.println(df1.format(1234567.123));//"1,234,567.12";
//需求:加入千分位,保留4位小数,并且不够补0;
DecimalFormat df2=new DecimalFormat("###,###.0000");
System.out.println(df2.format(1234567.123));//"1,234,567,1230";
}
}
2,java.math.BigDecimal;
该类型的数据精确度极高,适合做财务软件,财务软件中double精确度太低。
import java.math.BigDecimal;
public class NumberTest2{
public static void main(String[] args){
//创建大数据
BigDecimal v1=new BigDecimal(10);
BigDecimal v2=new BigDecimal(20);
//做加法运算
//v1+v2;//错误,两个引用类型不能做加法运算
//必须调用方法执行加法运算
BigDecimal v3=v1.add(v2);
System.out.println(v3);//30
}
}
十三,Random随机数
1,
import java.util.Random;
public class RandomTest{
public static void main(String[] args){
//创建一个新的随机数生成器
Random r=new Random();
//生成int类型的随机数
//int i=r.nextInt(101);//(0-100)之间的随机数
//System.out.println(i);
//循环生成5个随机数
for(int i=0;i<5;i++){
System.out.println(r.nextInt(101));
}
}
}
2,生成5个不重复的随机数
import java.util.Random;
public class RandomTest1{
public static void main(String[] args){
Random r=new Random();
int[] a=new int[5];
int index=0;
while(index<5){
int temp=r.nextInt(6);
//伪代码
if(temp!=0 && !contains(a,temp)){
a[index++]=temp;
}
}
//遍历
for(int i=0;i<a.length;i++){
System.out.println(a[i]);
}
}
//该方法完成判断temp元素在a数组中是否包含,包含返回true
public static boolean contains(int[] a,int temp){
for(int i=0;i<a.length;i++){
if(a[ i ]==temp){
return true;
}
}
return false;
}
}
十四,枚举
程序中的问题能在编译阶段能解决的,绝对不能放在运行解决。
以上程序可以引用“枚举类型”。
public class EnumTest{
public static void main(String[] args){
int a=10;
int b=0;
Result retValue=divide(a,b);
if(retValue==Result.SUCCESS){
System.out.println("成功");
}else if(retValue==Result.FALL){
System.out.println("失败");
}
}
//实现需求
public static Result divide(int a,int b){
try{
int c=a/b;
return Result.SUCCESS;//成功
}catch(Exception e){
return Result.FALL;//失败
}
}
}
定义一个枚举类型
enum Result{
//成功和失败 注意:规范大小写
SUCCESS,FALL //有限的
}