当前位置: 首页 > article >正文

1/31每日

1. Exception 和 Error 的区别

ExceptionError 都是 Throwable 类的子类,但它们有不同的用途和含义。

  • Exception: 代表程序运行时可以处理的异常情况。Exception 是可预料的,通常是程序逻辑错误或者其他外部因素导致的,程序可以通过捕获这些异常来做出适当的处理。例如:FileNotFoundExceptionIOException 等。

  • Error: 代表程序无法控制的严重错误,通常是由系统或硬件故障引起的。Error 不应当被捕获和处理,通常意味着程序的执行不能继续下去。例如:OutOfMemoryErrorStackOverflowError 等。

总结:

  • Exception 是可以被捕获和处理的异常。
  • Error 是无法被程序处理的错误,通常表示虚拟机或硬件故障。

2. Checked Exception 和 Unchecked Exception 的区别

Checked ExceptionUnchecked Exception 是 Java 中异常的两大类,主要区别在于是否需要显式处理(捕获或者声明)。

  • Checked Exception:

    • 需要显式处理,即程序必须通过 try-catch 块捕获,或者通过 throws 声明抛出。
    • 通常代表可以预见和处理的异常,如文件未找到、网络连接中断等。
    • 例如:IOExceptionSQLException
  • Unchecked Exception:

    • 不需要显式处理,通常是程序中的错误,系统不会强制要求处理这些异常。
    • 继承自 RuntimeException,通常是程序的逻辑错误,例如数组越界、空指针访问等。
    • 例如:NullPointerExceptionArrayIndexOutOfBoundsException

Java 三大特性

Java 的三大特性是:封装 (Encapsulation)继承 (Inheritance)多态 (Polymorphism)。这三大特性是面向对象编程的核心,帮助开发者组织和管理代码,提升可重用性和扩展性

  1. 封装 (Encapsulation):

    • 定义: 封装是将对象的状态(属性)和行为(方法)绑定在一起,并对外界隐藏实现细节,只有通过公有方法(如 getter 和 setter)访问对象的状态。
    • 好处: 通过封装,可以保护对象的内部状态不被随意改变,增加了安全性和灵活性,也提高了代码的可维护性。
    • 实现:
      • 将类的属性声明为 private,然后通过 public 方法提供对属性的访问。

继承 (Inheritance):

  • 定义: 继承是指一个类(子类)可以继承另一个类(父类)的属性和方法,使得子类可以复用父类的代码,同时可以扩展或修改父类的行为。
  • 好处: 继承使得代码得以复用,避免了重复代码,并且有助于构建类之间的层次结构。

多态 (Polymorphism):

  • 定义: 多态是指同一个方法在不同的对象中表现出不同的行为。通过多态,可以用统一的接口调用不同实现类的对象,增强代码的灵活性和可扩展性。
  • 好处: 多态支持程序设计中的“开放-封闭原则”,即对扩展开放,对修改封闭。即我们可以扩展新的子类,不需要修改现有代码。
  • 实现:
    • 方法重载:同一个类中,方法名称相同但参数不同,表现为编译时多态。
    • 方法重写:子类重写父类的方法,表现为运行时多态。

方法重载 (Overloading):

  • 同一个类中,方法名称相同,但参数类型、数量或顺序不同。
  • 这种多态性是在编译时确定的,叫做编译时多态。

方法重写 (Overriding):

  • 子类可以重写父类的方法,调用时会根据实际对象的类型来决定调用哪个方法。
  • 这种多态性是在运行时确定的,叫做运行时多态。

多态的优势

  • 灵活性: 可以通过父类引用指向子类对象,调用父类方法时实际执行的是子类重写的方法。

        在上面的例子中,animal1animal2 都是 Animal 类型的引用,但它们指向的是 DogCat 的实例。调用 sound() 方法时,实际执行的是 DogCat 中重写的方法,而不是 Animal 类中的方法,这体现了灵活性。

class Animal {
    public void sound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    @Override
    public void sound() {
        System.out.println("Dog barks");
    }
}

class Cat extends Animal {
    @Override
    public void sound() {
        System.out.println("Cat meows");
    }
}

public class Test {
    public static void main(String[] args) {
        Animal animal1 = new Dog();  // 父类引用指向子类对象
        Animal animal2 = new Cat();  // 父类引用指向子类对象
        
        animal1.sound();  // 输出 "Dog barks"
        animal2.sound();  // 输出 "Cat meows"
    }
}
  • 可扩展性: 新增子类时,不需要修改已有代码,只需新增子类并实现父类的接口或方法。
// 定义 Shape 接口
interface Shape {
    void draw();
}

// Circle 类实现了 Shape 接口
class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing Circle");
    }
}

// Rectangle 类实现了 Shape 接口
class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing Rectangle");
    }
}

// Triangle 类实现了 Shape 接口
class Triangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing Triangle");
    }
}

// 测试类
public class Test {
    public static void main(String[] args) {
        // 创建 Shape 类型的数组
        Shape[] shapes = { new Circle(), new Rectangle(), new Triangle() };
        
        // 使用多态遍历数组并调用每个形状的 draw 方法
        for (Shape shape : shapes) {
            shape.draw();
        }
    }
}
  • 代码简洁: 通过多态,代码更加简洁,避免了大量的 ifswitch 语句来判断类型。
class Animal {
    public void sound(String animalType) {
        if (animalType.equals("Dog")) {
            System.out.println("Dog barks");
        } else if (animalType.equals("Cat")) {
            System.out.println("Cat meows");
        } else {
            System.out.println("Unknown animal");
        }
    }
}

public class Test {
    public static void main(String[] args) {
        Animal animal = new Animal();
        animal.sound("Dog");  // 通过判断字符串来调用不同的行为
        animal.sound("Cat");
    }
}



abstract class Animal {
    public abstract void sound();
}

class Dog extends Animal {
    @Override
    public void sound() {
        System.out.println("Dog barks");
    }
}

class Cat extends Animal {
    @Override
    public void sound() {
        System.out.println("Cat meows");
    }
}

public class Test {
    public static void main(String[] args) {
        Animal dog = new Dog();
        Animal cat = new Cat();
        
        dog.sound();  // 输出 "Dog barks"
        cat.sound();  // 输出 "Cat meows"
    }
}
                                Collection
                                  |
        ----------------------------------------------------------------
        |                               |                               |
      List                           Set                            Queue
        |                               |                               |
  -----------------              ---------------               --------------
  |               |              |             |               |            |
ArrayList    LinkedList      HashSet     TreeSet        LinkedList    PriorityQueue
                                          |
                                        LinkedHashSet

Collection:这是所有集合类的根接口。它定义了一些基本的集合操作方法,如 add()remove()size() 等。

  • List:继承自 Collection,是有序的集合,允许重复元素。常见的实现类有:

    • ArrayList:基于动态数组实现,查找速度快,插入和删除效率较低。
    • LinkedList:基于双向链表实现,适合频繁的插入和删除操作。
  • Set:继承自 Collection,是无序的集合,不允许重复元素。常见的实现类有:

    • HashSet:基于哈希表实现,元素无序,查找速度快。
    • LinkedHashSet:基于哈希表和链表实现,保持插入顺序。
    • TreeSet:基于红黑树实现,元素自动按升序排序。
  • Queue:继承自 Collection,用于按顺序处理元素。常见的实现类有:

    • LinkedList:既是 List 的实现类,也是 Queue 的实现类,适用于队列操作。
    • PriorityQueue:基于优先级堆实现,元素按优先级排序。。

 

HashMap 的扩容机制是基于负载因子(load factor)和容量(capacity)来动态调整大小的。具体流程如下:

  1. 负载因子HashMap 默认的负载因子是 0.75,意味着当 HashMap 中存储的元素个数达到了容量的 75% 时,会触发扩容。

  2. 容量HashMap 的容量是它可以存储的桶的数量。扩容时,HashMap 会将桶的数量扩展为原来容量的两倍。

  3. 扩容触发条件:当 HashMap 中的元素数量超过了负载因子和当前容量的乘积时(即元素数量 >= 容量 * 负载因子),就会触发扩容。

  4. 扩容过程

    • 新的容量是原来容量的两倍。
    • 所有的键值对都会重新计算哈希值并被重新分配到新的桶中,因为桶的数量发生了变化。这个过程可能会带来一定的性能开销,特别是当数据量很大的时候。
  5. 扩容后的影响:扩容后,HashMap 的性能通常会稍微降低,直到再填充一些元素后,性能才会回到正常水平。

总的来说,HashMap 通过负载因子和容量来平衡空间和性能,避免了过早的扩容带来的不必要开销,同时也防止了因为容量不足导致的频繁扩容。


http://www.kler.cn/a/527921.html

相关文章:

  • SQL server 数据库使用整理
  • 【Proteus仿真】【51单片机】多功能计算器系统设计
  • HTML<hgroup>标签
  • NVIDIA GPU介绍:概念、序列、核心、A100、H100
  • 策略梯度 (Policy Gradient):直接优化策略的强化学习方法
  • 深入探讨:服务器如何响应前端请求及后端如何查看前端提交的数据
  • 事务02之锁机制
  • Linux中部署Yolov5详解
  • 嵌入式知识点总结 Linux驱动 (八)-Linux设备驱动
  • H. Mad City
  • 深度学习编译器的演进:从计算图到跨硬件部署的自动化之路
  • 《大数据时代“快刀”:Flink实时数据处理框架优势全解析》
  • 翻译: Dario Amodei 关于DeepSeek与出口管制一
  • (二)QT——按钮小程序
  • 本地运行大模型效果及配置展示
  • 牛客周赛 Round 77
  • Java 16进制 10进制 2进制数 相互的转换
  • 数据分析系列--⑦RapidMiner模型评价(基于泰坦尼克号案例含数据集)
  • 通过.yml文件创建环境
  • 反射、枚举以及lambda表达式
  • Ubuntu下的Doxygen+VScode实现C/C++接口文档自动生成
  • 想品客老师的第九天:原型和继承
  • Nginx代理
  • 面试回顾——1
  • JAVA实战开源项目:房屋租赁系统(Vue+SpringBoot) 附源码
  • Visual RAG: Expanding MLLM visual knowledge without fine-tuning 论文简介