第四周总结

第四周总结

day17

1.晨写

1.接口和抽象类的区别
1)成员的区别
	成员变量:
		接口:只能是常量,存在默认修饰符 public static final ,可以省略不写
		抽象类:可以是变量,也可以自定义常量
	成员方法:
		接口:只能是抽象方法, 默认修饰符:public abstract ,可以省略不写
		抽象类:既可以存在抽象方法,也可以存在非抽象方法, 如果是抽象方法,abstract不能省略;
	构造方法:
		接口:没有构造方法, 通过接口多态实例化,通过具体的子实现类对象的创建
		抽象类:无参/有参构造方法, (抽象类不能实例化,需要靠具体的子类实例化)分层初始化,先父类初始化,然后在子类				 初始化
2)关系区别
	类与类: (类:包含具体类或者抽象类), 继承关系 extends, 可以单继承,不能多继承,可以多层继承;
	类与接口:实现关系 implements,一个类继承另一个类的同时,可以实现多个接口
	接口与接口:继承关系:extends,可以支持单继承,也可以多继承以及多层继承
3)设计理念的区别
	接口:体现出的这个事物本身不具备的功能,一种额外功能;是一种"like a"的关系
	抽象类: 由于不能实例化,需要具体的子类实例化,体现的是一种"isa"的关系
A类是B类的一种,或者是B是A的一种
2.多态的成员访问特点
Fu f = new Zi(); 向上转型 :父类引用指向子类对象
成员变量:编译看左,运行看左
成员方法:编译看左,运行看右,因为存在方法重写
构造方法:如果Fu是抽象类,分层初始化
	先父类,然后子类分别初始化; ---->抽象类多态
如果Fu是接口,借助于子实现类,但是如果子实现类也是抽象类,这个抽象类一定也有具体子类,还是分层初始化; 
---->接口多态
3.final关键字的特点
final关键字:
	可以修饰成员变量,此时变量是一个"常量";
	可以修饰的成员方法,该方法不能被重写
	可以修饰类,该类不能继承 ; 引用类型 String字符串类 被final修饰
4.方法的形式参数是引用类型,具体类的情况,参数如何传递?
  方法的形式参数如果是引用类型, 具体类
class Teacher{
    public void xxx(){
...
    }
}
class Demo{
    public void show(Teacher t){ //实际参数需要传递的是
        Teacher类对象
        t.xxx() ;
    }
}
测试类去测试
        Demo d = new Demo();
        Teacher t = new Teacher() ; //创建类对象
        d.show(t) ;
5.接口与接口的关系,类与接口的关系
类与接口:实现关系 implements,一个类继承另一个类的同时,可以实现多个接口
接口与接口:继承关系:extends,可以支持单继承,也可以多继承以及多层继承

2.总结

1.关于包的概念 (package):理解
实际开发中分包的概念: 包都是用的是多级包
公司域名反写,中间.隔开
代码分层 不同的包下放的不同代码
业务层代码 service-----------逻辑判断
数据数据访问层 dao(data access object :数据访问对象)
放一些实体类(描述事物的一些属性)pojo/entity/domain
测试类的代码: main 方法测试 ----> 包名 test
以后前后端交互:包名 controller/web :后端接口的具体地址
2.权限修饰符的范围(重点)
private:私有的
       :默认修饰符 :没有任何修饰
protected: 受保护的
public :公共的公开的
3.内部类(了解) —属于设计层面
一个类A中包含了类B ------------------> 只有在源码中看到 list接口集合--
        ArrayList---提供内部类 Itr
        开发中不写内部类(公司内部核心代码)
        内部类
        成员内部类
        局部内部类
class A{
    private int num =200 ;
    class B{
    }
}
class A{
    public void show(){
        class B{
        }
    }
}
重点掌握:匿名内部类
4.当引用类型是一个具体类,调用该方法实际参数如何 传递?
如果是具体类,调用方法的时候,实际参数需要这个类的具体对象
class Student{
    public void study(){
        System.out.println("学习JavaEE之JavaSE基础");
    }
}
class StudentDemo{
    public void method(Student student){//形式参数一个引用类型:具体类,调用该
        方法,实际参数需要一个学生对象
        student.study() ;
    }
}
    //测试类中测试
//调用StudentDemo类的method方法
//创建StudentDemo类对象
    StudentDemo sd = new StudentDemo() ;
    //调用该方法,实际参数需要一个学生对象
    Student s = new Student() ;
sd.method(s); //实际参数s
5.当引用类型是一个抽象类,调用该方法实际参数如何 传递?
方法的形式参数是一个抽象类的情况调用方法的时候实际参数如何传递
        如果是抽象类,调用方法,实际参数需要传递抽象类的子类对象;
abstract class Person{//人类
    public abstract void work(); //工作
}
class PersonDemo{
    //成员方法
    public void show(Person p){//形式参数是一个抽象类,抽象类不能实例化,需要
        new 它的子类对象 抽象类多态
        p.work() ;
    }
}
//必须提供子类
//只能现在提供抽象类的具体的子类
class Worker extends Person{
    @Override
    public void work() {
        System.out.println("爱生活,爱工作,爱高圆圆");
    }
}
    //测试类中测试
    PersonDemo pd = new PersonDemo() ;
    //创建Person对象
//Person p = new Person(); 抽象类不能实例化
// pd.show(p);
//抽象类多态
    Person p = new Worker() ;
pd.show(p);
        System.out.println("-----------------------------------------");
//匿名对象
        pd.show(new Worker());
6.当引用类型是一个接口,调用该方法实际参数如何 传递?
方法的形式参数是一个接口,调用方法,实际参数如何传递
        如果是接口,调用方法,实际参数需要传递接口的子实现类对象
interface Love{
    void love() ;
}
class LoveDemo{
    public void function(Love lo){ //方法形式参数是一个接口类型,接口new不了
        lo.love();
    }
}
//需要提供具体的子实现类
class LoveImpl implements Love{
    @Override
    public void love() {
        System.out.println("love loveImpl...");
    }
}
    //测试类中测试
//调用LoveDemo类的中的function方法
//创建LoveDemo类对象
    LoveDemo ld = new LoveDemo() ;
    //创建Love对象
//Love love = new Love() ;//接口不能实例化,肯定需要接口的子实现类
//ld.function(love);
//接口多态的方式:接口名 对象名 = new 具体的子实现类名() ;
    Love love = new LoveImpl() ;
ld.function(love);
//方式2:
        ld.function(new LoveImpl()) ;
7.当返回值是一个具体类,调用该方法实际参数如何 传递?
方法的返回值如果是引用类型,是一个具体类,方法结束需要返回?
        如果方法的返回是一个具体类,需要返回当前类的具体对象 ;
//学生类
class Student{
    public void study(){
        System.out.println("正在学习JavaEE");
    }
}
//StudentDemo
class StudentDemo{
    public Student method(){//这个的返回值是一个引用类型,具体类---方法结束,
        必须返回一个当前类的具体类对象
// 如何结束???
//return Student;
//方式1 :
/*Student s = new Student() ;
return s;*/
//方式2:匿名对象的格式
        return new Student() ;
    }
}
    //测试类
//调用StudentDemo这个类里面的method方法
    StudentDemo sd = new StudentDemo() ;
    Student s = sd.method(); // 这个方法的本质: new Student();
s.study() ;
8.当返回值是一个抽象类,调用该方法实际参数如何 传递?
如果是抽象类,需要返回的是该抽象类的子类对象;
//抽象类
abstract class Person{
    public abstract void work();
}
class PersonDemo {
    public Person show(){ //方法的返回值是一个抽象类,必须要提供抽象类子类
//??
/* Person p = new Person() ;//抽象类不能new
return p ;*/
//return new Person() ;
//需要抽象类的子类对象:抽象类多态
//方式1:抽象类多态
/* Person p = new Programmer() ;
return p;*/
//方式2:匿名对象
        return new Programmer() ;
    }
}
//需要有抽象类的子类,才能使用抽象类多态
class Programmer extends Person{ //程序员类是具体的子类
    @Override
    public void work() {
        System.out.println("不断的去完成项目开发...");
    }
}
    //测试类中测试
//调用PersonDemo的show方法
    PersonDemo pd = new PersonDemo() ;
    Person person = pd.show(); //show方法本质 new Programmer() ;
person.work();
9.当返回值是一个接口类,调用该方法实际参数如何 传递?
如果是接口,需要返回的是当前接口的子实现类对象;
//定义一个接口
interface Mary{
    void mary() ;
}
//定义一个类
class MaryDemo{
    public Mary method(){ //方法的返回值是接口类型,接口实例化不了的!
//??
//Mary mary = new Mary() ;
// return mary ;
//return new Mary() ;
//方式1:接口多态
// Mary mary = new WeddingCompany() ;
//return mary ;
//方式2:匿名对象
        return new WeddingCompany() ;
    }
}
//需要接口的子实现类
//婚庆公司
class WeddingCompany implements Mary{
    @Override
    public void mary() {
        System.out.println("婚庆公司布置婚礼现场!");
    }
}
    //测试类中测试
    MaryDemo maryDemo = new MaryDemo() ;
    Mary m = maryDemo.method();//method方法本质:创建子实现类对象 new
    WeddingCompany() ;
m.mary();
10.权限修饰符的范围
在同一个包下的同一个类中
    成员方法权限修饰符号的范围问题       
		private私有修饰符 √
		默认修饰符 √
		protected 受保护的 √
		public 公开的 √
    在同一个包下 的子类中/在同一个包下的无关类中
		private私有修饰符
		默认修饰符 √
		protected 受保护的 √
		public 公开的 √
    不同包下的子类中
		private私有修饰符
		默认修饰符
		protected 受保护的 √
		public 公开的 √
    在不同包下的无关类中
		private私有修饰符
		默认修饰符
		protected 受保护的
		public 公开的 √
    权限修饰符的范围:
		private 最小,其次默认修饰符,然后protected受保护的,最大为public

day18

1.晨写

1.关于默认修饰符,私有修饰符private,protected,public的范围
同一个包下的情况
    		  同一个包下的同一个类中 同一个包下的子类中/同一个包下无关类
私有修饰符 private    可以访问                    不能访问
默认修饰符            可以访问                    可以访问
受保护的protected     可以访问                    可以访问
公开的public          可以访问                    可以访问
  
不同包下的情况
                在不同包下的子类中         在不同包下的无关类中
私有修饰符 private     不能访问                   不能访问
默认修饰符             不能访问                   不能访问
受保护的protected      可以访问                   不能访问
公开的public           可以访问                   可以访问
        
private范围最小:仅仅在当前类中
默认修饰符:同一个包下都能访问 大于private
protected:同一个包下或者不同包的子类 大于默认修饰符
public:访问权限最大
2.方法的形式参数如果是抽象类,调用方法实际参数应该传递什么?
方法的形式参数如果是抽象类,调用方法实际参数需要抽象类的子类对象
abstract class Person{
    public abstract void work();
}
class PersonDemo{
    public void method(Person p){ //需要的是抽象类的子类对象
        p.work() ;
    }
}
//需要提供子类
class Worker extends Person{
    public void work(){
        System.out.println("工人都需要工作...") ;
    }
}
    //测试类中:调用PersonDemo类中的method方法
//创建PersonDemo对象
    PersonDemo pd = new PersonDemo() ;
    //抽象类多态:
    Person p = new Worker();
pd.method(p) ;
3.方法的形式参数如果是接口,调用方法实际参数应该传递什么?
方法形式参数如果是接口,调用方法,实际参数需要传递该接口的子实现类对象
interface Mary{
    void mary() ;
}
class MaryDemo{
    public void show(Mary mary){//需要接口的子实现类对象
        mary.mary() ;
    }
}
//提供接口的实现类--具体类
class MaryImpl implements Mary{
    public void mary() {
        System.out.println("结婚了...") ;
    }
}
    //测试类中测试:调用MaryDemo类中show方法
    MaryDemo md = new MaryDemo() ;
    //接口多态
    Mary mary = new MaryImpl();
md.show(mary );
4,方法的返回值如果是接口,该方法结束需要返回什么?(具体代码实现)
方法的返回值如果是接口类型,该方法结束需要返回该接口的子实现类对象
interface Mary{
    void mary() ;
}
class MaryDemo{
    public Mary function(){
// 返回的Mary的子实现类对象
        Mary mary = new MaryImpl() ;
        return mary ;
    }
}
//提供接口的实现类--具体类
class MaryImpl implements Mary{
    public void mary() {
        System.out.println("结婚了...") ;
    }
}
5,方法的返回值如果是具体类,该方法结束需要返回什么?
方法的返回值是具体类,需要返回的是该具体类的对象
class Student{
    public void playGame(){
        System.out.println("玩游戏...");
    }
}
class StudentDemo{
    public Student method(){
//需要Student类的对象
        Student s = new Student () ;
        return s ;
    }
}
    //测试类
//调用StudentDemo类中的method方法
    StudentDemo sd = new StudentDemo() ;
    Student student = sd.method() ;//本质就是创建了学生对象
student.playGame() ;
//(sd.method()).playGame() ; 这样可以的,不建议这样写
6,方法的返回值如果是抽象类,该方法结束需要返回什么?(具体代码实现)
方法的返回值如果是抽象类类型,该方法结束需要返回该抽象类的具体子类对象
abstract class Mary{
    public abstract void mary() ;
}
class MaryDemo{
    public Mary function(){
// 返回的Mary的子类对象
        Mary mary = new MaryTest() ;
        return mary ;
    }
}
//提供抽象类的子类--具体类
class MaryTest extends Mary{
    public void mary() {
        System.out.println("结婚了...") ;
    }
}

2.总结

1.内部类
1.1 局部内部类
1.1.1 格式
class Outer{
    public void show(){
        class Inner{} //局部内部类
    }
}
1.1.2 面试题
局部内部类:在外部类的局部位置,方法定义中
        
         特点:
         不管是局部内部类/成员内部类: 里面的成员都可以直接访问外部类的成员包括私有
        
         如果通过外部类直接访问局部内部类的成员?
         在局部位置上,创建了局部内部类的对象,对象名调用成员方法
        
        
         面试题:
         jdk版本7的版本,局部内部类访问的外部类的成员方法的局部变量,这个局部变量有什么特点?为什么?
         jdk7的版以及以前:int num = 20 ; 立即报错:必须被final修饰!
         jdk8已经优化了,通过反编译查看, num已经被final修饰符
        
         为什么?
         因为局部变量的生命周期,随着方法的调用而存在,随着方法调用结束而消失,
		下面这个代码show(),调用完毕,num应该就被是释放了
        
         但是,show方法里面创建的局部内部类对象,对象里面的成员方法在间接的使用局部变量,
		此时不能让num立即释放,必须为final修饰符
         最终的,无法更改的,是一个常量!
//外部类
class Outer{
    private int x = 100 ;
    //外部类的成员方法
    public void show(){
        int num = 20 ; //隐藏了final修饰符
//局部内部类
        class Inner{
            //成员方法
            public void method(){
                System.out.println(x);//局部内部类的成员在访问外部类的成员
                System.out.println(num) ; //此时这里面需要访问的外部类的局部
                变量num
            }
        }
//创建局部内部类对象
        Inner inner = new Inner() ;
        inner.method();
    }
}
//测试类
public class InnerClassDemo {
    public static void main(String[] args) {
//就创建外部类的对象
        Outer outer = new Outer() ;
        outer.show();
    }
}
1.2 成员内部类
1.2.1 格式
class Outer{
    class Inner{ //成员内部类
    }
}
1.2.2 外部类如何直接访问内部类的成员方法?
class Outer{
    private int num = 100 ;
    class Inner{
//这个是非静态的成员内部类:才能使用外部类名.内部类名 对象名 =
        外部类对象.内部类对象;
        public void show(){
//成员内部类可以直接访问外部类成员,包括私有
            System.out.println(num) ;
        }
    }
    //在外部类的成员方法中访问show
    public void method(){
//创建成员内部类对象
        Inner inner = new Inner();
        inner.show() ;
    }
}
    //测试类中测试直接访问show(
//外部类名.内部类名 对象名 = 外部类对象.内部类对象;
    Outer.Inner oi = new Outer().new Inner();
oi.show() ;
1.2.3 成员内部类的修饰符可以有private;保证数据安全性
private ---学习集合中 ArrayList的源码中会看成员内部被private修饰
         保证数据的安全性,不让这外部类直接访问内部类成员
         伪代码:
         人的身体内有心脏
         class Body{//身体
 成员内部类
 private class Heart{心脏
 //完成手术的功能
         public void operator(){
 System.out.println("心脏搭桥...") ;
 }
 }

         //提供外部类的成员方法
         public void method(){
 //完成逻辑判断..
 //如果这个人是外科医生
 //创建Heart类对象,调用operator()
 }
 }

         外部类名.内部类名 对象名 = 外部类对象.内部类对象;
         Body.Heart bh = new Body().new Heart() ;//错误的写法
1.2.4 成员内部类可以被static修饰
成员被static修饰:这个成员内部类的中的所有的方法:静态的还是非静态的,访问外部类的成员必须只能拿访问静态的东西
        
         静态的成员内部类:外部类直接访问静态内部类的成员,
         将静态的成员内部类看成是外部类的静态成员
         外部类名.内部类名 对象名 = new 外部类名.内部类名();
//外部类
class Outer3{
    private int num = 20 ;
    private static int num2 = 50 ;
    //静态的成员内部类
    static class Inner3{
        //非静态的方法
        public void show(){
//System.out.println(num);
            System.out.println(num2) ;
        }
        //静态的方法
        public static void show2(){
//System.out.println(num);
            System.out.println(num2);
        }
    }
}
//测试类
public class InnerClassDemo3 {
    public static void main(String[] args) {
//要访问静态的成员内部类中的成员方法以及静态方法?
//外部类名.内部类名 对象名 = 外部类对象.内部类对象; //这个格式针对
        成员内部类非静态
// Outer3.Inner3 oi = new Outer3().new Inner3() ;
//外部类名.内部类名 对象名 = new 外部类名.内部类名();
        Outer3.Inner3 oi = new Outer3.Inner3();
        oi.show(); //show() 静态成员内部类的非静态的方法: 必须对象来访问
        oi.show2() ;//show2():静态方法:不推荐 对象名访问访问
//静态东西:使用类名访问
        System.out.println("-------------------------------------------") ;
//Inner3类看成是Outer3静态成员,show2()在Inner3也是静态的方法
        Outer3.Inner3.show2() ;
    }
}
1.2.5 面试题
/**
 * 看程序,补全代码 控制台输出,30,20,10
 *
 * 内部类和外部类就没有继承关系
 */
class Outer4{
    int num = 10 ;
    //成员内部类
    class Innter4{
        int num = 20 ;
        //成员内部类的成员方法
        public void show(){
            int num = 30 ;
//补全代码
            System.out.println(num);//遵循就近
            System.out.println(this.num); //this:代表当前类对象的地址值引用
            Inner4这个类的方法
// System.out.println(new Outer4().num); //new Outer4().num :外部
                    类对象访问
            System.out.println(Outer4.this.num) ; //外部类名.this.变量名: 外
            部类的this限定
        }
    }
}
//测试类
public class Test {
    public static void main(String[] args) {
        Outer4.Innter4 oi = new Outer4().new Innter4() ;
        oi.show();
    }
}
1.3匿名内部类
1.3.1 定义
匿名内部类是局部内部类的一种简化格式(重点)
匿名内部类:就是没有名字的类
        * 格式
        *
        * 抽象类或者接口的匿名内部类
        * new 类名或者是接口名(){ //类:一般都是抽象类 ,具体类也可也,但是不推荐
        *
        * 重写方法() {
        * ...
        * }
        * };
        * 场景范围:就是在方法的形式参数以及返回值是抽象类或者接口的情况下,是一种简
        化格式
        * 匿名内部类的本质:
        * 就是继承该类(抽象类)或者实现了给接口的子类对象;
interface Love{
    void show() ;
    void show2() ;
}
/*
class LoveImpl implements Love{ //类名 LoveImpl
@Override
public void show() {
}
@Override
public void show2() {
}
}
*/
//外部类
class Outer2{
    public void method(){
//没有使用匿名内部类之前
/* class Inner2{
public void show(){
System.out.println("show Inner...");
}
public void show2(){
System.out.println("show2 Inner... ");
}
}
//创建Inner对象
Inner2 inner = new Inner2() ;
inner.show();
inner.show2() ;*/
/*
new 类名或者是接口名(){
* 重写方法() {
...
}
};
*/
//匿名内部类格式:简化书写格式
/* new Love(){
@Override
public void show() {
System.out.println("show Love");
}
@Override
public void show2() {
System.out.println("show2 Love");
}
}.show();
new Love(){
@Override
public void show() {
System.out.println("show Love");
}
@Override
public void show2() {
System.out.println("show2 Love");
}
}.show2();*/
//上面这个格式在访问方法上面比较麻烦
//优化:
//给匿名内部类 new 类名或者接口名(){...重写方法} 起一个对象名字
        Love l = new Love(){
            @Override
            public void show() {
                System.out.println("show Love");
            }
            @Override
            public void show2() {
                System.out.println("show2 Love");
            }
        } ;
        l.show();
        l.show2();
    }
}
//测试类
public class NoClassDemo {
    public static void main(String[] args) {
        Outer2 outer2 = new Outer2() ;
        outer2.method();
    }
}
1.3.2 匿名内部类在开发中的使用 (形式参数是一个抽象类)
/**
 * 匿名内部类在开发情况的使用
 *
 * 方法的形式参数如果是抽象类的情况,调用该方法,实际参数需要传递当前抽象类的
 子类对象
 *
 * 匿名内部类的本质:
 * 代表继承了 该类(抽象类)或者实现类该接口的子类对象
 * new 抽象类名或者接口名(){
 *
 * 重写抽象方法...
 * } ;
 */
abstract class Person{
    public abstract void work() ;//工作
}
class PersonDemo{
    public void method(Person p){ //抽象类 作为形式参数,抽象类不能实例化
        p.work();
    }
}
//定义子类 继承自Person类,重写work
/*class Worker extends Person{
@Override
public void work() {
System.out.println("日日夜夜敲代码...");
}
}*/
//测试类
public class Test {
    public static void main(String[] args) {
//调用PersonDemo类的method 方法
/* PersonDemo pd = new PersonDemo() ;
//抽象类多态:
Person p = new Worker() ;
pd.method(p)*/; // ---->p.work();
//方式2:匿名内部类
        PersonDemo pd = new PersonDemo() ;
// new 抽象类名或者接口名(){
// *
// * 重写抽象方法...
// * } ;
        pd.method(new Person(){
            @Override
            public void work() {
                System.out.println("日日夜夜敲代码");
            }
        });
    }
}
1.3.3 匿名内部类在开发中的使用 (形式参数是一个接口)
/**
 * 方法的形式参数如果是一个接口,调用方法,实际参数需要传递该接口子实现类对象
 */
//飞的接口
interface Fly{
    void fly() ;
}
class FlyDemo{
    public void method(Fly fly){//方法的形式参数是一个接口,调用方法,需要接口的子实现类对象
        fly.fly();
    }
}
//定义一个子实现类 实现Fly接口
class Bird implements Fly{
    @Override
    public void fly() {
        System.out.println("鸟会飞了...");
    }
}
//测试列
public class Test2 {
    public static void main(String[] args) {
//调用FlyDemo类的method方法
        FlyDemo fd = new FlyDemo() ;
//接口多态
        Fly fly = new Bird() ;
        fd.method(fly); //----->fly.fly();
        System.out.println("------------------------------------------");
//直接 匿名内部类
/**
 * new 类名或者接口名(){
 * 重写方法
 * } ;
 */
        FlyDemo fd2 = new FlyDemo() ;
        fd2.method(new Fly(){
            @Override
            public void fly() {
                System.out.println("会飞了...");
            }
        });
    }
}
1.3.4 匿名内部类,在方法的返回值的用法(返回值是抽象类)
/**
 * 返回值问题:
 * 如果方法的返回值是抽象类型,方法结束,需要返回抽象类的子类对象
 */
abstract class Person2{
    public abstract void work() ;
}
class CodeDemo{
    public Person2 show(){
//需要返回抽象类的子类对象
//抽象类多态
/*Person2 p = new Programmer() ;
return p;*/
//使用抽象类的匿名内部类的格式
        return new Person2(){
            @Override
            public void work() {
                System.out.println("程序员日日夜夜开发项目");
            }
        } ;
    }
}
//定义一个子类
class Programmer extends Person2{
    @Override
    public void work() {
        System.out.println("程序员不断开发新的项目");
    }
}
//测试类
public class Test3 {
    public static void main(String[] args) {
//调用CodeDemo的show
/* CodeDemo cd = new CodeDemo() ;
Person2 p = cd.show() ;//---本质:new Programmer() ;
p.work();*/
        CodeDemo cd2 = new CodeDemo() ;
        Person2 person2 = cd2.show();
        person2.work();
    }
}
1.3.5 匿名内部类,在方法的返回值的用法(返回值是接口)
/**
 * 方法的返回值问题:
 * 如果是接口类型,方法结束,必须要返回接口的子实现类对象
 */
//会吼叫的接口
interface CanCry{
    void cry() ; //吼叫的方法
}
class CryDemo{
    public CanCry funtion(){
//返回接口的子实现类对象
//接口多态
/* CanCry canCry = new Cat();
return canCry ;*/
//接口匿名内部类
        return new CanCry() {
            @Override
            public void cry() {
                System.out.println("狗发出汪汪汪的吼叫");
            }
        } ;
    }
}
//定义CanCry接口的子实现类实现cry方法
class Cat implements CanCry{
    @Override
    public void cry() {
        System.out.println("猫发出喵喵的吼叫");
    }
}
//测试类
public class Test4 {
    public static void main(String[] args) {
//调用CryDemo的function方法
/* CryDemo cd = new CryDemo() ;
CanCry cc = cd.funtion() ; //本质---->new Cat() ;
cc.cry();*/
        CryDemo cd2 = new CryDemo() ;
        CanCry cc = cd2.funtion() ; //本质--->接口的匿名内部类--->代表任意子实现类对象
        cc.cry();
    }
2.Java的常用类
 Object:重点类 所有的类的父类:几乎的成员方法都需要被任何子类重写
     toString()/hashCode()/equals()...
     String:重点类(开发中使用最多的)
     String s = new String("hello") ;
     String s2 = "hello" ; //常量---常量池中 (推荐这种方式)
     转换功能:
        char[] toCharArray()
        byte[] getBytes()
     截取:
        subString(int begin,int end) 包前不包后
        字符串的其他功能:替换/去除两端空格...
        StringBuffer:字符串缓冲区
        append(传递任何数据类型) :追加
        StringBuffer----String类型
        String类型----StringBuffer
        Integer :int类型包装类类型:
        String--> Integer-->int
        Integer.parseInt(String字符串值)--->int
        String---->Long--> long
        Long.parseLong(String字符串)---long
        int-->Integer-->String
        Character:char类型的包装类类型:
     判断功能:
public static boolean isUpperCase() :是否为大写
public static boolean isLowerCase() :是否为小写
public static boolean isrDigit() :数字字符
        java.util.Date:日期类 :重点类型转换
        String:文本格式 ------Date格式
     应用场景:
        网页中日期组件
        2022-8-16:String 文本格式------>Date格式
        Calendar:日历类/Math:数学运算/Random:随机数生成器
3.Object类的成员方法和String类重点构造方法总结
Object类里面的toString():建议所有子类重写,直接输出对象名称,看到的一个简明扼要的信息表达式而不是一堆地址值;
Object里面的equals() :建议所有子类重写, 否则,默认比较的引用数据类型的地址值是否一样,
重写之后,比较的是成员信息是否相同;
String类
构造方法
String(char[] chs) :将字符数组构造成String
String(byte[] bytes):将字节数组构造成String
String类的特点:
一旦被创建,其值不能被更改;
4.面试题
 String s1 = "hello" ;
 String s2 = new String("hello") ;
 他们分别创建了几个对象,有什么区别呢?
 s1: 现在常量池中,是否存在这个常量,如果存在,直接返回地址值;否则,开辟新的空间地址值,赋值s1
 s2:在堆内存中申请空间,然后常量"hello",
 还需要在常量池中找是否存在这个常量,有,就返回地址,重新开辟常量池空间

 共同点:都表示创建"hello"字符串实例

day19

1.晨写

1.Object类的getClass()方法的描述的是什么
获取对象的运行时对象的类;
获取一个类的字节码文件对象的方式之一;
2.Object类的toString()以及equals的含义
toString():获取的类对象的字符串形式,所有子类都有重写toString(),直接输出对象名称,打印出的地址值;
		   重写之后,获取出的是了类的成员信息表达式;
equals:比较两个对象是否相同(Object中的源码)
	   不重写Object的equals方法,默认比较的是两个对象的地址值.
重写Object的equals(),在引用类型中比较的是内容是否一样.
重写jdk提供的api,重写equals(),建议重写hashCode();
3.String类的特点是什么
String类:字符串是一个常量,采用创建字符串对象的方式,常量赋值-----代表当前字符串的实例;
		一旦被创建,其值(常量池的地址值)不能被改变,除非重写去赋值.
String类作为引用类型,当成为方法的形式参数和基本类型的效果一致,形式参数的改变,不影响实际参数.
4.String s1 = “hello” ; String s2 = new String (“hello”);s1和s2有什么区别?
共同点:都是表示创建一个字符串实例.
不同点:
  s1:直接在常量池中找是否存在常量,没有直接开辟空间;内存中只有一个内存地址值;
  s2:堆内存中申请空间,默认初始化完毕--->产生堆内存地址,还要常量--->指向常量池地址:在内存中创建两个(堆/常量池)
5.String类的构造方法列举三个
String(char[] chs):将字符数组---构造成String字符串
String(byte[] bytes):将字节数组---构造成String字符串(寻找ASCII码表

2.总结

1.String类的常用功能
1.1 转换功能
char[] toCharArray() :String转换字符数组
        byte[] getBytes() :将字符串转换成字节数组
        String[] spilt(String regex):通过指定的分割符号,将字符串转换成字符串数组
public static String valueOf(int/double/long/....Object):可以将任何类型转换String
        String toUpperCase() :转换大写
        String toLowerCase():转换小写
1.2 获取功能
String subString(int beginindex):通过截取字符串:获取一个新的字符串(从指定位置截取,默认截取到末尾)
String subString(int beginIndex,int endIndex):从指定开始,到指定位置endIndex-1处结束
int length():获取字符串长度
char charAt(int index):返回指定索引处的字符
String concat(String str):将指定字符串拼接到末尾,获取一个新的字符串
1.3 其他功能
public int compareTo(String str):两个按照字典顺序比较
        两个字符串,----转换字符串数组,获取每一个字符串长度;
        Math.min(长度1,长度2):获取长度最小的值
        有一个统计变量 < 最小长度的值
不断的循环
        统计变量从0开始,依次两个字符数组中的每一个字符值
        char v1[统计变量] = 字符 ; "hello"
        char v2[统计变量] = 字符; "abc" "hel"
        判断:
        两个字符是否不一样,
        两个字符相减---->ASCII码表的值在相减
        循环结束完毕,如果上面判断一直不成立
        return 第一个字符串的长度- 第二个长度;
2.StringBuffer和String的区别
String的特点:字符串常量,一旦创建,其值不改变; 不支持可变的字符序列
StringBuffer:支持的可变的字符序列,而且线程安全的,---执行效率低,多线程环境会用,
			单线程环境下用的StringBuilder这个类;
方法的形式参数:
String和基本类型效果一样;形式参数的改变不影响实际参数
StringBuffer:作为方法的形式参数,形式参数的改变,直接影响实际参数;
3.实际开发中:需要把A类型–B 类型,然后B类型转换成A类型?
A类型--->B类型,目的是为了使用B类型的特有功能,但是结果类型可能A类型,
        所有B类型的功能使用完之后,然后在转换A类型;
        只要牵扯类型转换,必须记住常用的转换
/**
 * 类型转换
 * StringBuffer和String的类型转换
 *
 * String---->StringBuffer,目的为了StringBuffer的特有功能
 * StringBuffer--->String,结果需要是String类型
 */
public class StringBufferDemo3 {
    public static void main(String[] args) {
//String----StringBuffer
//有一个字符串
        String s = "hello" ;
//StringBuffer sb = s;
//方式1:利用StringBuffer()无参构造方法+append(String str)
//创建一个字符串缓冲区对象
        StringBuffer sb = new StringBuffer() ;
        sb.append(s) ;
        System.out.println(sb); //字符串缓冲区存储的数据内容 "hello",类型是
        StringBuffer
        System.out.println("----------------------------------");
//方式2:利用StringBuffered的有参构造方法StringBuffer(String str)
        StringBuffer sb2 = new StringBuffer(s) ;
        System.out.println(sb2);
        System.out.println("-----------------------StringBuffer转换成String--
                        ---------------------");
//StringBuffer --->String
                StringBuffer buffer = new StringBuffer("helloworld") ;//字符序列是
        helloworld,外面的类型StringBuffer
//方式1:public String(StringBuffer buffer) ;String类的构造方法
        String str = new String(buffer) ;
        System.out.println(str) ; //内容"helloworld",类型String
        System.out.println("-------------------------------------");
//方式2:public String toString() 显示的应该是字符串缓冲区中的实际的
        字符序列内容
        String str2 = buffer.toString();
        System.out.println(str2);
/*int i = 100 ;
String s4 = "100" ;*/
    }
}
4.自动拆装箱
/**
 * @author 高圆圆
 * @date 2022/8/17 16:44
 *
 * Integer类的构造方法
 * public Integer(int value):将int类型----Integer类型
 * public Integer(String s) throws NumberFormatException :将数字字符串
转换成Integer
 * throws:抛出异常的意思
 * 抛出异常的可能性,当你传入的字符串如果不是数字字
符串,jvm解析的时候,将这个异常就信息打印在控制台上
 *
 *
 */
public class IntegerDemo2 {
    public static void main(String[] args) {
        int i = 100 ;//基本类型
// public Integer(int value):将int类型----Integer类型
        Integer ii = new Integer(i) ;
        System.out.println(ii) ;//100
        ii += 200 ;
        System.out.println(ii);
//public Integer(String s) throws NumberFormatException :将数字字符
        串 转换成Integer
//String s = "hello" ;//字符串: 必须是数字字符串 Integer是int类型包
        装类型
/* String s = "20" ;
Integer iii = new Integer(s) ;
System.out.println(iii);*///20
    }
/**
 * 上面代码的使用反编译工具查看
 * jdk5新特性:自动拆装箱 :基本类型--- 变成对应的引用类型 "装箱"
 * 这些引用类型----->基本类型 ""拆箱
 *
 * int i = 100;
 * Integer ii = new Integer(i); //装箱 int---->Integer
 * System.out.println(ii);
 *
 * //我们的写的代码 ii+=200 ;
 * //反编译工具---将 ii+=200:优化下面格式
 *
 * ii = Integer.valueOf(ii.intValue() + 200); //参数里面:
 ii.intValue()+ 200 : ii--->拆箱 int类型 +200 求和
 * //参数里面完成计算---->int结果
 * public static Integer valueOf(int i) :将int类型的结果----
 >Integer "装箱"
 *
 *
 * System.out.println(ii);
 *
 */
}
5.Integer内存缓冲区
/**
 * @author 高圆圆
 * @date 2022/8/17 17:13
 * 将一个常量值赋值给Integer类型,通过反编译工具 调用的Integer.valueOf(int类
型的值)
 */
public class IntegerTest {
    public static void main(String[] args) {
        Integer i1 = 127 ;
        Integer i2 = 127 ;
        System.out.println(i1==i2) ;//true
        System.out.println(i1.equals(i2)) ;//true
        Integer i3 = 127 ;
        Integer i4 = new Integer(127) ;
        System.out.println(i3==i4) ; //false
        System.out.println(i3.equals(i4)) ;//true
//值128 超过-128-127
        Integer i5 = 128 ; //Integer i5 = new Integer(128);
        Integer i6 = 128 ; //Integer i6 = new Integer(128);
        System.out.println(i5==i6) ; //false
        System.out.println(i5.equals(i6)) ;//true
        Integer i7 = new Integer(128) ;
        Integer i8 = new Integer(128) ;
        System.out.println(i7==i8) ;//false
        System.out.println(i7.equals(i8)) ;//true
    }
}
/**
 * Integer的valueOf(int i)的原码
 * p
 *
 * class Integer{
 *
 * static final Integer cache[]; //Integer类型数组
 *
 * ublic static Integer valueOf(int i) { //127
 * * if (i >= IntegerCache.low && i <= IntegerCache.high)
 * //范围-128-127之间:传递int类型的值在-128-127之间,直接从内部缓存区:(数组
 里面取数据即可!)
 * * return IntegerCache.cache[i + (-IntegerCache.low)];
 *
 * 如果超过这个范围,new Integer(int类型的值)
 * * return new Integer(i);
 * * }
 * //Integer的静态的成员内部类
 * private static class IntegerCache { //Integer的内部缓存区
 *
 *
 * static final int low = -128;
 * static final int high;
 * int h = 127 ;
 * high = h;
 *
 * ...
 *
 * }
 *
 * }
 *
 *
 */
6.int和String的相互转换
/**
 * 基本数据类型:八种 如何转换String
 * String---->基本类型
 * 使用 int举例
 *
 * int---->String :Integer.valueOf(int类型的值)
 * String---->int :Integer.parseInt(数字字符串)
 */
public class IntegerDemo3 {
    public static void main(String[] args) {
//int---->String
        int i = 10 ;
//方式1:字符串拼接 符号+
        System.out.println(i+"");//"10"
//方式2:int---->Integer:装箱---->String
//Intege(int i)
        Integer ii = new Integer(i) ;
//Integer---->String :public String toString()
        String s = ii.toString();
        System.out.println(s) ; //"10"
//方式3:Integer类的静态方法:public static String toString(int i) (推)
        String s2 = Integer.toString(i);
        System.out.println(s2);
        System.out.println("-----------------------------------------------")
        ;
//String --->int
        String str = "100" ;// 数字字符串
//方式1:推荐 Integer 静态方法 public static int parseInt(String
        str): "最常用的"
        int number = Integer.parseInt(str);
        System.out.println(number); //100
//方式2:String---->Integer--->int
//Integer(String s)
        Integer integ = new Integer(str) ;
//public int intValue()
        int number2 = integ.intValue();
        System.out.println(number2) ;
    }
}

day20

1.晨写

1.列举出String类常用的转换功能4个即可
char[] toCharArray(): 将字符串转换成字符数组
static String valueOf(int/double/boolean/Object/char) :将任何数据类型转换成String
byte[] getBytes():将字符串转换成字节数组
String[] spilt(String str) 通过指定的分割符号,将字符串拆分成字符串数组
2.StringBuffer列举出常用的构造方法以及追加功能和反转功能
构造方法:
StringBuffer():创建字符串缓冲区对象,里面没有字符序列
StringBuffer(String str):将字符串类型--->字符串缓冲区StringBuffer
StringBuffer append(追加任何数据类型包括Object)
StringBuffer reverse():反转功能
3.Integer类的内部缓存区做了什么事情
内部缓存区:Integer类的静态的成员内部类 IntegerCache
low和heigh的值: -128-127,如果直接将int类型赋值直接赋值给Integer,实际底层调用的是Integer.valueOf(int的值 ):
判断int类型的值是否在-128-127之间,如果在这两者之间,直接内部缓存区中的Integer[] cache,这里面取数据
如果没有在这两者之间,直接重新new Integer(int类型的值)
4.String和StringBuffer之间如何转换
String---StringBuffer
方式1:通过StringBuffer无参构造方法+append(String str)追加功能
        String s = "hello" ;
//创建StringBuffer对象
        StringBuffer sb = new StringBuffer() ;
        sb.append(s) ;
方式2:通过StringBuffer的有参构造方式
        String s = "hello" ;
        StringBuffer sb = new StringBuffer(s) ;

StringBuffer--->String
方式1:String的构造方法String(StringBuffer buffer)
        StringBuffer sb = new StringBuffer("helloworld") ;
		//创建String对象
        String s = new String(sb) ;
方式2:String的成员方法toString
        StringBuffer sb = new StringBuffer("helloworld") ;
        String s = sb.toString() ;
5.int和String类型之间的转换
基本类型和String转换:中间桥梁:就是基本类型的对应的引用类型
String --->int
	int = Integer.paresInt(String字符串);
String --->long long表示时间概念(毫秒值)
	long l = Long.parseLong(字符串) ;
int---->String
	String s = Integer.toString(int数据) ;

2.总结

1.集合也是个容器,特点:支持可变长度
使用数组存储5个学生,学生有姓名和年龄,(对象数组),将数组学生信息遍历出来--
        Student[] students = new Student[5] ;
        数组存储引用类型,不太合适;----使用集合
        Collection接口 <引用类型> 单例集合 Map<K,V>
List子接口 Set子接口
        List Set
        实现类 实现类
        ArrayList HasHSet ---> HashMap
        Vecetor TreeSet ----> TreeMap
        LinkedList
        接口以及这些常用功能有哪些
2.Character类的特有功能
Character类:char类型 包装类类型
 构造方法:
 Character(char value) :将一个char类型的字符值构造成Character类对象

 常用成员方法:
 判断字符是否为大写字母字符
 public static boolean isUpperCase(char ch)

 判断字符是否为小写字母字符
 public static boolean isLowerCase(char ch)

 判断字符是否为数字字符
 public static boolean isDigit(char ch)
3.集合和数组的区别
1)长度的区别
	数组长度:固定
	集合长度:可变
2)存储数据类型的区别:
	数组:既可以存储基本数据类型,也可以存储引用数据类型
		int[] arr = {1,2,3} ;
		Student[] students = new Student[5] ;
	集合:只能存储引用数据类型
		List<Student>:集合列表
3)存储元素的区别:
	数组只能存储同一种类型的元素
	集合本质可以存储任意引用类型的元素(多种引用类型)
4.Date和String的类型转换
/**
  Date重点:日期文本格式和Date如何转换?
  String日期文本格式 "2022-8-13"------>java.util.Date 日期格式
  Date日期格式 转换成 String
 
  使用中间桥梁:DateFormat类 是一个抽象类,不能实例化,jdk提供更具体的子类:SimpleDateFormat
 
  构造方法
  public SimpleDateFormat(String pattern)
  yyyy:年 MM:月 dd:月中日期 HH:小时 mm:分钟 ss:秒
 
  成员方法:
  Date---->String public String foramt(Date date) :格式化
 
  String--->Date: public Date parse(String dateStr) throws
 ParseException: 解析
  这个本身可能出现异常,如果解析的字符串的格式和 pattern参数的模式匹配,就出错了,解析失败!
  public SimpleDateFormat(String pattern)
 
  String s = "2008-5-12" ;
  SimpleDateFormat sdf = new
 SimpleDateFormat("yyyy年MM月dd日") ;
  SimpleDateFormat sdf = new
 SimpleDateFormat("yyyy-MM-dd ") ;
 
 */
public class DateDemo2 {
    public static void main(String[] args) throws ParseException {
//Date---->String :格式化操作
        Date date = new Date() ; //创建当前系统时间日期对象
        System.out.println(date);
//使用中间桥梁 public SimpleDateFormat(String pattern)
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd") ;
// public String foramt(Date date) :格式化
        String s = sdf.format(date);
        System.out.println(s);
        System.out.println("-------------------------------------") ;
//String--->Date: public Date parse(String dateStr) throws
        ParseException: 解析
        String dataStr = "2008-5-12" ;
//创建中间桥梁 public SimpleDateFormat(String pattern)
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd") ;
//解析
        Date d = sdf2.parse(dataStr);
        System.out.println(d);
    }
}
5.Collection集合的遍历方式1
 使用Collection集合存储5个不同的字符串,5个字符串遍历出来 (使用第一种方式存)
         Collection高级功能:
         Object[] toArray() :将集合转换成对象数组
public class ColletionDemo2 {
    public static void main(String[] args) {
//创建Collection集合
        Collection c = new ArrayList();
//5个不同的字符串
        c.add("hello");
        c.add("world");
        c.add("javaee");
        c.add("javase");
        c.add("mysql");
        System.out.println(c);
//Object[] toArray() :将集合转换成对象数组
        Object[] objects = c.toArray();//相当于:Object obj = new String() ;
        for (int x = 0; x < objects.length; x++) {
//System.out.println(objects[x]+"---
            "+objects[x].length());//objects[x]:Object类型
//不仅要字符串的内容,要输出字符串的长度------>length()--->String
            的特有功能
//向下转型 String
            String s = (String) objects[x];
            System.out.println(s + "---" + s.length());
        }
    }
}

day21

1.重点类

String 掌握一些常用转换功能以及常用的获取功能
StringBuffer:字符串缓冲区, 一些特殊功能反转/截取和String里面的意义的,,StringBuffer和String的转换;
Integer的内部缓存区IntegerCache,int和String的转换(中间桥梁Integer)
Character的常用的判断功能:判断是为大写字母字符,是否为小写字母字符,是否为数字字符...
Random:创建一个伪随机数生成器 Random()+public int nextInt(int n)
System类: gc():了解(开启垃圾回收器,会调用Object类的finalize(),努力回收没有更多引用的对象),
				获取当前系统时间毫秒值...
Date:日期类: java.util.Date---->String日期文本的互相转换
SimpleDataForamt(String pattern)
String---->Date日期格式: public Date
parse(String s):解析
Date---->String日期文本 public String format(Date date):格式化

2.对象数组: 可以存储对象的数组

存储5个学生---存储学生数组中
Student[] students = new Student[5] ;
数组中存储的引用类型,数组的弊端:长度是固定----java提供了"集合"

3.数组和集合的区别

1.长度的区别
	数组长度固定
	集合长度可变
2.存储数据类型的区别
	数组:存储的数据类型:可以是基本数据类型,也可以是引用类型
	集合:存储的数据类型:只能使用引用类型
3.存储元素的区别
	数组:这个容器只能存储同一种类型的元素
	集合:这个容器可以存储不同的引用类型的元素

4.Collection:集合的顶层次的根接口

boolean add(E e) : E---->Element :元素----->理解Object任何Java引用类型
        boolean constains(Object o):判断是否包含元素
        boolean isEmpty():判断集合是否为空
        int size():获取元素数
        Object[] toArray():将集合转换成对象数组
        remove(Object o):删除指定的元素
        void clear() :暴力删除所有元素:清空
      
 使用Collection存储5个不同学生,使用toArray()--->转换Object[]使用
     1.Collection集合的迭代器
        迭代器-----是集合的遍历元素的一种专有方式!
        迭代器的使用原理: 大致的翻阅一下源码
        Collection----->new ArrayList():最基本实现类---然后实现Collection接口的Iterator迭代器
     2.List集合的特有功能--->遍历自定义对象Student/其他类型(有几种方式呢)
        List集合三个子实现类的特点
        ArrayList:底层数组 (普遍用的,效率高,不安全)
        LinkedList:底层链表(添加.删除/修改比较快,查询比较慢的)
        Vector:底层数组(效率低,安全)
        List集合:存储重复元素------------->如何去重?
        存储重复的String,如何去重?
        存储Student(自定义的),如何去重?
     3.Set集合----->元素唯一
        HashSet:保证元素唯一 使用它
        TreeSet :保证元素唯一,还有对元素内容排序(按照学生的年龄从小到大排序?)
        迭代器原码的的大致内容---本质就是接口多态
        
//迭代器接口i
interface Iterator<E>{
    boolean hasNext();//判断是否有下一个元素可以迭代(遍历)
    E next(); //获取下个元素}//规定获取迭代器的方法
}
public interface Iterable<T>{ //最顶层次的接口
    Iterator<E> iterator(); //获取集合迭代器的
}
//接口
interface Collection<E> extends Iterable<T> // T --->Type类型
{
    Iterator<E> iterator();//获取集合迭代器的 继承父接口过来的
}
//子接口
interface List<E> extends Collection<E>{ //iterator()继承过来}
    //具体的实现类
    class ArrayList<E> implements List<E>{
        //将父接口--->继承的父接口----里面所有的抽象方法都重写
        public Iterator<E> iterator() {
//具体的子类实现类这个方法
            return new Itr();
        }
        Iterator<引用类型> 集合迭代器对象 = collection集合对象.iterator() ;本质就
                是实现了Iterator接口的子实现类,具体的类名是ArrayList集合的内部类Itr来实现的;

5.List集合存储自定义对象去重

List<Student> list集合存储自定义对象并去保证元素唯一
 Student:自定义的类

         分析:
             1)假设就创建List集合对象,里面存储重复的字符串数据
			2)创建一个新的List集合,空集合
			3)遍历以前的集合,获取以前的所有元素,在新的集合中判断,是否包含这个
                元素,如果不包含,说明不重复
				将元素添加到新集合中,如果包含,说明重复,重复元素不需要加入到新集合中(找考虑不包含的情况)
			4)最终,遍历新的集合,就是一个不重复的元素!
                
                 刚才存储List<String> String----jdk提供的

         刚才存储重复的字符串并保证元素唯一,里面用到集合的contains(Object a)
里面依赖于一个indexof
 public boolean contains(Object o) {
 return indexOf(o) >= 0; //查询元素
 }

         indexOf方法又依赖于Object的equals方法,--->contains(Object o)间接依赖于
        Object的equals方法
 而List<String>,里面是String类型,本身重写了Object的equals方法,所以比较
                的是字符串内容是否相同

         但是我们List<Student>,自定义的类型,所有必须重写Objectequals(),
 才能比较的是对象的成员信息是否相同,相同认为是同一个人
 不重写比较的就是地址值是否相同
        public class ListTest3 {
            public static void main(String[] args) {
//创建一个集合
                List<Student> list = new ArrayList<>() ;
//创建学生对象
                Student s1 = new Student("张三",25) ;
                Student s2 = new Student("张三",25) ;
                Student s3 = new Student("高圆圆",43) ;
                Student s4 = new Student("高圆圆",43) ;
                Student s5 = new Student("高圆圆",22) ;
                Student s6 = new Student("张嘉译",50) ;
                Student s7 = new Student("张嘉译",50) ;
//将7个学生添加到list集合中
                list.add(s1) ;
                list.add(s2) ;
                list.add(s3) ;
                list.add(s4) ;
                list.add(s5) ;
                list.add(s6) ;
                list.add(s7) ;
//创建一个的空的集合
                List<Student> newList = new ArrayList<>() ;
//遍历以前的集合,
                for(Student s:list){
//获取到每一个学生对象s
//在新集合中判断如果新集合中不包含这个s,说明不重复
                    if(!newList.contains(s)){
//将学生对象s添加到新集合中
                        newList.add(s) ;
                    }
                }
//遍历新集合
                for(Student s:newList){
                    System.out.println(s.getName()+"---"+s.getAge());
                }
            }
        }
**
        * @author 高圆圆
* @date 2022/8/19 16:33
                *
                * 学生类
*/
        public class Student {
            private String name; //姓名
            private int age; //年龄

            public Student() {
            }

            public Student(String name, int age) {
                this.name = name;
                this.age = age;
            }

            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;
            }

            @Override
            public String toString() {
                return "Student{" +
                        "name='" + name + '\'' +
                        ", age=" + age +
                        '}';
            }

            //alt+fn+ins--->eauals and hascode
            @Override
            public boolean equals(Object o) {
                if (this == o) return true;
                if (o == null || getClass() != o.getClass()) return false;
                Student student = (Student) o;
                if (age != student.age) return false;
                return name.equals(student.name);
            }

            @Override
            public int hashCode() {
                int result = name.hashCode();
                result = 31 * result + age;
                return result;
            }
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值