第三部分Java SE-Java应用
第1单元 Java API应用部分学习笔记-续
Part3 StringBuilder和StringBuffer、System、Math、Random、Date和Calendar、Object以及封装类的使用
1.任务3:StringBuilder和StringBuffer使用
(1)面试题String 和 StringBuffer、StringBuilder区别?
- 1.String是不可变字符串类,不可变指的是字符串的内容不可变;后者是可变字符串类。
String str = "china";
String str2 = str.toUpperCase();//问:str 是什么?china
// str2 是 CHINA
str = "tit";
- 2.StringBuffer和StringBuilder是可变字符串类,内容是可变的。
- 3.它们的区别:StringBuffer是线程安全的,StringBuilder是非线程安全的。
- 常用方法: append(); delete(); insert(); reverse(); replace(); length(); charAt();
- 开发中常用在 SQL组合条件查询上,动态拼接SELECT语句。
(2)输入手机号,输出类似188********0221
- replace(int start, int end, String str):用指定的String中的字符替换此序列的子字符串中的String。
public class ChangeMobile {
public String change(String oldMobile) {
StringBuilder stringBuilder = new StringBuilder(oldMobile);
stringBuilder.replace(3, 7, "****");
return stringBuilder.toString();
}
/**不使用可变字符串类*/
public String change2(String oldMobile) {
String first = oldMobile.substring(0,3);
String second = oldMobile.substring(7);
return first + "****" + second;
}
public static void main(String[] args) {
ChangeMobile cm = new ChangeMobile();
System.out.println("请输入您的手机号:");
Scanner scanner = new Scanner(System.in);
String om = scanner.next();
System.out.println("隐藏后的手机号为:" + cm.change(om));
System.out.println("隐藏后的手机号为:" + cm.change2(om));
}
}
(3)输入字符串abc,输出cba
- reverse():导致该字符序列被序列的相反代替。
public class ReverseString {
/**输入字符串abc,输出cba*/
public String reverseStr(String oldStr) {
StringBuilder str1 = new StringBuilder(oldStr);
str1.reverse();
return str1.toString();
}
/**不使用可变字符串*/
public String reverseStr2(String oldStr) {
//abcd
String newStr = "";
for (int i = oldStr.length() - 1; i >= 0; i--) {
char c = oldStr.charAt(i);
newStr = newStr + c;
}
return newStr;
}
public static void main(String[] args) {
ReverseString rs = new ReverseString();
System.out.println(rs.reverseStr("abc"));
System.out.println(rs.reverseStr2("abcd"));
}
}
(4)比较可变字符串的内容
StringBuilder str1 = new StringBuilder("china");
StringBuilder str2 = new StringBuilder("china");
System.out.println(str1.equals(str2));//false
System.out.println(str1 == str2);//false
String str3 = new String("china");
String str4 = new String("china");
System.out.println(str3.equals(str4));//true
System.out.println(str3 == str4);//false
2.任务4:System类的用法
- out和err的区别:err的输出语句会随机出现,而out是按顺序出现;err不会占用缓冲区,而out会占用缓冲区。
(1)输出程序的执行时间:
- System.currentTimeMillis();返回当前时间(以毫秒为单位)。
(2)复制数组元素:
- arraycopy(Object src, int srcPos, Object dest, int destPos,int length);将指定源数组中的数组从指定位置复制到目标数组的指定位置。
public static void main(String[] args) {
int first [] = {100,200,300,400,500};
int second [] = {1,2,3,4,5};
System.arraycopy(first, 1, second, 2, 3);
for (int x : second) {
System.out.println(x + " ");
}
}
(3)垃圾回收(garbage collector)相关方法:
-
System.gc():建议JVM进行垃圾回收,不是强制进行垃圾回收。
-
Runtime.getRuntime().gc()
(4)退出程序:
-
System.exit(n)
-
Runtime.getRuntime().exit(n)
3.任务5:Math类的用法
- 在API文档里看不到Math构造方法,什么原因? 为什么里面的方法被static修饰?
- 答:没有构造方法,因为它的成员全部是静态的。
(1)Math.abs():返回绝对值
(2)Math.ceil():向上取整
- 11.4、11.5 -11.4 -11.49 -11.5 -11.6
- 对以上数进行向上取整分别为:12.0、12.0、-11.0、-11.0、-11.0、-11.0
(3)Math.floor():向下取整
-
12.4、12.5 -12.4 -12.49 -12.5 -12.6
-
对以上数进行向下取整分别为:12.0、12.0、-13.0、-13.0、-13.0、 -13.0
(4)Math.round():四舍五入
- 13.4、13.5 -13.4 -13.49 -13.5 -13.6【面试题】
- 对以上数进行四舍五入分别为:13.0、14.0、-13.0、-13.0、-13.0、-14.0
(5)Math.random() 生成随机数
生成随机数0~1,包含0,不包含1;生成随机小数double【面试题】
(6)(int)(Math.random() * 1000) 生成0-1000的随机整数
4.任务6:Random类的使用
- java.util.Random : 是随机数类
//生成0-1000的随机整数
Random ran = new Random();
int x = ran.next(1000);
5.任务7:Date类和Calendar类使用
(1)java.util.Date:输出系统的当前日期
(2)java.util.Calendar:输出系统当前时间
public class DateUtil {
/** 获得当前日期,使用Date类 */
public static String getCurrentDate() {
Date date = new Date();
//转成本地格式
return date.toLocaleString();
}
/** 使用Calendar获得日期时间*/
public static String getCurrentDateByCalendar() {
Calendar c = Calendar.getInstance();
return "" + c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1) + "-" + c.get(Calendar.DAY_OF_MONTH) + " " + c.get(Calendar.HOUR_OF_DAY) + ":" + c.get(Calendar.MINUTE) + ":" + c.get(Calendar.SECOND);
}
public static void main(String[] args) {
System.out.println(DateUtil.getCurrentDate());
System.out.println(DateUtil.getCurrentDateByCalendar());
}
}
6.任务8:Object类
- 所有类的顶级父类。用到toString、equals()、hashcode()等方法。它
- 在java.lang核心包中,String、System等都来自于核心包。
(1)finalize()方法
- 垃圾回收时,该方法被调用(正式垃圾回收前该方法执行),观察以下程序的输出结果。
public class FinalizeMethod {
protected void finalize() {
System.out.println("Student对象被垃圾回收时,finalise被调用");
}
public static void main(String[] args) {
FinalizeMethod s = new FinalizeMethod();
s = null;//对象设置为null,可以进行回收
System.gc();
}
}
(2)equals方法重写
public class Teacher {
private String name;
private int age;
public Teacher(String name, int age) {
this.name = name;
this.age = age;
}
//重写equals方法 Ctrl+shift+s -> Generate hashCode()and equals
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Teacher other = (Teacher) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public static void main(String[] args) {
Teacher t1 = new Teacher("吴老师", 25);
Teacher t2 = new Teacher("吴老师", 25);
System.out.println(t1 == t2);//输出结果:false 地址比较两个对象两个地址指向
System.out.println(t1.equals(t2));//输出结果:true
}
}
7.任务9:封装类的使用 Wrapper Class
(1)什么是封装类?
- 答:8种基本数据类型对应的类 类型,就是封装类;由JDK提供,位于java.lang核心包中,全部被final修饰。
- boolean ------ Boolean
- byte ------------Byte
- short----------- Short
- char ----------- Character
- int -------------- Integer
- double -------- Double
- float ----------- Float
- long ----------- Long
- 重要方法
int num = Integer.parseInt(“200”):把字符串变成数字,通过封装类完成,里边的参数必须是数字构成的。
(2)怎么用以及自动拆箱和装箱?
Integer x = new Integer(20);//引用类型
Integer y = new Integer("20");
int z = 20;//基本类型
System.out.println(z == x);//true,自动拆箱机制
System.out.println(x == y);//false,new两次比较地址
System.out.println(z == y);//true,自动拆箱机制
System.out.println(x.equals(y));//true
Integer m = 100;//自动装箱,100是基本类型,左侧是Integer类类型,把100封装成对象,在赋值给m;
int n = x;//自动拆箱右侧x是Integer对象
Integer mv = new Integer("23abc");//这是错误的,里边的参数必须是数字构成的
Integer mv1 = new Integer("");//错误
(3)如何将字符串转换为数字?
String str = "2000";
int num = Integer.parseInt(str);//把字符串变成数字,通过封装类完成
String str1 = "2000";
double num1 = Double.parseDouble(str1);
int grade = 4;//数字变成字符串
String gra = grade + "";
8.任务10: 实现1 - 0.9的精确计算。
(1)以下输出结果是什么?
System.out.println(1 - 0.9); // 结果不是0.1,而是0.09999999999999998,二进制到十进制转换出现误差
(2)如何实现精确计算?
-
使用:java.math.BigDecimal包,要想实现精确计算一定要用new BigDecimal(String str)构造方法;参数一定是String
-
当数字值超出了long能表示的范围,计算时使用大整数类BigInteger API:java.math.BigInteger
-
1.小数减法和除法的精确计算:
public class Calc {
/**减法计算:依然无法精确计算*/
public double sub(double num1, double num2) {
BigDecimal number1 = new BigDecimal(num1);// API,参数是double类型
BigDecimal number2 = new BigDecimal(num2);
return number1.subtract(number2).doubleValue();
}
/** 实现精确计算*/
public double subV2(double num1, double num2) {
BigDecimal number1 = new BigDecimal(num1 + "");// API,参数是String类型
BigDecimal number2 = new BigDecimal(num2 + "");
return number1.subtract(number2).doubleValue();
}
private static final int DEF_DIV_SCALE = 3;
/**提供精确的除法运算,当发生除不尽的情况时,精确到小数点以后3位,以后的数字四舍五入*/
public static double div(double v1, double v2) {
return div(v1, v2, DEF_DIV_SCALE);
}
/**提供精确的除法运算。当发生除不尽的情况时,由scale参数指定精度,以后的数字四舍五入*/
public static double div(double v1, double v2, int scale) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
public static void main(String[] args) {
Calc calc = new Calc();
System.out.println(calc.subV2(1.0, 0.9));
System.out.println("小数除法精确计算结果:" + bid.div(11.3, 2.1));
}
}
- 2.大整数计算:
public class BigIntegerDemo {
public static void main(String[] args) {
BigInteger bd1 = new BigInteger("12345556789");
BigInteger bd2 = new BigInteger("45678912345636956565656565");
System.out.println("大整数加法计算结果:" + bd2.add(bd1));
System.out.println("大整数减法计算结果:" + bd2.subtract(bd1));
System.out.println("大整数乘法计算结果:" + bd2.multiply(bd1));
System.out.println("大整数除法计算结果:" + bd2.divide(bd1)); }
}
Part4、口述部分(面试题)
1.字符串创建方式有哪些?有何不同?
- 答:有两种方式,参考下面代码:
String name = "chian";
String addr = new String("hebei")
(1)问:String addr = new String(“hebei”);创建了几个对象?
- 答:创建了2个对象:第一个是:“hebei”; 第二个是:new出来的,就是addr指向的。
(2)String存储机制:字符串池(字符串常量池)
(3)两种创建字符串对象的方式有啥区别?
String str1 = "hello";
String str2 = "hello";
String str3 = new String("hello");
- 首次创建Hello时,Hello被放入字符串常量池,如果有其它变量的值也是Hello的话,直接从常量池里取;已经存在的Hello,不再创建新的。也就是这个字符串Hello被共享,这也是String不可变的原因(因为被共享)。 new String(“Hello”),每new一次都有一个新的空间在堆区产生。
2.列举几种API当中被final修饰的类
- String、StringBuffer、StringBuilder、Math、System、Integer等8个封装类。
3. ==与equals()有什么区别?
- == 比较基本类型时,判断两个值是否相等,如果相等就是true,不相等是false
- ==比较对象时,判断两个对象的“地址”是否相同;不是比较对象包含的内容(对象的属性),对象内容的比较用equals()方法
- 虽然对象包含的内容是相同的,但是得到是false,原因是:StringBuffer和StringBuilder并没有重写equals方法,这里用的equals还是Object类里的。
分析以下程序的输出结果:
String str1 = "hello";
String str2 = "hello";
String str3 = new String("hello");
String str4 = new String("hello");
System.out.println(str1 == str2);//true
System.out.println(str3 == str4);//false
System.out.println(str1 == str3);//false
System.out.println(str1.equals(str3));//true
System.out.println(str3.equals(str4));//true
StringBuilder str1 = new StringBuilder("china");
StringBuilder str2 = new StringBuilder("china");
System.out.println(str1.equals(str2));//false
System.out.println(str1 == str2);//false
String str3 = new String("china");
String str4 = new String("china");
System.out.println(str3.equals(str4));//true
System.out.println(str3 == str4);//false
4.String、StringBuffer、StringBuilder有何区别?
- (1)String是不可变字符串类,后两者是可变字符串类。
- (2)StringBuffer是线程安全的,StringBuilder是非线程安全的。
5.String是不是Java内置数据类型?能否用String当变量名?能否继承String类?
- 答:不是,Java内置数据类型只有8种;能当变量名使用;不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允许改变。
6.System.gc()调用后JVM会立即进行垃圾回收吗?
- 答:不一定,gc()只是建议JVM进行回收。
7.能否创建System、Math类的对象?
- 答:不可以,因为他们的方法都是私有的,所以不能创建。
8.Math.random()随机数范围是什么?
- 答:大于等于0,小于1(注意:不可能等于1)
9.final、finalize()的区别
- final是Java关键字,用于修饰类、属性、方法和变量
- finalize()是Object类的方法,与垃圾回收有关,在垃圾回收前被自动调用
五、独立任务
- 用户输入字符串,程序统计字符串中"ab"出现的总次数
public class StringCount {
public static void main(String[] args) {
String str1 = "ab12abaabnbab5abaxb";
String str2 = "ab";
int time = 0;
int start = 0;
while (str1.indexOf(str2, start) >= 0 && start < str1.length()) {
time++;
start = str1.indexOf(str2, start) + str2.length();
}
System.out.println("方法1:给定字符串中ab出现" + time + "次");
int count = (str1.length() - str1.replace(str2, "").length())/str2.length();
System.out.println("方法2:给定字符串中ab出现" + count + "次");
}
}
- 用户输入用户名和密码,输出使用MD5和SHA加密的密码
public class Code {
public static void sha(String un) throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest m = MessageDigest.getInstance("SHA-1");
m.update(un.getBytes("UTF-8"));
byte[] s = m.digest();
System.out.println(Arrays.toString(s));
}
public static void md5(String un) throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest m = MessageDigest.getInstance("MD5");
m.update(un.getBytes("UTF-8"));
byte[] s = m.digest();
System.out.println(Arrays.toString(s));
}
public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入用户名:");
String uname = scanner.next();
System.out.println("请输入密码:");
String upsw = scanner.next();
System.out.println("用户名的MD5编码为:");
md5(uname);
System.out.println("密码的MD5编码为:");
md5(upsw);
System.out.println("用户名的SHA-1编码为:");
sha(uname);
System.out.println("密码的SHA-1编码为:");
sha(upsw);
}
}
- 用户输入学号,输出该生所在系名称
学号格式:170554119,05是系的编号;01-机械系,02-电子系,03-自动化系,05-计算机系,08-理学系
public class StudentID {
public void getCs(String id) {
String str = id.substring(6,8);
switch(str) {
case "01":
System.out.println("该学生为机械系。");
break;
case "02":
System.out.println("该学生为电子系。");
break;
case "03":
System.out.println("该学生为自动化系。");
break;
case "05":
System.out.println("该学生为计算机系。");
break;
case "08":
System.out.println("该学生为理学系。");
break;
default:
System.out.println("查询不到该生的有效信息!");
break;
}
}
public static void main(String[] args) {
StudentID si = new StudentID();
Scanner scanner = new Scanner(System.in);
System.out.println("请输入您的学号(类似于201720050235):");
String str = scanner.next();
si.getCs(str);
}
}
六、附录
- 字符串实用类:[StringUtils]http://commons.apache.org/proper/commons-lang/
- 著名的开源组件网站www.apache.org