Java基础--重点难点


1、访问控制修饰符

修饰符 当前类 同一包内 子孙类(同一包) 子孙类(不同包) 其他包
public Y Y Y Y Y
protected Y Y Y Y/N(说明) N
default(相当与不些) Y Y Y N N
private Y N N N N

说明:子类与基类不在同一包中:那么在子类中,子类实例可以访问其从基类继承而来的 protected 方法,而不能访问基类实例的protected方法。

2、数字的引用类型

Number的子类(基本数值类型的包装类)、大数值类:BigInteger、BigDecimal

3、Math类

基本数学运算(初等指数、对数、平方根、三角函数)

4、switch语句

支持 byte、short、int、char、String 类型

5、String、StringBuffer、StringBuild

StringBuffer --- 线程安全

StringBuild ---- 快、但线程不安全

6、日期时间类

  • Date ---> 日期时间类

  • SimpleDateFormat ---> 格式华日期,解析字符串为时间......

  • 休眠(sleep)---> Thread.sleep(毫秒数)

  • 测量时间 --->

    • long start=System.currentTimeMills();  // 返回当前时间,1970年01月01日至今的毫秒数
      
  • Calendar 类 ---> 日期时间类,它是抽象类,比 Date 类强大

  • GregorianCalendar 类 ---> 是 Calendar 类的一个具体实现类

7、正则表达式

  • Pattern 类 ---> 自定义正则规则
  • Matcher 类 ---> 根据 Pattern 对象(自定义的正则规则),对字符串解析 and 匹配
  • PatternSyntaxException:正则中的异常处理类

8、输入类

Scanner 类: next()、hasNext()、nextLine()、hasNextLine()、......等方法

9、流、文件、IO操作:

Stream、File、IO操作等等

10、数组 & 集合框架

10-1 数组 + Arrays 数组工具类

  • 数组元素可以是任意类型(即:基本类型、引用类型)。
  • Arrays 工具类可以对数组进一些操作,如:排序等等

10-2 ArrayList

  • 本质是对 数组Object[ ] 的封装,将该数组作为它的一个属性。元素存储在 数组中
  • 对 ArrayList 的操作,实际上也是,用数组工具类---Arrays 来封装数组的CRUD以及排序等操作方法
  • ArrayList 中的数组:默认容量为 10;扩容时,一般是增加当前容量的50% 。ArrayList 的容量属性,用户一般用不到,用的一般是 长度属性--size(元素的个数)

10-3 LinkedList

是双向链表。不是用数组来存储元素,是用内部类--Node来存储元素的

内部类---Node的关键属性:

  • item --> <E>
  • next --> <E>
  • prev --> <E>

LinkedList 的关键属性:

  • first ---> Node<E>
  • last ---> Node<E>
  • size ---> int

10-4 HashSet

继承了 HashMap,且实际是用 HashMap 的 key 来存放元素的。HashMap 的 key 是唯一性的,所以 HashSet 的元素可以达到唯一性。

主要属性:

  • map ---> HashMap :用此属性来存放元素,此 map 的 value 全都为 PRSENT 属性变量
  • PRESENT ---> new Object(): 此属性为常量

对 HashSet 的操作 实际上是 封装对 map 的 Key 的操作。

10-5 LinkedHashSet

继承 HashSet,实现 Set 接口。它不是线程安全的

它自身的构造函数 实际上都是调用 父类的构造函数 ---> 即,HashSet 的 HashSet(int intialCapacity, float loadFactor, boolean dumy)。实际上 HashSet 的这个构造方法是专门提供给 LinkedHashSet 使用的,本质是创建一个 LinkedHashMap

10-6 HashMap

常量属性:

  • DEFAULT_INITIAL_CAPACITY=16 初识容量
  • MAXIMUN_CAPACITY = 2^30 最大容量
  • DEFAULT_LOAD_FACTOR = 0.75f 负载系数
  • TREEIFY_THRESHOLD = 8 阀值
  • UNTREEIFY_THRESHOLD = 6 取消阀值
  • MIN_TREEIFY_THRESHOLD = 64 最小阀值

关键属性:

  • size
  • entrySet
  • table
  • loadFactor
  • threshold

内部类:

  • Node<K, V>

https://blog.csdn.net/qq_41345773/article/details/92066554

HashMap 的 key 的类型:

  • 一切对象皆可为Key。如:Integer、Long、String、Object等。实际中,常使用 String 作为Key值

HashMap 的 key 是如何保证唯一性:

  • 当两个 Key 的 Hash 值 相等时,HashMap会继续 比较这两个Key的值(即,key1.equals(key2)
  • 作为 HashMap 的 Key 的 对象(类class),一般要重写两个方法: hashCode() 方法、equals() 方法。原因见下2句
  • 1、hashCode() 方法:获取该对象的 Hash哈希值。不同的两个对象(值不同的对象),hash哈希值可能相同,所有还要使用 equals() 方法来比较。
  • 2、String 已经重写了这两个方法,所以常使用 String 类型作为 Key。如果使用 自定义类型 作为 Key,则要重写这两个方法

HashMap 的 key 的底层存储:

  • HashMap 使用的是数组+单向链表(红黑树)的形式进行存储key,数组的元素是链表(or 红黑树)。当链表中的元素就是 HashMap的Key。当链表的元素个数大于8个(一个阀值属性)时,链表将转换为红黑树来存储Key
  • 哈希值Hash相同的Key(HashMap是对key取二次哈希)、hashMap 根据 key 的 二次hash 值 对 HashMap的默认承载量length(一般为16)取余 相同的 Key,存放在数组同一个位置。来决定该 key 放置在数组中的哪个索引。
  • 数组中同一个位置的中的所有 Key,以 链表(or 红黑树) 的形式进行存储。
  • 扩容:当元素过多,链表(or 红黑树)中的 Key 的数量也将增加,查找将变慢;这时就需要对数组进行扩容,HashMap 对该数组进行扩容后, 数组容量将是原来的 2倍

HashMap 的 线程安全性问题

  • HashMap 是 线程不安全
  • 可以 使用 Collections.synchronizeMap() 获取一个线程安全的集合
  • ConcurrentHashMap、Hashtable 都是线程安全的。(因为 Hashtable 内含有 synchronize 关键字)
  • HashMap 的 Key 可以为 Null,所有使用时 要考虑 Key的空指针问题,以及 整个集合 为Null 的问题。

最主要的实体类:Entry 类

Entry类实际上是一个单向的链表结构,在 HashMap 中的 Entry里面有的一些属性,如下

  1. K key :即,键值对的key。
  2. V value:即,键值对的value。
  3. Entry<K, V> next :将 一个Entry实体 视为链表的节点,该属性 就是 单向链表的节点指向下一个节点的指针
  4. int hash :该元素的hash值。

在 HashMap 中 Entry类实际上是一个单向的链表结构 (将 Entry 视为节点);HashMap 采用 Entry数组 来存储key-value对,每一个键值对组成了一个Entry实体 。所以说 HashMap 是由 数组+单向链表(红黑树) 进行存储的

10-7 LinkedHashMap

参考:https://www.cnblogs.com/xiaoxi/p/6170590.html

继承了 HashMap,LinkedHashMap 是一个有序的 键值对 Map

如何达到有序:通过维护一个运行于所有条目的双向链表,LinkedHashMap保证了元素迭代的顺序该迭代顺序可以是插入顺序或者是访问顺序。

最主要的实体类:Entry 类

  1. K key:即,键值对的key。
  2. V value:即,键值对的value。
  3. Entry<K, V> next :将 一个Entry实体 视为链表的节点,该属性 就是 单向链表的节点指向下一个节点的指针
  4. int hash :该元素的hash值。
  5. Entry<K, V> before
  6. Entry<K, V> after

前4个属性是从 HashMap 继承,属性 before、after 是 LinkedHashMap 新增的。

属性 K keyV value 用于存储集合中的元素(即,键值对),int hash是决定该Entry实体在 Entry[] 数组中的哪个位置,next是用于维护HashMap指定table位置上连接的Entry的顺序的,before、After是用于维护Entry插入的先后顺序的

属性 键值对(K key+V value) + Entry<K, V> next + int hash 组成 像 HashMap 那样的 数组+单向链表 的结构来存储 键值对元素。

属性 键值对(K key+V value) + Entry<K, V> before + Entry<K, V> after 组成双向循环链表,用于决定键值对元素的 插入顺序 or 访问顺序。

11、反射机制

1、发射是什么(反射式框架设计的灵魂)

  1. JAVA反射机制是在运行状态中

    • 对于任意一个类,都能够知道这个类的所有属性和方法;
    • 对于任意一个对象,都能够调用它的任意一个方法和属性;

    这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

2、反射机制提供的功能

  • 在运行时判断任意一个对象所属的类
  • 在运行时构造任意一个类的对象
  • 在运行时判断任意一个类所具有的成员变量和方法
  • 在运行时调用任意一个对象的成员变量和方法
  • 生成动态代理

3、反射相关的主要 API:

  • java.lang.Class:代表一个类(可暂时把它视为元类)
  • java.lang.reflect.Method:代表类的方法
  • java.lang.reflect.Field:代表类的成员变量
  • java.lang.reflect.Constructor:代表类的构造方法

4、反射的使用场景:

  • Java编码时知道类和对象的具体信息,此时直接对类和对象进行操作即可,无需反射
  • 如果编码时不知道类或者对象的具体信息,此时应该使用反射来实现
    • 比如:类的名称、属性、属性值 等信息放在 XML 文件中,需要在运行时读取 XML 文件,动态获取 类的信息,在编译时根本无法知道该 对象or 类 可能属于哪些类,程序只依靠运行时信息来发现该 对象and类的真是信息。(Spring框架中,基于 XML 的控制反转、依赖注入等就是依靠 反射机制)

5、Class类:(也是Java 为什么可以做到这一点的原因)

  • 对照镜子后可以得到的信息:某个类的属性、方法和构造器、某个类到底实现了哪些接口。对于每个类而言,JRE 都为其保留一个不变的 Class类型的对象。一个 Class对象包含了特定某个类的有关信息。
  • Class 本身也是一个类
  • Class 对象 只能由系统建立对象
  • 一个类 在 JVM 中只会有一个Class 实例
  • 一个Class 对象 对应的是一个加载到 JVM 中的一个 .class 文件。(也是Java 为什么可以做到这一点的原因)
  • 每个类的实例都会记得自己是由哪个 Class 实例所生成
  • 通过 Class 可以完整地得到一个 类 中的 完整结构

参考:https://blog.csdn.net/weixin_42724467/article/details/84311385

6、获取反射入口(class 对象)的三种方法:

  1. 通过 Class.forName("全类名")

    try {
    	Class<?> perClazz = Class.forName("reflect_fanshe.Person");
    	System.out.println(perClazz);
    } catch (ClassNotFoundException e) {
    	e.printStackTrace();
    }
    
  2. 类名.class

    Class<?> perClazz2 = Person.class;
    
  3. 对象.getClass()

    Person person = new Person();
    Class<?> perClazz3 = person.getClass();
    

7、根据反射入口对象(class) 获取类的各种信息:

在第 6 点中获取了 反射入口对象。根据反射入口对象(class) 获取类的各种信息。操作--略,参考链接

8、通过反射获取对象的实例,并操作对象

在 第 7 点 中可获取类的各种信息,便可建立该类的对象实例,然后再通过对象实例进行相关操作。操作--略,参考链接

posted @ 2020-05-31 16:06  roronoa_wang  阅读(104)  评论(0编辑  收藏  举报