JavaSE复习一

一、属性和局部变量的相同点和不同点

  `1.1 相同点:都是声明在类的内部

   1.2 不同点:属性在方法外,局部变量在方法内。

      属性是跟随类创建的时候一起创建,而局部变量只有在类调用的时候才会开辟相应的内存空间进行创建。

二、Object类

   2.1 equals的使用:

    Person类

public class Person {
    
    private String name;
    private int 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;
    }
    public Person() {
        super();
    }
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    
    //Eclipse中自动生成的equals()方法
    @Override
    public boolean equals(Object obj) {
        System.out.println("Person equals().....");
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Person other = (Person) 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;
    }
    
    
//    //重写Object类中的equals()方法
//    public boolean equals(Object obj) {
//        
//        if(this == obj){
//            return true;
//        }
//        
//        if(obj instanceof Person){
//            Person p = (Person)obj;
//            
//            if(this.name != null){
//                
//                return this.name.equals(p.name) && this.age == p.age;
//            }else{
//                return p.name == null && this.age == p.age;
//            }
//            
//            
//        }else{
//            return false;
//        }
//    }
    
    //手动实现
//    @Override
//    public String toString() {
//        return "Person[name = " + name + ",age = " + age + "]"; 
//    }
    
    //Eclipse自动生成
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
    
}

 

 1 /*
 2  * Object类中equals()的使用
 3  * 
 4  * 面试题:== 和equals()的区别?
 5  * 
 6  * 1. == 的复习:
 7  *   使用在基本数据类型和引用数据类型变量的比较上
 8  *       > 基本数据类型使用:比较两个变量的值是否相等
 9  *       > 引用数据类型使用:比较两个对象的地址值是否相等
10  *   
11  * 2. equals()的使用:
12  *      ① 使用范围:只能使用在引用数据类型变量的调用上。
13  *   ② Object类中equals():仍然比较两个对象的地址值是否相等。
14  *       Object类中的源码:
15  *       public boolean equals(Object obj) {
16             return (this == obj);
17         
18  *      }
19  *   ③ 像String、Date、包装类、File类等重写了Object类中的equals()方法,比较两个对象
20  *   的实体内容是否相等。
21  *   ④ 自定义类来说,我们通常调用equals()时,都不是比较二者的地址是否相同。而是希望比较二者的属性等
22  *   是否相同。那么意味着我们需要在自定义类中重写equals()方法,比较两个对象的内容是否相等。
23  * 
24  */
25 public class EqualsTest {
26     
27     public static void main(String[] args) {
28         
29         // ==
30         //比较基本数据类型:
31         int m1 = 10;
32         int n1 = 10;
33         System.out.println(m1 == n1);//true
34         
35         double d1 = 10;
36         System.out.println(m1 == d1);//true
37         
38         char c1 = ‘A‘;
39         char c2 = 65;
40         System.out.println(c1 == c2);//true
41         
42         //比较引用数据类型:
43         Person p1 = new Person();
44         Person p2 = new Person();
45         System.out.println(p1 == p2);//false
46         Person p3 = p1;
47         System.out.println(p1 == p3);//true
48         
49         System.out.println("*****************************");
50         
51         System.out.println(p1.equals(p2) + "$");//true $
52         
53         String s1 = new String("abc");
54         String s2 = new String("abc");
55         
56         System.out.println(s1 == s2);//false
57         System.out.println(s1.equals(s2));//true
58         
59         
60         Person p4 = new Person("Tom",12);
61         Person p5 = new Person("Tom",12);
62         
63         System.out.println(p4.equals(p5) + "!");//false --->true
64     }
65 }

 

  2.2  String中的equals源码 :

分享图片

   

   2.3 toString()方法的简介和使用:

/*
 * Object类中toString()的使用
 * 
 * 1. 当在输出语句中,通过对象调用toString()方法时,和直接输出对象效果是一样的。
 * 2. java.lang.Object类中toString()定义如下:
 *    public String toString() {
         return getClass().getName() + "@" + Integer.toHexString(hashCode());
      }
 *  3.对于自定义类来说,如果没有重写Object类中的toString()方法,则默认输出对象的地址值。
 *     如果重写toString()的话,则重写的原则:输出对象的实体内容。
 * 
 *  4.像String 、Date、File、包装类等都重写了Object类中的toString()。当调用toString()时,输出
 *  当前对象的实体内容。
 * 
 * 
 */
public class ToStringTest {
    
    public static void main(String[] args) {
        
        Person p1 = new Person("Tom",12);
        System.out.println(p1.toString());//[email protected] -->Person[name = Tom,age = 12]
        System.out.println(p1);//[email protected]>Person[name = Tom,age = 12]
        
        
        String str = new String("abc");
        System.out.println(str);//abc
    }
}

 

三、代码块

  3.1  代码块的执行顺序要先从类的加载机制开始讲起:

    3.1.2 类的加载机制:

(1)  父类的静态代码块

(2)  子类的静态代码块  

(3)  父类的非静态代码块

(4)  父类的构造器

(5)  子类的静态代码块

(6)  子类的构造器

  1 /*
  2  * 类的成员之四:代码块(或初始化块)
  3  * 1.作用:用来初始化类或对象的
  4  * 2.代码块的分类:静态代码块  vs 非静态代码块
  5  * 
  6  * 3. 静态代码块
  7  *         >可以声明输出语句
  8  *         >随着类的加载而执行,仅执行一次
  9  *         >作用:初始化类的信息:类变量
 10  *         >静态代码块内部只能调用静态的属性和方法,不能调用非静态的属性和方法
 11  *         >静态代码块的加载要早于非静态代码块
 12  *         >类中声明了多个静态代码块,则按照声明的先后顺序执行
 13  * 
 14  * 4. 非静态代码块
 15  *         >可以声明输出语句
 16  *         >随着对象的创建而执行
 17  *         >每创建一个对象,就执行一次
 18  *         >作用:初始化对象的信息
 19  *         >非静态代码块中可以调用静态的属性和方法,也可以调用非静态的属性和方法
 20  *         >类中声明了多个非静态代码块,则按照声明的先后顺序执行
 21  * 
 22  * 
 23  * 
 24  * 
 25  */
 26 public class BlockTest {
 27     public static void main(String[] args) {
 28 //        Person.show();
 29         
 30         Person p1 = new Person();
 31         
 32         Person p2 = new Person();
 33         
 34         
 35     }
 36 }
 37 
 38 class Person{
 39     
 40     //属性
 41     String name;
 42     int age;
 43     
 44     static String nation;
 45     
 46     
 47     //非静态代码块2
 48     {
 49         System.out.println("non-static hello2");
 50     }
 51     //非静态代码块1
 52     {
 53         System.out.println("non-static hello1");
 54         age = 1;
 55         
 56 //            nation = "CHN";
 57 //            show();
 58 //            name = "Tom";
 59 //            eat();
 60         
 61     }
 62     
 63     //静态代码块2
 64     static{
 65         System.out.println("static hello2");
 66     }
 67     //静态代码块1
 68     static{
 69         System.out.println("static hello1");
 70         
 71 //        nation = "CHN";
 72 //        show();
 73         //调用非静态的结构:编译不通过
 74 //        name = "Tom";
 75 //        eat();
 76     }
 77     
 78     
 79     
 80     
 81     
 82     
 83     //构造器
 84     public Person(){
 85         
 86     }
 87     public Person(String name,int age){
 88         this.name = name;
 89         this.age = age;
 90     }
 91     
 92     //方法
 93     public void eat(){
 94         System.out.println("人吃饭");
 95     }
 96     public void walk(){
 97         System.out.println("人走路");
 98     }
 99     
100     public static void show(){
101         System.out.println("我是一个人");
102     }
103     
104 }

 

 

 

四、final关键字

  4.1 final关键字相关简介:

final可以用来修饰类、变量、方法

final修饰类:这个类不能提供子类。比如:String类

final修饰方法:此方法不能被重写。比如:Object类中getClass()

final修饰变量:表明此"变量"一旦赋值,就不可修改。--->常量

final修饰属性:常量。

final修饰局部变量:在调用之前必须赋值。一旦赋值,就不可修改。
比如: static final,全局常量 比如:PI

 

五、 abstract关键字

 

5.1  可以用来修饰:类、方法
5.2  具体的:
  5.2.1  abstract修饰类:抽象类
      5.1.1  此类不能实例化
      5.1.2  此类中定义的非静态方法,可以通过继承的方法,使用子类的对象进行调用
      5.1.3  抽象类中有构造器。此时的构造器的作用是便于子类对象实例化时调用

  5.2.2  abstract修饰方法:抽象方法
      5.2.1  抽象方法的特点:没方法体
      5.2.2  抽象类中可以没抽象方法,但是抽象方法所属的类一定是抽象类
      5.2.3  抽象类的子类如果重写了抽象父类中的所的抽象方法,则此子类就可以实例化
      5.2.4  抽象类的子类如果没重写抽象父类中的所的抽象方法,则此子类仍然是一个抽象类

5.3  注意点:
      5.3.1  abstract 不能用来修饰构造器、属性。
      5.3.2  abstract 修饰类,此时的类就不能再用final修饰。
      5.3.3  abstract 修饰方法,此时的方法不能再用final修饰。
      5.3.4  abstract 修饰方法,此时的方法不能再用private修饰 -->private的方法不能被重写
      5.3.5  abstract 修饰方法,此时的方法不能再用static修饰

六:接口 abstract

  

6.1  使用class来定义一个类,使用interface来定义一个接口

 

6.2  类和接口是并列的结构

 

6.3  接口内能定义哪些结构?

1.  jdk7及以前:只能定义全局常量 和 抽象方法

 

2.  全局常量:使用public static final修饰

 

3.  抽象方法:使用public abstract修饰

 

4.  通常定义常量和抽象方法时,可以省略这些修饰符。

 

5.  jdk8:接口中可以定义静态方法、默认方法


6.  jdk9:接口中可以定义私的方法


6.4  接口中不能定义构造器,不能直接实例化一个接口

 

6.5  类与接口是实现关系,使用implements表示。实现类一旦实现了接口,就获取到了接口中声明的
       全局常量和抽象方法。
  6.5.1 如果实现类重写了接口中的所抽象方法,则此类不是一个抽象类,可以实例化
  6.5.2 如果实现类没重写接口中的所的抽象方法,则此类仍然是一个抽象类,不能实例化


6.6  一个类可以实现多个接口:多实现。 vs 类的单继承

  格式: class AA extends BB implements CC,DD,EE{}

6.7  接口与接口之间是继承关系,而且是多继承的。
  interface A extends B,C{}

 

示例代码:

  1 package TestCode;
  2 /*
  3 @author Peny Chen
  4 @create 2019-10-05-16:58
  5 */
  6 
  7 public class USBTest {
  8     public static void main(String[] args) {
  9 
 10         Computer com = new Computer();
 11 
 12         Flash flash = new Flash();
 13         //实参:接口的实现类的对象
 14         com.transferData(flash);
 15 
 16         System.out.println();
 17         //实参:接口的实现类的匿名对象
 18         com.transferData(new Printer());
 19 
 20         //实参:接口的匿名实现类的对象
 21         USB u1 = new USB(){
 22 
 23             @Override
 24             public void startTrasfer() {
 25                 System.out.println("mp3开始播放音乐");
 26             }
 27 
 28             @Override
 29             public void stopTransfer() {
 30                 System.out.println("mp3结束播放音乐");
 31             }
 32 
 33         };
 34 
 35         com.transferData(u1);
 36 
 37         //实参:接口的匿名实现类的匿名对象
 38         com.transferData(new USB(){
 39 
 40             @Override
 41             public void startTrasfer() {
 42                 System.out.println("电纸书开始传输数据");
 43             }
 44 
 45             @Override
 46             public void stopTransfer() {
 47                 System.out.println("电纸书结束传输数据");
 48 
 49             }
 50 
 51         });
 52 
 53     }
 54 
 55 }
 56 
 57 
 58 class Computer{
 59 
 60     public void transferData(USB usb){//体现接口的多态性:USB usb = new Flash();
 61 
 62         usb.startTrasfer();
 63 
 64         System.out.println("具体传输操作的细节....");
 65 
 66         usb.stopTransfer();
 67     }
 68 
 69 
 70 }
 71 
 72 interface USB{
 73     //定义接口的基本尺寸的常量:长、宽、...
 74 
 75     public abstract void startTrasfer();
 76 
 77     public abstract void stopTransfer();
 78 
 79 }
 80 
 81 class Flash implements USB{
 82 
 83     @Override
 84     public void startTrasfer() {
 85         System.out.println("U盘开始传输数据");
 86     }
 87 
 88     @Override
 89     public void stopTransfer() {
 90         System.out.println("U盘结束传输数据");
 91     }
 92 
 93 }
 94 
 95 class Printer implements USB{
 96 
 97     @Override
 98     public void startTrasfer() {
 99         System.out.println("打印机开始传输数据");
100     }
101 
102     @Override
103     public void stopTransfer() {
104         System.out.println("打印机结束传输数据");
105     }
106 
107 }

运行结果:

分享图片

 

6.8  抽象类和接口的异同?
  同:不能实例化。
  异:

    (1)抽象类有构造器;接口没有构造器。
    (2)类:单继承性。 接口:与类多实现,与接口多继承
    (3)类中声明属性、方法、构造器、代码块等
    (4)接口:java 7之前:常量、抽象方法
    (5)java8:静态方法、默认方法
    (6)java9:私有方法

 

七、内部类

  7.1   定义:

    在一个类A的内部定义另一个类B,此时类B就称作类A的内部类(InnerClass),类A就称作类B的外部类(OuterClass)

 

        7.2  内部类的分类:

     成员内部类(直接声明在类内部,方法外)

     局部内部类(声明在外部类的方法内)

 

  7.3  成员内部类的理解:

    7.3.1  作为类

        可以内部定义属性、方法、构造器等

        可以被final修饰

        可以被abstract修饰

    7.3.2   作为外部类的成员

        可以调用外部类的属性、方法等

        可以被4种不同的权限修饰符修饰

        可以被static修饰

 

   7.4  成员内部类

      7.4.1  如何创建成员内部类的对象

1 //创建静态的成员内部类Dog的对象
2 Person.Dog dog = new Person.Dog();
3 dog.jump();
4         
5 //创建非静态的成员内部类Bird的对象
6 Person p = new Person();
7 Person.Bird bird = p.new Bird();
8 bird.fly();

      

      7.4.2  如何在成员内部类中调用外部类的结构

 1 class Person{
 2     
 3     String name = "周毅";
 4     //非静态的成员内部类
 5     class  heart {
 6         
 7         String name = "勇敢的心";
 8             public void show(String name){
 9             System.out.println(name);//方法的形参
10             System.out.println(this.name);//内部类的属性
11             System.out.println(Person.this.name);//外部类的属性
12         }
13     }
14 }    

 

 

八、类的多态性质:

8.1 类的多种状态:向上转型和向下转型

详细步骤参考 博客 zhao_miao
https://blog.csdn.net/zhao_miao/article/details/83750898

这里补充一些知识点:

 

多态的提出是为了参数传递的便捷和通用,防止每次传递类类型参数之前需要 new一个对象出来,简化类类型参数的过程

 分享图片

 

8.2  多态的补充:

多态不适用于属性!编译和运行都看左边,即 Animal a1 = new dog();
a1.weight显示的父类Animal的weight属性

多态是编译时行为还是运行时行为?
多态是运行时行为

九、集合 数组和集合的区别

9.1  数组:有序可重复的序列,但是缺点是大小一旦固定就不可改变。

9.2  集合:
  Collection:

    List:(存储的元素有序可重复)

    ArrayList:底层是数组实现,线程不安全,插入效率不高,遍历效率高

    LinkedList:底层是循环双向链表实现,线程安全,频繁的插入和删除,效率高, 删除效率不高.

    Vector:底层是数组实现,线程安全

 

 

    Set:(存储的元素无序不可重复)

    HashSet:

    向HashSet中添加元素a,首先需要使用元素a所在类的hashCode()方法计算元素a的哈希值。此哈希值经过某种算法计算以后得到其在数组中的存放位置。
    如果此位置上没元素,则元素a添加成功。                                                                                                                    ---情况1
    如果此位置上元素b,需要比较两个元素的hash值,如果hash值不同,则元素a与元素b不相同,则元素a添加成功。 ---情况2
    如果hash值相同,调用元素a所在类的equals()方法,equals()返回值为true:认为元素a与元素b相同,元素a添加失败
    equals()返回值为false:认为元素a与元素b不相同,元素a添加成功                                                                                ---情况3

    添加成功的情况1:直接添加到数组位置上。
    添加成功的情况2、3:元素a与现的元素以链表的方式存储。“七上八下”(即JDK7采取向上扩展链表,JDK8采取向下扩展链表)

    结论:向HashSet中添加数据的话,要求数据所在的类要重写:hashCode()和equals()
    重写两个方法需要保证:hashCode() 和 equals()保持一致性。

 

    TreeSet:LinkedHashSet:作为HashSet的子类;可以照元素添加的顺序实现遍历(原因:使用了链表来记录元素添加的先后顺序。对于频繁的遍历操作,建议使用此类,效率偏高。

 

    LinkedHashSet:底层使用红黑树实现;能够对添加的数据实现排序

 

    Map:(存储的元素以k v 键值对存储)

    HashMap: 作为Map的主要实现类;线程不安全的,效率高;可以存储null的key和value

    TreeMap:TreeMap:可以实现对添加的数据实现排序。针对于key进行自然排序 或定制排序

    LinkedHashMap:作为HashMap的子类;可以照添加的顺序实现遍历操作,对于频繁的遍历操作建议使用此类,效率稍高

    CourrentHashMap:线程安全

    CourrentHashMap线程安全原理可以参考博客  junjiang3    https://www.cnblogs.com/junjiang3/p/8686290.html

相关文章
相关标签/搜索