1.如何理解String类的值不可变但可以共享?
JAVA为了提高效率,所以对于String类型进行了特别的处理---为string类型提供了串池 定义一个string类型的变量有两种方式: string name= "tom "; string name =new string( "tom ") 使用第一种方式的时候,就使用了串池, 使用第二中方式的时候,就是一种普通的声明对象的方式 如果你使用了第一种方式,那么当你在声明一个内容也是 "tom "的string时,它将使用串池里原来的那个内存,而不会重新分配内存,也就是说,string saname= "tom ",将会指向同一块内存
string类型是不可改变的问题: string类型是不可改变的,也就是说,当你想改变一个string对象的时候,比如name= "madding " 那么虚拟机不会改变原来的对象,而是生成一个新的string对象,然后让name去指向它,如果原来的那个 "tom "没有任何对象去引用它,虚拟机的垃圾回收机制将接收它。
所以前后两次的string的地址改变了.
2.String s = new String(“hello”);在内存中创建了几个对象?请说明
String s=new String("hello");在内存中创建的对象数量取决于常量池中是否已存在“hello"这个字符串。 如果常量池中已经存在“hello"这个字符串,那么在执行 String s=new String("hello");时,Java会在堆内存中创建一个新的String对象,并将这个对象的引用添加到常量池中,但此时常量池中“hello”的引用指向的是新创建的对象,而不是之前已经存在的对象。这种情况下,实际上只创建了一个对象,即新创建的String对象。 如果常量池中不存在“hello"这个字符串,那么在执行String s=new String("hello");时,Java会在堆内存中创建一个新的String对象,并且同时将这个字符串添加到常量池中。这种情况下,创建了两个对象一个是新创建的String对象本身,另一个是在常量池中添加的“hello"字符串的引用。 综上所述,是否创建两个对象取决于常量池中是否已存在“hello"这个字符串。如果不存在,则创建两个对象;如果存在,则只创建一个对象
3.用运算符“==”比较字符串对象时,只要两个字符串包含的是同一个值,结果便为 true。”这句话对吗?
错的
==比较引用数据类型时比较的是对象的地址值,equals方法比较的为字符串内容
4.String的常用方法有哪些?它们分别是什么意思?(至少7个)
public String() 创建一个空白字符串对象,不含有任何内容String s1 = new String();
public String(char[] chs) 根据字符数组的内容,来创建字符串对象
char[] chs = {'a','b','c'}; String s2 = new String(chs);
public String(String original)根据传入的字符串内容,创建字符串对象
String s3 = new String("123");
5.现已知工人(Worker)类,属性包含姓名(name)、工龄(year),请编写该类,提供构造方法和get、set方法。在测试类中,请查看键盘录入Scanner类的API,创建工人类对象,属性值由键盘录入,打印对象的属性值。输出效果如下:
请录入工人姓名:
张三
请录入工人工龄:
5
该工人对象的属性信息如下:
姓名:张三
工龄:5
1、创建Worker类,成员变量私有修饰,提供空参和全参构造方法,提供get和set方法。
2、创建Test01类,在主方法中,创建键盘录入Scanner对象。
2.1、姓名信息为字符串,使用Scanner的nextLine()方法。
2.2、工龄信息为整数,使用Scanner的nextInt()方法。
3、创建Worker类对象,并输出对象的成员变量值。
3.1、可以在创建对象时使用构造方法为成员变量赋值,也可以创建对象后使用set方法赋值。
3.2、获取成员变量的值,使用get方法。
public class Worker {
// 成员变量
private String name;
private int year;
// 构造方法
public Worker() {
}
public Worker(String name, int age) {
this.name = name;
this.year = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
}
import java.util.Scanner;
public class Test01 {
public static void main(String[] args) {
// 创建键盘录入对象
Scanner sc = new Scanner(System.in);
System.out.println("请输入工人姓名:");
String name = sc.nextLine();
System.out.println("请输入工人工龄:");
int year = sc.nextInt();
// 创建对象
Worker w = new Worker(name, year);
// 输出信息
System.out.println("该工人对象的信息如下:");
System.out.println("姓名:" + w.getName());
System.out.println("工龄:" + w.getYear());
}
}
6.在登录注册页面中,除了用户名和密码外,通常也会包含验证码。验证码是用来区分用户是计算机还是人,防止恶意破解密码、刷票、灌水等行为。请查看Random、StringBuilder相关API,定义方法,获取一个包含4个字符的验证码,每一位字符是随机选择的字母和数字,可包含a-z,A-Z,0-9。例如:7Kt5
训练步骤
1、定义方法,返回值是String,参数列表为空。
2、定义StringBuilder对象,将可选择的字符都放到StringBuilder对象中。
2.1、定义循环从a-z,使用StringBuilder的append方法依次添加所有小写字母
2.2、定义循环从A-Z,使用StringBuilder的append方法依次添加所有大写字母
2.3、定义循环从0-9,使用StringBuilder的append方法依次添加所有数字字符
3、创建Random对象。定义一个空字符串用于保存验证码。
4、定义一个执行4次的循环,用于获取4个字符。
4.1、在循环中,使用Random的nextInt方法,随机获取一个从索引0(包含)到字符串的长度(不包含)的索引。
4.2、使用StringBuilder的charAt方法,获取该索引上的字符,将其拼接到验证码字符串中。
5、返回结果,并在主方法中调用方法查看结果。
import java.util.Random;
public class Test02 {
public static void main(String[] args) {
String code = getRandomCode();
System.out.println(code);
}
public static String getRandomCode() {
// 准备数据,将可选择的字符都放入StringBuilder中
StringBuilder sb = new StringBuilder();
for (char ch = 'a'; ch <= 'z'; ch++) {
sb.append(ch);
}
for (char ch = 'A'; ch <= 'Z'; ch++) {
sb.append(ch);
}
for (char ch = '0'; ch <= '9'; ch++) {
sb.append(ch);
}
// 随机获取四位
Random r = new Random();
String code = "";
for (int i = 0; i < 4; i++) {
// 字符串中的字符有索引,随机获取一个索引即相当于随机获取到了该索引的字符
int index = r.nextInt(sb.length()); // 从索引0(包含)到字符串的长度(不包含)
code += sb.charAt(index); // 获取该索引上的字符
}
// 返回结果
return code;
}
}
7.在登录注册页面中,除了用户名和密码外,通常也会包含验证码。验证码是用来区分用户是计算机还是人,防止恶意破解密码、刷票、灌水等行为。在判断验证码时一般不区分大小写。请编写程序模拟验证码的判断过程,如果输入正确,给出提示,结束程序。如果输入错误,给出提示,验证码刷新,重新输入,直至正确为止。
生成4位随机验证码的功能在之前的题目中已经完成,可以直接使用。《定义方法,获取一个包含4个字符的验证码,每一位字符是随机选择的字母和数字,可包含a-z,A-Z,0-9。》
运行效果如下:
生成的验证码为:BkhD
请输入验证码
abcd
输入错误,请重新输入...
生成的验证码为:n1wX
请输入验证码
aaaa
输入错误,请重新输入...
生成的验证码为:Fm1a
请输入验证码
fm1a
输入正确
1、定义方法,实现获取包含4个字符的随机验证码。(参考以前的练习)
2、创建键盘录入Scanner对象。
3、定义while循环,循环条件为true。
4、在循环内,获取程序生成的验证码,提示用户输入,调用Scanner对象的nextLine方法获取用户输入。
5、使用String的equalsIgnoreCase方法比较生成的验证码和用户输入,因为不区分大小写。
5.1、如果相等,给出输入正确的提示,使用break语句跳出循环。
5.2、如果不相等,给出输入错误的提示,继续下一次循环。
import java.util.Random;
import java.util.Scanner;
public class Test03 {
public static void main(String[] args) {
// 键盘录入对象
Scanner sc = new Scanner(System.in);
while (true) { // 不清楚输入多少次,定义死循环,输入正确时跳出即可。
String code = getRandomCode();
System.out.println("生成的验证码为:" + code);
System.out.println("请输入验证码");
String line = sc.nextLine();
// 不区分大小写比较是否相等
if (code.equalsIgnoreCase(line)) {
System.out.println("输入正确");
break; // 跳出循环,结束程序
} else {
System.out.println("输入错误,请重新输入...");
}
}
}
public static String getRandomCode() {
// 准备数据
StringBuilder sb = new StringBuilder();
for (char ch = 'a'; ch <= 'z'; ch++) {
sb.append(ch);
}
for (char ch = 'A'; ch <= 'Z'; ch++) {
sb.append(ch);
}
for (char ch = '0'; ch <= '9'; ch++) {
sb.append(ch);
}
// 随机获取四位
Random r = new Random();
String code = "";
for (int i = 0; i < 4; i++) {
// 字符串中的字符有索引,随机获取一个索引即相当于随机获取到了该索引的字符
int index = r.nextInt(sb.length()); // 从索引0(包含)到字符串的长度(不包含)
code += sb.charAt(index); // 获取该索引上的字符
}
// 返回结果
return code;
}
}
二
1.完成MathLib类,可以做加,减,乘,除等功能,其中加法不但可以做数字的加法,还可以做字符串的相加。
package test1;
import java.math.BigDecimal;
import java.util.Scanner;
public class MathLib {
public static void main(String[] args) {
System.out.println("请选择需要的功能");
System.out.println("1.加法 2.减法 3.乘法 4.除法");
Scanner sc = new Scanner(System.in);
int choose = sc.nextInt();
System.out.println("请输入要计算的数字");
Scanner sc1 = new Scanner(System.in);
String num1 = sc1.nextLine();
Scanner sc2 = new Scanner(System.in);
String num2 = sc2.nextLine();
MathLib mathLib = new MathLib();
switch (choose){
case 1:
mathLib.add(num1,num2);
break;
case 2:
mathLib.subtract(num1,num2);
break;
case 3:
mathLib.multiple(num1,num2);
break;
case 4:
mathLib.divide(num1,num2);
break;
default:
System.out.println("您的输入有误");
break;
}
}
private void divide(String a, String b) {
System.out.println("结果为:"+(Integer.parseInt(a)/Integer.parseInt(b)));
}
private void multiple(String a, String b) {
System.out.println("结果为:"+(Integer.parseInt(a)*Integer.parseInt(b)));
}
private void subtract(String a ,String b) {
System.out.println("结果为:"+(Integer.parseInt(a)-Integer.parseInt(b)));
}
private void add(String a, String b) {
if(a.matches("\\d+")&&b.matches("\\d+")){
System.out.println("结果为:"+(Integer.parseInt(a)+Integer.parseInt(b)));
}else{
System.out.println("结果为:"+a+b);
}
}
}
2.任意给定的一串字母,统计字符串里面的大写字母和小写字母的个数。
import java.util.Scanner;
public class StringDemo03 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串");
String line = sc.nextLine();
int upperCaseCount =0;
int lowerCaseCount =0;
int numberCount =0;
char[]chars=line.toCharArray();
for (int i = 0; i < chars.length; i++) {
char c=chars[i];
if(c>='A'&&c<='Z'){
upperCaseCount++;
}else if(c>='a'&&c<='z'){
lowerCaseCount++;
}else{
numberCount++;
}
}
System.out.println("大写字母出现的次数为:"+upperCaseCount+" 小写字母出现的次数为:"+lowerCaseCount+" 数字字符出现的次数为:"+numberCount);
}
}
3.根据传入得路径,获取文件名。例如:D:/myfile/hello.java取出hello.java
package test1;
public class Test3c {
public static void main(String[] args) {
String s= "D:/myfile/hello.java";
System.out.println(s.substring(s.lastIndexOf("/") + 1));
}
}
4.求两个日期之间相隔的天数
例如:写一个方法(fun3("2010-09-20","2010-09-21") ) 结果为1天
package test1;
import java.time.LocalDate;
import java.time.Period;
public class Test3 {
public static void main(String[] args) {
fun();
}
public static void fun() {
LocalDate localDate1 = LocalDate.of(2020, 9, 20);
LocalDate localDate2 = LocalDate.of(2020, 9, 21);
Period between = Period.between(localDate1, localDate2);
int days=between.getDays();
System.out.println("天数为:"+days);
}
}
5.请使用日期时间相关的API,计算出一个人已经出生了多少天。
法一:
package test1;
import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.Scanner;
public class Test5 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入您的生日 例如:1970-01-01");
String birthday=sc.nextLine();
DateTimeFormatter pattern= DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate parse = LocalDate.parse(birthday, pattern);
LocalDate now = LocalDate.now();
Period time = Period.between(parse, now);
System.out.println("出生了"+(time.getYears()*365+ time.getMonths()*30+time.getDays())+"天");
}
}
法二
package test1;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class Test5c2 {
public static void main(String[] args) throws ParseException {
Scanner sc = new Scanner(System.in);
System.out.println("请输入您的出生日期,格式为yyyy-MM-dd:");
String birthday = sc.nextLine();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date birthdayDate = simpleDateFormat.parse(birthday);
long birthdayDateTime = ((Date) birthdayDate).getTime();
long todayTime = new Date().getTime();
long time = todayTime-birthdayDateTime;
long days = time/1000/60/60/24;
System.out.println("您已经出生" + days + "天");
}
}
6.验证for循环打印数字1-9999所需要使用的时间(毫秒)
package test1;
public class Test6 {
public static void main(String[] args) {
long start = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
System.out.println(i+" ");
}
long end = System.currentTimeMillis();
System.out.println("需要的时间="+(end-start));
}
}
7.求出今天距离2023年1月1日还有多少天
package test1;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test7 {
public static void main(String[] args) throws ParseException {
String dayString ="2023-01-01";
//使用DateFormat类中的方法parse,把字符串的日期,解析为Date格式的日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date dayDate = sdf.parse(dayString);
//把Date格式的出生日期转换为毫秒值
long time1 = dayDate.getTime();
//获取当前的日期,转换为毫秒值
long time2 = new Date().getTime();
//使用当前日期的毫秒值-日期的毫秒值
long time=time1-time2;
System.out.println("还有"+time/1000/60/60/24+"天");