Java学习记录6 Java常用类
1. 包装类Integer
-
基本数据类型及包装类
-
byte - Byte
-
boolean - Boolean
-
short - Short
-
char - Character
-
int - Integer
-
long - Long
-
float - Float
-
double - Double
-
-
基本数据类型对应的类统称为包装类(Wrapper Class)
-
代码实例
//基本数据类型转成包装类对象
Integer a = new Integer(3);
Integer b = Integer.valueOf(30);//推荐使用
//把包装类对象转成基本数据类型
int c = b.intValue();
double d = b.doubleValue();
//把字符串转成包装类对象
Integer e = new Integer("9999");
Integer f = Integer.parseInt("999888");
//把包装类转换成字符串
String str = f.toString();//""+f
//常见的常量
System.out.println("int类型最大的整数:"+Integer.MAX_VALUE);
2. 包装类-自动装箱、拆箱
-
自动装箱和拆箱就是讲基本数据类型和包装类之间进行自动的互相转换。
-
自动装箱:基本类型的数据处于需要对象的环境中时,会自动转为对象。
-
自动拆箱:每当需要一个值时,对象会自动转成基本数据类型,没必要再去显示调用intValue()等。
-
自动装箱过程是通过编译器自动调用包装类的valueOf()方法实现的,而自动拆箱是编译器自动调用包装类的xxxValue()实现的。
-
自动装箱与拆箱的功能事实上是编译器帮的忙,依据需要的语法进行装箱与拆箱。
-
示例代码:
Integer a = 234;//自动装箱:编译器处理Integer a = Integer.valueDf(234);
int b = a;//自动拆箱:编译器会修改成int b = a.intValue();
Integer c = null;
//java.lang.NullPointerException空指针异常
if(c != null)
{
int d = c;//自动拆箱:调用了:c.intValue();
} -
包装类的缓存问题
//缓存[-128,127]之间的数字,实际是系统初始的时候,创建了[-128,127]之间的一个缓存数组
//当我们调用valueOf()的时候,首先检查是否在[-128,127]之间,如果在这个范围内则直接从缓存数组中拿出已经建好的对象
//如果不在这范围内,则创建新的integer对象
Integer in1 = Integer.valueOf(-128);
Integer in2 = -128;
System.out.println(in1 == in2);//true 因为-128在缓存范围内,所以比较的是内容
System.out.println(in1.equals(in2));//true
System.out.println("*************");
Integer in3 = 1234;
Integer in4 = 1234;
System.out.println(in3 == in4);//false,因为1234不在缓存范围内,比较两个对象的地址,两个不同的对象的地址不同
System.out.println(in3.equals(in4));//true,比较内容,相同
3. String类
String源码分析
-
String类对象代表不可变的Unicode字符序列,因此String对象称为不可变对象。
-
不可变对象指的是对象内部的成员变量的值无法再改变。
//两个字符串的地址改变了,原字符串没改变
String str = "aaabbbvvvv";
System.out.println(Integer.toHexString(str.hashCode()));//70df541
str = str.substring(2);
System.out.println(Integer.toHexString(str.hashCode()));//494c0921//编译器做了优化,直接在编译的时候将字符串进行拼接
String s1 = "h" + "j";//相当于 s1 = hj;
String s2 = "hj";
System.out.println(s1 == s2);//true
//编译的时候不知道变量中存储的是什么,所以没办法在编译的时候优化
String s3 = "h";
String s4 = "j";
String s5 = s3 + s4;
System.out.println(s2 == s5);//false
System.out.println(s2.equals(s5));//true 做字符串比较的时候用equals,不使用==//StringBuilder线程不安全,效率高(一般使用它);StringBuffer线程安全,效率低
StringBuilder sb = new StringBuilder("abcdefg");
System.out.println(Integer.toHexString(sb.hashCode()));
System.out.println(sb);
sb.setCharAt(2, 'M');
System.out.println(Integer.toHexString(sb.hashCode()));
System.out.println(sb);
4. StringBuilder和StringBuffer用法
-
可变字符序列的常用方法
StringBuilder sb = new StringBuilder();
for(int i=0;i<26;i++)
{
//字符串拼接
sb.append((char)('a'+i));
}
System.out.println(sb);
//字符串倒置
sb.reverse();
System.out.println(sb);
//替换字符
sb.setCharAt(3, '高');
System.out.println(sb);
//插入一个字符
sb.insert(3, '陈').insert(4, '你');//链式调用:核心是,该方法调用了return this,把自己返回了
System.out.println(sb);
//删除区间的字符
sb.delete(3 , 5);
System.out.println(sb); -
字符序列使用陷阱
//使用String进行字符串的拼接
String str8 = "";
//本质上使用StringBuilder拼接,但是每次循环都会生成一个StringBuilder对象
long num1 = Runtime.getRuntime().freeMemory();//获取系统剩余内存空间
long time1 = System.currentTimeMillis();//获取系统的当前时间
for(int i=0;i<5000;i++)
{
str8 = str8 + i;//相当于产生10000个对象
}
long num2 = Runtime.getRuntime().freeMemory();//获取系统剩余内存空间
long time2 = System.currentTimeMillis();//获取系统的当前时间
System.out.println("String占用内存:"+(num1 - num2));
System.out.println("String占用时间" + (time2 - time1));
//使用StringBuilder进行字符串拼接
StringBuilder sb1 = new StringBuilder("");
long num3 = Runtime.getRuntime().freeMemory();//获取系统剩余内存空间
long time3 = System.currentTimeMillis();//获取系统的当前时间
for(int i=0;i<5000;i++)
{
sb1.append(i);
}
long num4 = Runtime.getRuntime().freeMemory();//获取系统剩余内存空间
long time4 = System.currentTimeMillis();//获取系统的当前时间
System.out.println("StringBuilder占用内存:"+(num3 - num4));
System.out.println("StringBuilder占用时间" + (time4 - time3));
结果:
String占用内存:50125104
String占用时间49
StringBuilder占用内存:0
StringBuilder占用时间1
5. Date时间类
-
时间处理相关类
-
Date是核心类
-
DateFormat用于字符串和时间对象的转换
-
Calendar:日期类
-
-
long类型变量表示时间
-
获取当前时刻的毫秒数:
long time4 = System.currentTimeMillis();//获取系统的当前时间
//当前时间
Date d = new Date();//Java util包
System.out.println(d);
//获取时间戳2000对应的时间
Date d1 = new Date(2000);
System.out.println(d1);
System.out.println(d1.getTime());//获取时间的毫秒数
System.out.println(d.after(d1));//时间比较
//以后遇到日期处理:使用Calendar日期类
Date d3 = new Date(2020-1900,3,10);
System.out.println(d3);
6. DateFormat类和SimpleDateFormat类
-
DateFormat类的作用
-
把时间对象转化成指定格式的字符串
-
把指定格式的字符串转换成时间对象
-
是一个抽象类,一般使用他的子类SimpleDateFormat类来实现
-
使用时要导入java.text.DateFormat包;
//把时间对象按照"格式字符串指定的格式"转成相应的字符串
DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String str = df.format(new Date(4000000));//返回的是String
System.out.println(str);
//把字符串按照”格式字符串指定的格式“转成相应的时间对象
DateFormat df2 = new SimpleDateFormat("yyyy年MM月dd日 hh时mm分ss秒");
Date date = df2.parse("1983年05月10日 10时45分59秒");
System.out.println(date);
//其他格式,利用D,获取本时间对象是所处年份的第几天
DateFormat df3 = new SimpleDateFormat("D");
String str3 = df3.format(new Date());//返回的是String
System.out.println(str3); -
7. Calendar日历类
-
是一个抽象类,为我们提供了关于日期计算的相关功能
-
GregorianCalendar是Calendar的一个具体子类,提供了世界上大多数国家/地区使用的标准日历系统。
//获取日期的相关元素
Calendar c = new GregorianCalendar(2999,10,9,22,10,50);
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int day = c.get(Calendar.DATE);//也可以使用DAY_OF_MONTH
int weekday = c.get(Calendar.DAY_OF_WEEK);//星期几,1-7,1:星期日,7星期1
System.out.println(c);
System.out.println(year);
System.out.println(month);//0-11,0是1月,11是12月
System.out.println(weekday);
System.out.println(day);
//设置日期的相关元素
Calendar c2 = new GregorianCalendar();
c2.set(Calendar.YEAR, 8012);
System.out.println(c2);
//日期的计算
Calendar c3 = new GregorianCalendar();
c3.add(Calendar.DATE, 100);//往后100天
c3.add(Calendar.YEAR, -100);//往后100年
System.out.println(c3);
//日期对象和时间对象的转化
Date d4 = c3.getTime();//日期转时间
System.out.println(d4);
Calendar c4 = new GregorianCalendar();
c4.setTime(new Date());//时间转日期
System.out.println(c4);//打印:1918年10月10日 11:23:45 周三
String[] dx = {"一","二","三","四","五","六"};
String dayweek1 = "";
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH) + 1;
int date = c.get(Calendar.DAY_OF_MONTH);
int dayweek = c.get(Calendar.DAY_OF_WEEK) - 1;
if(dayweek != 0)
{
dayweek1 = dx[dayweek - 1];
}
String dayweek2 = dayweek == 0 ? "日" : dayweek1+"";
int hour = c.get(Calendar.HOUR);
int minute = c.get(Calendar.MINUTE);
int second = c.get(Calendar.SECOND);
System.out.println(year + "年" + month + "月" + date + "日 " + hour
+ ":" + minute + ":" +second + " 周"+dayweek2);
调用:printCalendar(new GregorianCalendar());
结果:2020年5月29日 10:2:44 周五
8. 可视化日历程序
System.out.println("请输入日期(格式:2020=9-10):");
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
//String str = "2020-9-10";
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
Date date = df.parse(str);
Calendar c= new GregorianCalendar();
c.setTime(date);
int day = c.get(Calendar.DAY_OF_MONTH);
int days = c.getActualMaximum(Calendar.DATE);
System.out.println("日\t一\t二\t三\t四\t五\t六");
c.set(Calendar.DAY_OF_MONTH, 1);
for(int i=0;i<c.get(Calendar.DAY_OF_WEEK)-1;i++)
{
System.out.print("\t");
}
for(int i=1;i<=days;i++){
if(day == c.get(Calendar.DAY_OF_MONTH))
{
System.out.print(c.get(Calendar.DAY_OF_MONTH)+"*\t");
}
else
{
System.out.print(c.get(Calendar.DAY_OF_MONTH)+"\t");
}
if(c.get(Calendar.DAY_OF_WEEK)==Calendar.SATURDAY)
{
System.out.println();