Collection
集合与数组的对比
相同点:
都是数据的容器,在一个数组或集合中可以存储多个数据
不同点:
元素:
数组中的元素只能是相同,集合中的元素是任意的(泛型)
数组中可以存储基本类型和引用类型,集合只能存储引用类型
长度(元素个数):
数组是定长的,一旦初始化长度就不可以修改 集合长度可以修改,可以删除元素和添加元素
什么是泛型
泛型的声明
泛型就是可以表示一个广泛数据类型的类型参数(泛型只能表示引用类型),把数据类型作为参数来传递。
1)泛型可以声明在方法中:(泛型方法)
public static <标识符> void fun(){}
2)泛型可以声明在类中:(泛型类)
public class 类名<标识符>{
//类体
//泛型可以在类中充当成员变量
//泛型可以再类中充当方法的返回值
//泛型可以在类中充当方法的参数 }
3)泛型可以声明在接口中:(泛型接口)
public interface 接口名<标识符>{
//泛型可以充当接口中方法的返回值
//泛型可以充当接口中方法的参数 }
形式参数:
声明方法时,在方法的参数列表中声明,而且在方法体中会使用到,但是是一个未知的数据
类型参数:
在一个类中声明一个未知的数据类型,在类中可以使用这个类型,但是具体类型取决于实例化时传入的实际 类
泛型使用时得注意事项
1)泛型不能在类中声明静态属性、常量
final修饰的属性必须在声明的同时初始化,所以泛型不能声明常量
static修饰的属性是静态属性,先于对象,泛型类型取决于创建对象时传入的实际类型,所以泛型不能声明静态属性
综上所述:不能使用泛型声明静态属性、常量
2)泛型不能在类中初始化数组,但是可以声明数组
初始化数组时需要给元素进行分配空间,但是泛型类型不确定无法分配空间
3)在类中不能使用泛型声明参数个数相同的重载方法
当一个类中有两个泛型时,创建对象时,两个泛型使用相同类型替换,那么重载方法就是相同的方法(同名,参数列表 也相同)
4)使用不同实际类型创建出的泛型类对象的引用不可以相互赋值
List接口的实现类(相对有序存储、不排重、可通过下标访问集合元素)
1、ArrayList类
ArrayList类是List接口的大小可变数组的实现。
实现了所有可选列表操作,并允许包括null在内的所有元素。
存储特点: 相对有序存储,可以存储相同元素(不排重),可以通过下标访问集合元素,通过数组实现的集合
存储结构:数组
2、LinkedList 类
LinkedList类是List接口的链接列表实现。实现所有可选的列表操作,并且允许所有元素(包括null)。
存储特点: 相对有序存储,可以存储相同元素(不排重),可以通过下标访问集合元素,通过链表实现的集合
存储结构:双向链表
ArrayList 和 LinkedList 的区别
LinkedList集合适用在对元素插入和删除操作较频繁的时候
ArrayList集合适用在对元素查询、遍历操作较频繁的时候
3、Vector类
Vector类可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的组件。但是Vector 的大小可以根据需要增大或缩小,以适应创建 Vector后进行添加或移除项的操作。
3.2、Stack
Stack类表示后进先出(LIFO)的对象栈。是Vector的子类
ArrayList与LinkedList,Vector三种实现类存储的比较
a. 功能基本相同
b. 底层存储结构:ArrayList是数组,LinkedList是链表,Vector是数组
c. Vector是一个古老的集合,从JDK1.0开始就有了,Vector存在一些方法名比较长的方法,xxxElement
d. Vector是线程安全的,效率低,ArrayList是线程不安全的,效率高,推荐使用ArrayList【Collections工具类中 有相应的方法可以将ArrayList改为线程安全的】
e. ArrayList查找遍历比较快,LinkedList插入删除比较快
Set 常用实现类(相对无序存储、排重、不能通过下标访问)
存储特点
相对无序存储,不可以存储相同的元素(排重),不能通过下标访问
1、HashSet类
此类实现Set接口,由哈希表(实际上是一个HashMap实例)支持。
它不保证set的迭代顺序;特别是它不保证该顺序恒久 不变。
此类允许使用null元素。
Hash:哈希——实际含义散列,就是一种算法,把任意长度的输入通过散列算法变换成固定长度的输出,该输出就是散列值。
哈希表:数组加链表,既有数组的优点也有链表的优点。
同时重写hashCode和equals两个方法,可以实现元素的排重效果
//重写equals
public boolean equals(Object obj) {
//先判断传入的参数对象是否是Student对象,若不是直接返回false
if(obj instanceof Student) { //若是,强转成Student对象,并比较属性的值
Student s = (Student) obj;
if(this.name.equals(s.name)) { //若属性的值相同,则返回true
return true;
}
}
return false;
}
@Override
public int hashCode(){
/hashCode方法返回值是int类型,所以重写时需要找到int类型的数据返回,还要保证此方法的返回值与对 象的所有属性都相关,所以返回姓名属性的字符串的长度/
return this.name.length();
}
}
LinkedHashSet 类(有序存储、排重)
LinkedHashSet类是具有可预知迭代顺序(相对有序)的Set接口的哈希表和链接列表实现。是HashSet的子类。
存储特点: 有序存储,不可以存储相同元素(排重),通过链表实现的集合的有序。 LinkedHashSet集合的元素排重与HashSet集合排重方法一致。
TreeSet集合(无序、排重、通过二叉树实现集合重新排序)
是可以给元素进行重新排序的一个Set接口的实现。使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的Comparator进行排序,具体取决于使用的构造方法。
存储特点: 无序存储,排重,通过二叉树实现的集合,可以给元素进行重新排序
TreeSet集合中的无参数构造方法默认使用自然排序的方式对元素进行排序,使用TreeSet集合的定制排序时,创建集合 对象不可以直接使用无参数构造方法,需要使用传入一个Comparator比较器的构造方法创建集合对象。
定制排序
元素需要通过java.util.Comparator接口(比较器)中的compare方法进行比较大小,并排序。
compare方法除了可以进行排序外,还有排重的功能,但是必须在compare方法中对类中所有的属性值都进行判断,否则 不比较那个属性,排重就会忽略哪个属性 。
TreeSet集合中的无参数构造方法默认使用自然排序的方式对元素进行排序,使用TreeSet集合的定制排序时,创建集合 对象不可以直接使用无参数构造方法,需要使用传入一个Comparator比较器的构造方法创建集合对象。
Map接口
性值都进行判断,否则 不比较那个属性,排重就会忽略哪个属性 。
TreeSet集合中的无参数构造方法默认使用自然排序的方式对元素进行排序,使用TreeSet集合的定制排序时,创建集合 对象不可以直接使用无参数构造方法,需要使用传入一个Comparator比较器的构造方法创建集合对象。