ArrayList和LinkedList的区别:如何选择?
ArrayList 实现了 List 接口,继承了 AbstractList 抽象类。
LinkedList 是一个继承自 AbstractSequentialList 的双向链表,因此它也可以被当作堆栈、队列或双端队列进行操作。
两者的使用场景:
*当需要频繁随机访问元素的时候,例如读取大量数据并进行处理或者需要对数据进行排序或查找的场景,可以使用 ArrayList。例如一个学生管理系统,需要对学生列表进行排序或查找操作,可以使用 ArrayList 存储学生信息,以便快速访问和处理。
*当需要频繁插入和删除元素的时候,例如实现队列或栈,或者需要在中间插入或删除元素的场景,可以使用 LinkedList。例如一个实时聊天系统,需要实现一个消息队列,可以使用 LinkedList 存储消息,以便快速插入和删除消息。
*在一些特殊场景下,可能需要同时支持随机访问和插入/删除操作。例如一个在线游戏系统,需要实现一个玩家列表,需要支持快速查找和遍历玩家,同时也需要支持玩家的加入和离开。在这种情况下,可以使用 LinkedList 和 ArrayList 的组合,例如使用 LinkedList 存储玩家,以便快速插入和删除玩家,同时使用 ArrayList 存储玩家列表,以便快速查找和遍历玩家。
Java 泛型
使用类型参数解决了元素的不确定性
在 Java 中,泛型是一种强类型约束机制,可以在编译期间检查类型安全性,并且可以提高代码的复用性和可读性。
*类型参数化:泛型的本质是参数化类型,在定义类、接口或方法时,可以使用一个或多个类型参数来表示参数化类型。
*类型擦除:泛型在编译时会将泛型类型擦除,将泛型类型替换成 Object 类型。这是为了向后兼容,避免对原有的 Java 代码造成影响。
*通配符:通配符用于表示某种未知的类型,例如 List<?> 表示一个可以存储任何类型对象的 List,但是不能对其中的元素进行添加操作。通配符可以用来解决类型不确定的情况,例如在方法参数或返回值中使用。使用通配符可以使方法更加通用,同时保证类型安全。
上限通配符:泛型还提供了上限通配符 <? extends T>,表示通配符只能接受 T 或 T 的子类。使用上限通配符可以提高程序的类型安全性。
下限通配符:用 super 关键字来声明,其语法形式为 <? super T>,其中 T 表示类型参数。它表示的是该类型参数必须是某个指定类的超类(包括该类本身)。
禁止在foreach里执行元素的删除操作
阿里Java开发规约:禁止在foreach里执行元素的删除操作
因为 foreach 循环是基于迭代器实现的,而迭代器在遍历集合时会维护一个 expectedModCount 属性来记录集合被修改的次数。如果在 foreach 循环中执行删除操作会导致 expectedModCount 属性值与实际的 modCount 属性值不一致,从而导致迭代器的 hasNext() 和 next() 方法抛出 ConcurrentModificationException 异常。
为了避免这种情况,应该使用迭代器的 remove() 方法来删除元素,该方法会在删除元素后更新迭代器状态,确保循环的正确性。如果需要在循环中删除元素,应该使用迭代器的 remove() 方法,而不是集合自身的 remove() 方法。
Java Comparable和Comparator的区别
Comparable
如果一个类实现了 Comparable 接口(只需要干一件事,重写 compareTo() 方法),就可以按照自己制定的规则将由它创建的对象进行比较。
该方法的返回值可能为负数,零或者正数,代表的意思是该对象按照排序的规则小于、等于或者大于要比较的对象。如果指定对象的类型与此对象不能进行比较,则引发 ClassCastException 异常。
Comparator
Comparator 接口的定义相比较于 Comparable 就复杂的多了,不过,核心的方法只有两个。
第一个方法 compare(T o1, T o2) 的返回值可能为负数,零或者正数,代表的意思是第一个对象小于、等于或者大于第二个对象。
第二个方法 equals(Object obj) 需要传入一个 Object 作为参数,并判断该 Object 是否和 Comparator 保持一致。
到底该用哪一个?
*一个类实现了 Comparable 接口,意味着该类的对象可以直接进行比较(排序),但比较(排序)的方式只有一种,很单一。
*一个类如果想要保持原样,又需要进行不同方式的比较(排序),就可以定制比较器(实现 Comparator 接口)。
*Comparable 接口在 java.lang 包下,而 Comparator 接口在 java.util 包下。