}
public Cat(String name, int age, String kind, String host, double price) {
this.name = name;
this.age = age;
this.kind = kind;
this.host = host;
this.price = price;
System.out.println(“全参构造”);
}
//4.提供小猫类的功能
//4.1睡觉sleep:参数String name,double num,无返回值,打印:小猫name今天一共睡了num个小时
public void sleep(String name,double num){
System.out.println(“小猫”+name+“今天一共睡了”+num+“个小时”);
}
//4.2玩play: 参数String host,返回值String"逗猫棒",打印:小猫与主人host玩的很开心
public String play(String host){
System.out.println(“小猫与主人”+host+“玩的很开心”);
bark();//此处调用被封装的方法
return “逗猫棒”;
}
//4.3叫bark:打印:小猫喜欢喵喵叫,此方法要封装,玩的时候才叫
private void bark(){
System.out.println(“小猫喜欢喵喵叫”);
}
//4.4吃eat:参数int n,无返回值,打印:小猫Cat今晚要吃n根肉骨头
public void eat(int n){
System.out.println(“小猫Cat今晚要吃”+n+“根肉骨头”);
}
//4.5跳jump:参数String name,无返回值,打印:小猫name跳的老高啦~
public void jump(String name){
System.out.println(“小猫”+name+“跳的老高啦~”);
}
//2.2给被封装的属性提供get与set方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getKind() {
return kind;
}
public void setKind(String kind) {
this.kind = kind;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
练习题 : 面向对象练习:实现学生类
需求:创建学生类,按照上述步骤进行测试
学生的属性:学号 姓名 性别 住址 科目
学生的功能:学习 吃饭 睡觉 查看本类类型与所有属性和属性值
- 创建学生类Student
package cn.tedu.oop;
/本类用于描述学生这一类事物/
public class Student {
//1.1定义学生的属性
//1.2 封装学生的属性
private int id;//学号
private String name;//姓名
private char gender;//性别
private String address;//住址
private String subject;//科目
//2.1提供本类的无参构造
public Student(){
System.out.println(“我是Student的无参构造”);
}
//2.2提供本类的全参构造
//右键->Generate->Contructor->Shift全选所有属性->OK
public Student(int id, String name, char gender, String address, String subject) {
this.id = id;
this.name = name;
this.gender = gender;
this.address = address;
this.subject = subject;
System.out.println(“我是Student的全参构造”);
}
//3.1提供本类的普通方法1
public void study(){
System.out.println(“学习使我快乐~”);
}
//3.2提供本类的普通方法2
public void eat(int n){
System.out.println(“今天我要干它”+n+“碗大米饭”);
}
//3.3提供本类的普通方法3
public String sleep(){
return “今天又睡了美美的一觉”;
}
//4.提供本类的一个展示类型与所有属性和属性值的方法
public void show(){
System.out.println(“Student:[id=”+id+“,name=”+name+“,gender=”+gender+“,address=”+address+“,subject=”+subject+“]”);
}
//1.3提供属性对应的get与set方法
//右键->Generate->Getter and setter->Shift全选所有属性->OK
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
}
- 创建学生类的测试类TestStudent
package cn.tedu.oop;
/本类用作学生类的测试类/
public class TestStudnet {
public static void main(String[] args) {
//1.1使用无参构造创建对象
Student s = new Student();
//1.2通过setXxx()给对象的所有属性赋值
s.setId(1);
s.setName(“林冲”);
s.setGender(‘男’);
s.setSubject(“CGB”);
s.setAddress(“庙里”);
//1.3通过对象调用方法测试
s.study();
s.eat(3);
System.out.println(s.sleep());
s.show();//Student:[id=1,name=林冲,gender=男,address=庙里,subject=CGB]
//2.1使用全参构造创建对象
Student s2 = new Student(2,“李逵”,‘男’,“猪肉铺”,“ACT”);
s2.study();
s2.eat(10);
System.out.println(s2.sleep());
s2.show();
}
}
练习题 : 面向对象练习:设计学校开学招待设计案例
需求:
身份:老 师 学生 学生家长
吃饭:教师食堂 食堂 招待所
住宿:学校公寓 宿舍 招待所
1.创建父接口,描述人这一类事物
package cn.tedu.review;
//1.定义一个接口,描述人这一类事物
public interface Person {
//面向接口编程,设计出老师 学生 学生家长的共同行为
//好处:方便接口的实现类实现时统一标准,而且更加灵活
//2.设计出共同的功能
void eat();
void sleep();
}
2.创建老师类
package cn.tedu.review;
//3.定义一个老师类实现Person接口
public class Teacher implements Person{
//4.添加Person接口中未实现的方法,并按照老师的功能来实现
@Override
public void eat() {
System.out.println(“老师在教师食堂吃饭”);
}
@Override
public void sleep() {
System.out.println(“老师在学校公寓住宿”);
}
}
3.创建学生类
package cn.tedu.review;
//5.定义一个学生类实现Person接口
public class Student implements Person{
//4.添加Person接口中未实现的方法,并按照学生的功能来实现
@Override
public void eat() {
System.out.println(“学生在学校食堂吃饭”);
}
@Override
public void sleep() {
System.out.println(“学生回学校宿舍睡觉”);
}
}
4.创建家长类
package cn.tedu.review;
//7.定义一个家长类实现Person接口
public class Parents implements Person{
//8.添加Person接口中未实现的方法,并按照家长学生的功能来实现
@Override
public void eat() {
System.out.println(“家长在招待所的饭馆吃饭~”);
}
@Override
public void sleep() {
System.out.println(“家长会招待所休息~”);
}
}
5.创建测试类
package cn.tedu.review;
/本类用来测试学校开学招待案例/
//9.创建测试类
public class TestPerson {
public static void main(String[] args) {
//10.在main()中创建3个类的对象
Teacher t = new Teacher();
Student s = new Student();
Parents p = new Parents();
//11.通过对象使用功能
t.eat();
t.sleep();
s.eat();
s.sleep();
p.eat();
p.sleep();
}
}
练习题 : 面向对象练习:设置小动物类,包含会飞的动物 鸟类 昆虫
前提:如果有两个及两个以上的类拥有相同的方法,但是实现的功能不同
就可以向上形成一个接口,这样每次实现类就可以直接添加接口中未实现的方法
需求:
-
鸟与昆虫具有飞行的共同功能,就可以定义一个父接口FlyAnimal,描述飞行
-
定义父类小鸟类Bird : 腿的数量为2 ,下蛋数量可以自定义 ,还有下蛋的功能
-
定义父类昆虫类Insect : 腿的数量为6,产卵的数量可以自定义,还有产卵的功能
-
定义子级鸽子类Pigeon:它既会飞,也会下蛋
-
定义子级燕子类Swallow:它既会飞,也会下蛋,还有自己的特有功能筑巢
-
定义子级蚂蚁类Ant:它既会飞,也会产卵
-
定义子级蜜蜂类Bee:它既会飞,也会产卵,还有自己的特有功能制作蜂蜜
1. 创建父级接口FlyAnimal
/定义一个接口,描述动物会飞这一功能/
//1.定义父接口,并定义接口中飞行的功能
public interface FlyAnimal {
void fly();
}
2.创建父级抽象类Bird小鸟类
package cn.cxy.exec;
//5.定义抽象父类-小鸟类
abstract public class Bird {
//6.1 定义小鸟类中腿的数量为:2
int legNumbers = 2;
//6.2 定义小鸟类中产卵的成员变量,没有默认值
int eggNumber;
//7.定义小鸟类中下蛋的功能
public abstract void layEggs();
}
3.创建父级抽象类Insect昆虫类
package cn.cxy.exec;
//2.定义抽象父类-定义昆虫类
abstract public class Insect {
//3.1 定义昆虫类中腿的数量为:6
int legNumbers = 6;
//3.2 定义昆虫类中产卵的成员变量,没有默认值
int eggNumber;
//4.定义昆虫类中产卵的功能
public abstract void spawn();
}
4.创建子级鸽子类Pigeon:它既会飞,也会下蛋
package cn.cxy.exec;
//10.定义鸽子类-子实现类
public class Pigeon extends Bird implements FlyAnimal{
@Override//这是父抽象类中的抽象方法
public void layEggs() {
System.out.println(“鸽子的下蛋数为:”+eggNumber);
}
@Override//这是父接口中的抽象方法
public void fly() {
System.out.println(“鸽子要飞啦”);
}
}
5.创建子级燕子类Swallow:它既会飞,也会下蛋,还有自己的特有功能筑巢
package cn.cxy.exec;
//11.定义燕子类-子实现类
public class Swallow extends Bird implements FlyAnimal{
@Override//这是父抽象类中的抽象方法
public void layEggs() {
System.out.println(“燕子的下蛋数为:”+eggNumber);
}
@Override//这是父接口中的抽象方法
public void fly() {
System.out.println(“燕子归巢~”);
}
public void makeNest(){//这是子类的特有功能
System.out.println(“燕子在筑巢~”);
}
}
6.定义子级蚂蚁类Ant:它既会飞,也会产卵
package cn.cxy.exec;
//8.定义蚂蚁类-子实现类
public class Ant extends Insect implements FlyAnimal{
//9.添加父级中未实现的方法
@Override
public void fly() {//这是父接口中的抽象方法
System.out.println(“蚂蚁飞啦~”);
}
@Override
public void spawn() {//这是父抽象类中的抽象方法
System.out.println(“蚂蚁的产卵数为:”+eggNumber);
}
}
7. 定义子级蜜蜂类Bee:它既会飞,也会产卵,还有自己的特有功能制作蜂蜜
package cn.cxy.exec;
//12.定义蚂蚁类-子实现类
public class Bee extends Insect implements FlyAnimal{
//添加父级中未实现的方法
@Override
public void fly() {//这是父接口中的抽象方法
System.out.println(“蜜蜂飞啦~”);
}
@Override
public void spawn() {//这是父抽象类中的抽象方法
System.out.println(“蜜蜂的产卵数为:”+eggNumber);
}
public void makeHoney(){//这是子类的特有功能
System.out.println(“蜜蜂在产蜂蜜~”);
}
}
8.创建测试类TestAnimals测试所有的子类
package cn.cxy.exec;
/本类用作动物设计案例的测试类/
public class TestAnimals {
public static void main(String[] args) {
System.out.println(“我在测试蚂蚁类*”);
//1.1创建蚂蚁类对象
Ant a = new Ant();
//1.2设置产卵的数量
a.eggNumber = 300;
//1.3查看腿的条数–父类中的默认值,没有修改,直接获取
System.out.println(“蚂蚁的腿有”+a.legNumbers+“条”);
//1.4 调用实现后的功能 飞行 产卵
a.fly();
a.spawn();
System.out.println(“我在测试鸽子类*”);
//2.1创建鸽子类对象
Pigeon p = new Pigeon();
//2.2设置下蛋的数量
p.eggNumber = 3;
//2.3查看腿的条数–父类中的默认值,没有修改,直接获取
System.out.println(“鸽子的腿有”+p.legNumbers+“条”);
//2.4 调用实现后的功能 飞行 下蛋
p.fly();
p.layEggs();
System.out.println(“我在测试燕子类*”);
//3.1创建燕子类对象
Swallow s = new Swallow();
//3.2设置下蛋的数量
s.eggNumber = 6;
//3.3查看腿的条数–父类中的默认值,没有修改,直接获取
System.out.println(“燕子的腿有”+s.legNumbers+“条”);
//3.4 调用实现后的功能 飞行 下蛋
s.fly();
s.layEggs();
//3.5调用子类的特有功能–筑巢
s.makeNest();
System.out.println(“我在测试蜜蜂类*”);
//4.1创建蜜蜂类对象
Bee b = new Bee();
//4.2设置产卵的数量
b.eggNumber = 600;
//4.3查看腿的条数–父类中的默认值,没有修改,直接获取
System.out.println(“蜜蜂的腿有”+b.legNumbers+“条”);
//4.4 调用实现后的功能 飞行 产卵
b.fly();
b.spawn();
//4.5调用子类的特有功能–产蜂蜜
b.makeHoney();
}
}
最终的执行效果:
练习题 : 实现二分法查找/折半查找
注意:折半查找的前提:数据必须是有序的
package cn.cxy.exec;
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
public class BinarySearch {
public static void main(String[] args) {
//从方法,获取一个乱序数组
int[] a = suiJi();
//对a数组排序
Arrays.sort(a);//优化的快速排序
System.out.println(Arrays.toString(a));
while(true) {
System.out.print(“查找的目标值:”);
int t = new Scanner(System.in).nextInt();
//二分法查找,
//从a数组中,查找t的位置
int index = binarySearch(a, t);
System.out.println(index);
}
}
private static int[] suiJi() {
//随机产生5+ [0,6)范围整数n
int n = 5+ new Random().nextInt(6);
//新建int[]数组,长度n
//再存到变量a
int[] a = new int[n];
//遍历数组,填入100内随机整数
for (int i = 0; i < a.length; i++) {
a[i] = new Random().nextInt(100);
}
//返回数组a
return a;
}
private static int binarySearch(int[] a, int t) {
/*
-
t = 36
-
mid
-
[16, 21, 30, 36, 39, 70, 70, 92]
-
lo
-
hi
-
*) lo和hi关系 lo<=hi
-
*) 交叉就是找不到数据
-
*) lo位置是插入点位置
-
*)定义三个下标值
-
lo=0, hi=a.length-1
-
mid 只定义先不赋值
-
*)循环,当lo<=hi
-
*)计算中间下表存到 mid
-
*)如果a[mid]<t,lo定位到mid+1
-
*)否则如果a[mid]>t,hi定义到mid-1
-
*)否则,返回mid的值
-
*)lo、hi交叉结束
-
返回 -(lo+1),表示-(插入点+1)
*/
int lo = 0;
int hi = a.length-1;
int mid;
while(lo <= hi) {
mid = (lo+hi) / 2;
if(a[mid] < t) {
lo = mid+1;
} else if(a[mid] > t) {
hi = mid-1;
} else {
return mid;
}
}
//避免lo是0,加1后,再加负号
return -(lo+1); // -(插入点+1)
}
}
练习题 : 二分法实现数据动态插入
注意:折半查找的前提:数据必须是有序的
package cn.cxy.exec;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import java.util.Scanner;
public class BinaryInsert {
public static void main(String[] args) {
/*
-
集合、泛型,都不支持基本类型
-
用基本类型的包装类
*/
ArrayList list = new ArrayList<>();
System.out.println(“回车继续”);
while(true) {
new Scanner(System.in).nextLine();
int n = new Random().nextInt(100);
//二分法查找,在list中找n所在的位置
//找不到,返回 -(插入点+1)
int index = Collections.binarySearch(list, n);
if(index < 0) {
index = (-index)-1;
}
list.add(index, n);
System.out.println(list.toString());
}
}
}
练习题 : 求数字阶乘(递归解法版)
需求:接收用户输入的数字,计算该数字的阶乘结果
已知:负数不可以有阶乘,0的阶乘结果是1,
5 ! = 5 x 4 x 3 x 2 x 1
package cn.cxy.design;
//需求:求用户输入数字的阶乘结果
//f(int n)–用来求阶乘
//规律:
//f(n)= n*f(n-1)
//f(5)= 54321 = 5*f(4)
//f(4)= 4321 = 4f(3)
//f(3)= 321 = 3*f(2)
//f(2)= 21 = 2f(1)
//f(1)= 1
//
//5!=54321=120
//4!=432*1
//3!=321
//2!=2*1
//1!=1
public class TestRecursion {
public static void main(String[] args) {
int result = f(15);//调用f()用来求阶乘
System.out.println(result);
}
/*递归的两要素 1.总结规律 2.最简问题/
public static int f(int n) {
if(n == 1) {//最简问题
return 1;
}else {//其他情况 n*f(n-1)
//递归:再方法内部自己调用自己
return n*f(n-1);
}
}
}
练习题 : 递归求目录总大小
需求:递归求目录的总大小 D:\ready,步骤分析如下:
1.列出文件夹中的所有资源–listFiles()–>File[]
2.判断,当前资源是文件还是文件夹–文件夹大小为0,文件大小需要累加
–是文件,求文件的字节量大小length(),累加就行
–是文件夹,继续列出文件夹下的所有资源–listFiles()–>File[]
–判断,是文件,求文件的字节量大小length(),累加就行
–判断,是文件夹,再一次列出文件夹下的所有资源
–…重复操作
也就是说,规律就是:只要是文件夹,就需要重复步骤1 2
package cn.cxy.file;
import java.io.File;
/*本类用来递归求目录总大小/
public class FileSumRecursion {
public static void main(String[] args) {
//1.指定要求哪个目录的总大小
/**注意:此处指定的目录必须是真实存在的
- 如果传一个不存在的文件夹会报错,如果是传了一个空文件夹,大小为0*/
File file = new File(“D:\ready”);
//2.调用size()求目录大小
long total = size(file);
//3.接收结果并打印
System.out.println(“文件夹的总大小为:”+total);
}
private static long size(File file) {
//1.列出文件夹中的所有资源–listFiles()–>File[]
File[] fs = file.listFiles();
//2.遍历数组,获取每file对象
//2.1定义变量,记录总和
long sum = 0;
for(int i = 0;i < fs.length ; i++) {
//2.2通过下标操作当前遍历到的资源
File f = fs[i];
//2.3判断,当前资源是文件还是文件夹–文件夹大小为0,文件大小需要累加
if(f.isFile()) {
//–是文件,求文件的字节量大小length(),累加就行
sum += f.length();//相当于:sum = sum + f.length();
}else if(f.isDirectory()) {
//–是文件夹,继续列出文件夹下的所有资源,1 2步骤–listFiles()–>File[]
/*方法的递归,递归现象,就是在方法的内部调用方法自身/
sum += size(f);
}
}
return sum;//把sum记录的值返回调用位置
}
}
练习题 : 递归删除文件夹
需求:递归删除文件夹 D:\ready\a
1.列出文件夹下的所有资源listFiles()
2.判断,当前资源是文件还是文件夹
–判断,是文件,直接删除delete()
–判断,是文件夹,继续重复操作1 2
具体思路可以分为这么几步:
1.首先,我们需要指定一个根目录作为要删除的对象
2.列出文件夹下的所有资源listFiles(),并进行遍历
3.判断当前的资源,如果是文件,直接删除;如果是文件夹,则执行步骤2
4.将文件夹中的内容删除完毕后,删除文件夹本身
package cn.tedu.file;
import java.io.File;
/*本类用于递归删除目录/
public class TestFileDeleteRecursion {
public static void main(String[] args) {
//1.指定要删除的目录
/**为了更好的测试,注意指定的目录是已存在的目录,但是,千万不要删盘符!!!*/
/我们也有一些没有权限的文件夹,那个是无法访问且不能删除的哦/
File file = new File(“D:\ready\a”);
//2.调用删除目录的方法
boolean result = del(file);
//3.打印删除的结果
System.out.println(“删除的结果为:”+result);
}
public static boolean del(File file) {//完成的同学不是很多,抓紧时间写,写完截图发群里哈,这首歌结束我们继续
//1.列出文件夹下的所有资源
File[] fs = file.listFiles();
//2.循环遍历拿到的所有资源
for (int i = 0; i < fs.length; i++) {
//2.1获取本次循环遍历到的file对象
File f = fs[i];
//3.判断,当前资源是文件还是文件夹
if(f.isFile()) {
f.delete();//是文件,直接删除
System.out.println(file.getName()+“文件删除成功!”);
}else if(f.isDirectory()) {
//是文件夹,需要继续进行步骤1 2 ,出现了重复调用的情况
//递归,在方法的内部调用自己
del(f);
}
}
//位置:在for循环执行之外删除文件夹
file.delete();//空文件夹直接删除
System.out.println(file.getName()+“文件夹删除成功!”);
return true;
}
}
练习题 : 复制文件(字节流批量读取)
需求:接收用户目标文件的路径,复制目标文件到指定路径
import java.io.*;
import java.util.Scanner;
public class TestCopyFiles {
public static void main(String[] args) {
//1.提示并接收用户输入的要复制的源文件路径–复制啥
System.out.println(“请输入源文件路径:”);
String f = new Scanner(System.in).nextLine();
//2.提示并接收用户输入的目标文件所在的位置–复制到哪
System.out.println(“请输入目标文件的路径:”);
String t = new Scanner(System.in).nextLine();
//3.1根据源文件路径封装from文件对象
File from = new File(f);
//3.2根据目标文件路径封装to文件对象
File to = new File(t);
//3.3根据用户提供的路径完成文件的复制操作
copy(from,to);
}
public static void copy(File from, File to) {
InputStream in = null;//定义在整个方法中都生效的字节输入流对象,注意是局部变量,需要初始化,对象的默认值是null
OutputStream out = null;//定义在整个方法中都生效的字节输出流对象,注意是局部变量,需要初始化,对象的默认值是null
try {
//1.读取from文件–操作文件的是字节输入流
in = new BufferedInputStream(new FileInputStream(from));
//2.写出到to文件–操作文件的是字节输出流
out = new BufferedOutputStream(new FileOutputStream(to));
//3.边读边写
int b = 0;//定义变量b,记录读取到的数据
/**需求:想要实现批量读取,使用的是read(byte[] b)重载的形式,可以按照数组的方式来读 */
/**可以自定义数组,长度建议与源码保持一致,81024 = 8192/
byte[] bs = new byte[8*1024];
while( (b=in.read(bs)) != -1 ) {//只有没有数据时,才返回-1,跳出循环,读写结束
out.write(bs);//将读到的数据写出到文件
}
System.out.println(“恭喜您!文件复制成功!”);
} catch (IOException e) {
System.out.println(“很抱歉!文件复制失败!”);
e.printStackTrace();//打印错误信息
}finally {
//释放资源
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
练习题 : 逆序遍历List集合
手写一个程序,完成List集合对象的逆序遍历
package cn.cxy.exec;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/*本类用于进一步测试List接口/
public class TestList {
public static void main(String[] args) {
//1.创建List接口的多态对象
List list = new ArrayList<>();
//2.向创建好list集合添加元素
list.add(“喜羊羊”);
list.add(“美羊羊”);
list.add(“懒羊羊”);
list.add(“沸羊羊”);
list.add(“小肥羊”);
list.add(“肥羊卷”);
System.out.println(list);
System.out.println(“listIterator的逆序遍历:”);
ListIterator it3 = list.listIterator();
while(it3.hasNext()){//判断是否有下一个元素可迭代
System.out.println(it3.next());//打印当前迭代到的元素
if(!it3.hasNext()){//直到迭代器没有下一个元素可迭代–到最后了
System.out.println(“开始逆序迭代:”);
while (it3.hasPrevious()){//判断是否有上一个元素可迭代
System.out.println(it3.previous());//打印获取到的上一个元素
}
break;//终止循环,不然会一直从头到尾,再从尾到头迭代
}
}
}
}
练习题 : 回文问题
需求,如果一个用户输入的数据,从前到后或者从后到前读到的内容都是一样的,我们就称这种数据为"回文",比如123321 或者 12321 或者上海自来水来自海上等等
import java.util.Scanner;
public class TestNumber {
public static void main(String[] args) {
System.out.println(“请输入一个字符串:”);
String s = new Scanner(System.in).nextLine();
if(!stringJudge(s)){
System.out.println(s + “不是回文字符串”);
}else{
System.out.println(s + “是回文字符串”);
}
//调用第二个方法解决
stringJudge2(s);
}
//判断字符串是否回文
private static boolean stringJudge(String str) {
for (int i = 0; i < str.length() - i - 1; i++){
if(str.charAt(i) == str.charAt(str.length() - i - 1)){
continue;
}else{
return false;
}
}
return true;
}
//判断字符串是否回文2
private static void stringJudge2(String s) {
//方法2:将字符串反转比较
String s2 = new StringBuffer(s).reverse().toString();
if(s.compareTo(s2) == 0){
System.out.println(s + “是回文字符串”);
}else{
System.out.println(s + “不是回文字符串”);
}
}
}
练习题 : 手写数组列表
手写一个数组列表,实现基本的数据操作功能
数组列表类:
package cn.cxy.exec;
import java.util.Arrays;
public class ShuZuLieBiao {
T[] a;
int index;
public ShuZuLieBiao() {
this(10);
}
public ShuZuLieBiao(int length) {
a = (T[]) new Object[length];
}
public void add(T t) {
//确认容量
queRenRongLiang();
a[index] = t;
index++;
}
private void queRenRongLiang() {
//还有位置
if(index<a.length) {
return;
}
//容量增长1.5倍
//防止初始长度是0,再加两个位置
int n = a.length + a.length/2 + 2;
a = Arrays.copyOf(a, n);
}
public T get(int i) {
jianChaFanWei(i);
return a[i];
}
private void jianChaFanWei(int i) {
//检查下标范围
if(i<0 || i>=index) {
//抛出一个异常,表示这里出错
throw new IndexOutOfBoundsException(
“下标:”+i);
}
}
public int size() {
return index;
}
public T remove(int i) {
jianChaFanWei(i);//检查范围
T t = a[i];//取出i位置的值
/* [i+1, index) 范围的值,向前复制1位
-
i
-
[1,2,4,5,6,-,-,-,-,-,-]
-
|
-
index
*/
System.arraycopy(a, i+1, a, i, index-i-1);
a[index-1] = null;
index–;
return t; //返回被移除的值
}
}
测试类:
package cn.cxy.exec;
public class TestSZLB {
public static void main(String[] args) {
//泛型,不支持基本类型
ShuZuLieBiao lb = new ShuZuLieBiao<>();
lb.add(“aaa”);
lb.add(“vvv”);
lb.add(“ggg”);
lb.add(“rrr”);
lb.add(“qqq”);
lb.add(“uuu”);
lb.add(“aaa”);
System.out.println(lb.size());
System.out.println(lb.get(0));
System.out.println(lb.get(lb.size()-1));
System.out.println(lb.remove(4));
for(int i=0;i<lb.size();i++) {
System.out.println(lb.get(i));
}
}
}
练习题 : 文件复制案例
需求:接收用户输入的两个路径,将这两个路径代表的两个文件的内容同时复制到第3个文件中
如:将1.txt与2.txt里的内容按顺序同时复制到3.txt中
package cn.cxy.exec;
import java.io.*;
import java.util.Scanner;
/本类用于练习IO流文件复制综合案例/
public class Demo {
public static void main(String[] args) {
//1.提示并接收用户输入的两个路径
System.out.println(“请输入源文件的路径1:”);
String f1 = new Scanner(System.in).nextLine();//被复制的那个文件
System.out.println(“请输入源文件的路径2:”);
String f2 = new Scanner(System.in).nextLine();//被复制的那个文件
System.out.println(“请输入新文件的路径:”);
String t = new Scanner(System.in).nextLine();//复制好的新文件
//2.调用创建好的自定义方法,完成文件的复制
ZJCopy(f1,f2,t);//使用字节流完成复制的操作
}
//使用字节流完成文件复制的操作
private static void ZJCopy(String f1,String f2, String t) {
//1.定义两个在本方法中都生效的字节流局部变量,注意初始化值为null
BufferedInputStream in1 = null;//高效字节输入流,用于读取
BufferedInputStream in2 = null;//高效字节输入流,用于读取
BufferedOutputStream out = null;//高效字节输出流,用于写出
//2.由于IO操作可能会发生异常,所以需要完成try-catch-finally结构
try{
//3.1创建一个高效字节输入流对象,用于读取源文件
in1 = new BufferedInputStream(new FileInputStream(f1));
in2 = new BufferedInputStream(new FileInputStream(f2));
//3.2创建一个高效字节输出流对象,用于向新文件输出数据
out = new BufferedOutputStream(new FileOutputStream(t,true));
//4.使用两个流对象完成复制操作
int b;
while((b=in1.read())!=-1){
out.write(b);
}
int b2;
while((b2=in2.read())!=-1){
out.write(b2);
}
System.out.println(“恭喜!复制成功!”);
}catch (IOException e){
System.out.println(“复制失败!”);
e.printStackTrace();
}finally {
//5.关流
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
in2.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
in1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
练习题 : 面向对象:学生专业与成绩管理
- 编写学生类Student
包含属性:sno学号 name姓名 gender性别 major专业 totalScore总成绩
- 编写专业类Major
包含属性:totalScore总成绩 englishScore英文成绩 midScore期中成绩 finalScore期末成绩
- 编写三个不同的子专业类继承专业类Major,以下为各个专业与它们独有的专业课:
1)计算机系:ComputerMajor 编程课成绩(专业课):programmingScore
2)中文系:ChineseMajor 写作课成绩(专业课):writingScore
3)数学系:MathematicsMajor 数学理论成绩(专业课):mathScore
4)提供计算最终成绩的getScore():
成绩计算逻辑:总成绩=专业课成绩40%+英文课成绩10%+期中成绩15%+期末成绩35%
4.在测试类中定义一个可以容纳5个学生的学生数组
输入学生的各项信息,学号按输入顺序,第1个学生学号为1
使用随机数给学生随机分配专业
输入学生的各项分数,计算得出学生的总成绩
利用将以上所有信息创建对应的学生对象,存入数组中
输出学生的信息,格式:
学号:1, 姓名:‘李四’, 性别:女, 专业:数学专业{数学理论课成绩:98.0,英文课成绩:88.0,期中成绩:79.0,期末成绩:90.0}, 总成绩:91.35
1. 创建学生类
package cn.tedu.oop;
//1.定义学生类
public class Student{
//2.定义学生类的属性
int sno;//学号
String name;//姓名
char gender;//性别
Major major;//专业
double totalScore;//总成绩
//3.提供本类的全参构造,注意分数需要调用Major类的getScore()获取
public Student(int sno, String name, char gender, Major major, double totalScore) {
this.sno = sno;
this.name = name;
this.gender = gender;
this.major = major;
this.totalScore = major.getScore();
}
//4.重写toString()方法,方便直接查看学生类的所有属性值
@Override
public String toString() {
return “学号:” + sno +
“, 姓名:'” + name + ‘’’ +
“, 性别:” + gender +
“, 专业:” + major +
“, 总成绩:” + totalScore;
}
}
2. 创建专业类
package cn.tedu.oop;
//5.创建专业类,注意这个是一个父类,下属还有3个子类代表3个不同的具体专业
public class Major {
//6.定义专业类的属性
double totalScore;//总成绩
double englishScore;//英文成绩
double midScore;//期中成绩
double finalScore;//期末成绩
//7.提供本类的全参构造,注意总成绩需要计算得出,不在本构造方法里
public Major(double englishScore, double midScore, double finalScore) {
this.englishScore = englishScore;
this.midScore = midScore;
this.finalScore = finalScore;
}
//8.创建一个计算获取成绩的方法
//由于这个方法一定会被子类重写,所以方法里没有具体计算成绩的业务
public double getScore(){
return totalScore;
}
}
3. 创建计算机专业类
package cn.tedu.oop;
//9.创建计算机专业类,继承专业类
public class ComputerMajor extends Major {
//10.添加子类独有的属性:编程课成绩
double programmingScore;
//11.生成子类自己的全参构造
public ComputerMajor(double programmingScore,double englishScore, double midScore, double finalScore) {
//这里是在调用父类的构造方法,因为英文 期中 期末 成绩都是在父类那里赋值的
super(englishScore, midScore, finalScore);
//在子类的构造方法中只需要给子类的特有属性专业课成绩赋值即可
this.programmingScore = programmingScore;
}
//12.子类重写父类的getScore(),具体实现总分数的计算
@Override
public double getScore(){
//计算逻辑:总成绩=专业课成绩40%+英文课成绩10%+期中成绩15%+期末成绩35%
totalScore = programmingScore0.4+englishScore0.1+midScore0.15+finalScore0.35;
//返回计算好的成绩
return totalScore;
}
//13.重写toString()方法,方便直接查看专业类的所有属性值
@Override
public String toString() {
return “计算机专业{” +
“编程课成绩:” + programmingScore +
“,英文课成绩:” + englishScore +
“,期中成绩:” + midScore +
“,期末成绩:” + finalScore +
‘}’;
}
}
4. 创建文学专业类
package cn.tedu.oop;
//14.创建计算机专业类,继承专业类
public class ChineseMajor extends Major {
//15.添加子类独有的属性:写作课成绩
double writingScore;
//16.生成子类自己的全参构造
public ChineseMajor(double writingScore,double englishScore, double midScore, double finalScore) {
//这里是在调用父类的构造方法,因为英文 期中 期末 成绩都是在父类那里赋值的
super(englishScore, midScore, finalScore);
//在子类的构造方法中只需要给子类的特有属性专业课成绩赋值即可
this.writingScore = writingScore;
}
//17.子类重写父类的getScore(),具体实现总分数的计算
@Override
public double getScore(){
//计算逻辑:总成绩=专业课成绩40%+英文课成绩10%+期中成绩15%+期末成绩35%
totalScore = writingScore0.4+englishScore0.1+midScore0.15+finalScore0.35;
//返回计算好的成绩
return totalScore;
}
//18.重写toString()方法,方便直接查看专业类的所有属性值
@Override
public String toString() {
return “文学专业{” +
“写作课成绩:” + writingScore +
“,英文课成绩:” + englishScore +
“,期中成绩:” + midScore +
“,期末成绩:” + finalScore +
‘}’;
}
}
5. 创建数学专业类
package cn.tedu.oop;
//19.创建数学专业类,继承专业类
public class MathematicsMajor extends Major {
//20.添加子类独有的属性:数学理论课成绩
double mathScore;
//21.生成子类自己的全参构造
public MathematicsMajor(double mathScore, double englishScore, double midScore, double finalScore) {
//这里是在调用父类的构造方法,因为英文 期中 期末 成绩都是在父类那里赋值的
super(englishScore, midScore, finalScore);
//在子类的构造方法中只需要给子类的特有属性专业课成绩赋值即可
this.mathScore = mathScore;
}
//22.子类重写父类的getScore(),具体实现总分数的计算
@Override
public double getScore(){
//计算逻辑:总成绩=专业课成绩40%+英文课成绩10%+期中成绩15%+期末成绩35%
totalScore = mathScore0.4+englishScore0.1+midScore0.15+finalScore0.35;
//返回计算好的成绩
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
最后的内容
在开头跟大家分享的时候我就说,面试我是没有做好准备的,全靠平时的积累,确实有点临时抱佛脚了,以至于我自己还是挺懊恼的。(准备好了或许可以拿个40k,没做准备只有30k+,你们懂那种感觉吗)
如何准备面试?
1、前期铺垫(技术沉积)
程序员面试其实是对于技术的一次摸底考试,你的技术牛逼,那你就是大爷。大厂对于技术的要求主要体现在:基础,原理,深入研究源码,广度,实战五个方面,也只有将原理理论结合实战才能把技术点吃透。
下面是我会看的一些资料笔记,希望能帮助大家由浅入深,由点到面的学习Java,应对大厂面试官的灵魂追问
这部分内容过多,小编只贴出部分内容展示给大家了,见谅见谅!
- Java程序员必看《Java开发核心笔记(华山版)》
- Redis学习笔记
- Java并发编程学习笔记
四部分,详细拆分并发编程——并发编程+模式篇+应用篇+原理篇
- Java程序员必看书籍《深入理解 ava虚拟机第3版》(pdf版)
- 大厂面试必问——数据结构与算法汇集笔记
其他像Spring,SpringBoot,SpringCloud,SpringCloudAlibaba,Dubbo,Zookeeper,Kafka,RocketMQ,RabbitMQ,Netty,MySQL,Docker,K8s等等我都整理好,这里就不一一展示了。
2、狂刷面试题
技术主要是体现在平时的积累实用,面试前准备两个月的时间再好好复习一遍,紧接着就可以刷面试题了,下面这些面试题都是小编精心整理的,贴给大家看看。
①大厂高频45道笔试题(智商题)
②BAT大厂面试总结(部分内容截图)
③面试总结
3、结合实际,修改简历
程序员的简历一定要多下一些功夫,尤其是对一些字眼要再三斟酌,如“精通、熟悉、了解”这三者的区别一定要区分清楚,否则就是在给自己挖坑了。当然不会包装,我可以将我的简历给你参考参考,如果还不够,那下面这些简历模板任你挑选:
以上分享,希望大家可以在金三银四跳槽季找到一份好工作,但千万也记住,技术一定是平时工作种累计或者自学(或报班跟着老师学)通过实战累计的,千万不要临时抱佛脚。
另外,面试中遇到不会的问题不妨尝试讲讲自己的思路,因为有些问题不是考察我们的编程能力,而是逻辑思维表达能力;最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。
MathematicsMajor extends Major {
//20.添加子类独有的属性:数学理论课成绩
double mathScore;
//21.生成子类自己的全参构造
public MathematicsMajor(double mathScore, double englishScore, double midScore, double finalScore) {
//这里是在调用父类的构造方法,因为英文 期中 期末 成绩都是在父类那里赋值的
super(englishScore, midScore, finalScore);
//在子类的构造方法中只需要给子类的特有属性专业课成绩赋值即可
this.mathScore = mathScore;
}
//22.子类重写父类的getScore(),具体实现总分数的计算
@Override
public double getScore(){
//计算逻辑:总成绩=专业课成绩40%+英文课成绩10%+期中成绩15%+期末成绩35%
totalScore = mathScore0.4+englishScore0.1+midScore0.15+finalScore0.35;
//返回计算好的成绩
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-UK0bQD0K-1711055624703)]
[外链图片转存中…(img-UybUgAR0-1711055624703)]
[外链图片转存中…(img-HejW4CX7-1711055624704)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
[外链图片转存中…(img-LmHVqTiD-1711055624704)]
最后的内容
在开头跟大家分享的时候我就说,面试我是没有做好准备的,全靠平时的积累,确实有点临时抱佛脚了,以至于我自己还是挺懊恼的。(准备好了或许可以拿个40k,没做准备只有30k+,你们懂那种感觉吗)
如何准备面试?
1、前期铺垫(技术沉积)
程序员面试其实是对于技术的一次摸底考试,你的技术牛逼,那你就是大爷。大厂对于技术的要求主要体现在:基础,原理,深入研究源码,广度,实战五个方面,也只有将原理理论结合实战才能把技术点吃透。
下面是我会看的一些资料笔记,希望能帮助大家由浅入深,由点到面的学习Java,应对大厂面试官的灵魂追问
这部分内容过多,小编只贴出部分内容展示给大家了,见谅见谅!
- Java程序员必看《Java开发核心笔记(华山版)》
[外链图片转存中…(img-gjTEFnlu-1711055624704)]
- Redis学习笔记
[外链图片转存中…(img-DhN8Vl8x-1711055624705)]
- Java并发编程学习笔记
四部分,详细拆分并发编程——并发编程+模式篇+应用篇+原理篇
[外链图片转存中…(img-WUu3MOkU-1711055624705)]
- Java程序员必看书籍《深入理解 ava虚拟机第3版》(pdf版)
[外链图片转存中…(img-h8fYmn9s-1711055624706)]
- 大厂面试必问——数据结构与算法汇集笔记
[外链图片转存中…(img-5cADcl3D-1711055624706)]
其他像Spring,SpringBoot,SpringCloud,SpringCloudAlibaba,Dubbo,Zookeeper,Kafka,RocketMQ,RabbitMQ,Netty,MySQL,Docker,K8s等等我都整理好,这里就不一一展示了。
[外链图片转存中…(img-5zhtOGOY-1711055624706)]
2、狂刷面试题
技术主要是体现在平时的积累实用,面试前准备两个月的时间再好好复习一遍,紧接着就可以刷面试题了,下面这些面试题都是小编精心整理的,贴给大家看看。
①大厂高频45道笔试题(智商题)
[外链图片转存中…(img-gPNSKeIA-1711055624707)]
②BAT大厂面试总结(部分内容截图)
[外链图片转存中…(img-GSHoVJZ9-1711055624707)]
[外链图片转存中…(img-RI7389lC-1711055624707)]
③面试总结
[外链图片转存中…(img-SxFqT2MO-1711055624707)]
[外链图片转存中…(img-dNbCh7WD-1711055624708)]
3、结合实际,修改简历
程序员的简历一定要多下一些功夫,尤其是对一些字眼要再三斟酌,如“精通、熟悉、了解”这三者的区别一定要区分清楚,否则就是在给自己挖坑了。当然不会包装,我可以将我的简历给你参考参考,如果还不够,那下面这些简历模板任你挑选:
[外链图片转存中…(img-CdUh3oqI-1711055624708)]
以上分享,希望大家可以在金三银四跳槽季找到一份好工作,但千万也记住,技术一定是平时工作种累计或者自学(或报班跟着老师学)通过实战累计的,千万不要临时抱佛脚。
另外,面试中遇到不会的问题不妨尝试讲讲自己的思路,因为有些问题不是考察我们的编程能力,而是逻辑思维表达能力;最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。