7.集合框架

1 集合框架
java中很重要的一个知识点,实际开发中使用的评率较高,java程序中的必备模块
集合就是一个长度可以改变,可以保存任意数据类型的动态数组
集合不是由一个类来完成的,而是由一组接口和类构成了一个框架体现
最上层是一组接口,接下来是接口的实现类,第三层是对集合进行各种操作的工具类
| 接口 | 描述 |
|---|---|
| Collection | 集合框架最基本的接口,一个Collection可以存储一组无序、不唯一的对象 |
| List | Collection的子接口,存储一组有序,但不唯一的对象 |
| Set | Collection的子接口,存储一组无序、唯一的对象 |
| Map | 独立于Collection的另外一个接口,存储一组键值对对象、提供键到值的映射 |
| Iterator | 输出集合元素的接口,一般适用于无序集合,从前到后单向输出 |
| ListIterator | Iterator的子接口,可以双向输出集合中的元素 |
| Enumeration | 传统的输出接口,已经被Iterator取代 |
| SortedSet | Set的子接口,可以对集合中的元素进行排序 |
| SortedMap | Map的自己扣,可以对集合中的键值元素进行排序 |
| Queue | 队列接口,实现队列操作 |
| Map.Entry | Map的内部接口,描述Map中的一个键值对元素 |
1.1Collection接口
Collection是集合框架中最基础的父接口,可以存储一组无序、不唯一的对象,一般不会直接使用该接口,也不能被实例化只能用来提供规范定义。
Collection常用方法
| 方法 | 描述 |
|---|---|
| int size() | 获取集合长度 |
| boolean isEmpty() | 判断集合是否为空 |
| boolean contains(Object o) | 判断集合中是否存在某个对象 |
| Iterator iterator() | 实例化Iterator接口,遍历集合 |
| Object[] toArray() | 将集合转换成为一个Object类型的对象数组 |
| boolean add(E e) | 向集合中添加元素 |
| boolean containsAll(Collection c) | 判断集合中是否存在某个集合的所有元素 |
| boolean addAll(Collection c) | 向集合中添加某个集合的所有元素 |
| boolean removeAll(Collection c) | 从集合中移除某个集合的所有元素 |
| void clear() | 清楚集合中的所有元素 |
| boolean equals(Object o) | 判断两个集合是否相等 |
| int hashCode() | 获取集合的是散列值 |
1.2Collection的子接口
LIst:存放有序、不唯一的元素
Set:存放无序、唯一的元素
Queue:队列接口
1.2.1 List
List是Collection常用的子接口,存储一组有序、不唯一的对象,List接口在继承Collection接口的 基础上进行了扩展
| 方法 | 描述 |
|---|---|
| E get(int index) | 通过下标获取指定位置的元素 |
| E set(int index) | 替换集合中指定位置的元素 |
| void add(int index, E element) | 向集合中指定位置添加元素 |
| E remove(int index) | 通过下标删除集合中指定位置的元素 |
| int indexOf(Object o) | 查找某个对象在集合中的位置 |
| int lastIndexOf(Object o) | 从后向前查找某个对象在集合中的位置 |
| ListIterator listIterator() | 实例化ListIterator接口 |
| List subList(int index1,int index2) | 获取集合中的子集合 |
1.2.2 List接口的实现类
ArrayList是最常用的List接口实现类
java
ArrayList list = new ArrayList();
1.2.3 Set接口
Set是Collection的子接口Set接口以散列的形式存储数据,所有元素没有顺序,可以存储一组无序且唯一的对象
1.2.4 Set接口的实习哪类
HashSet是开发总经常使用的实现类,存储一组无序且唯一的对象,无序是指元素的存储顺序和遍历顺序不一致
java
HashSet hashSet = new HashSet();
LinkHashSet是Set的另外一个子接口,可以存储一组有序且唯一的元素,有序是指元素的存储顺序和遍历顺序一致
java
LinkedHashSet<String> set = new LinkedHashSet<String>();
判断两个对象是否相等的时候,首先调用hashcode方法,如果两个hashcode的值不一样,则可以直接判定两个对象不相等,如果两个的hashcode值相等,再通过equals方法判断是否相等
在Set接口总,除了LinkedHashSet可以存放有序元素之外,TreeSet中保存的元素也是有序,TreeSet的有序和LinkedHashSet的有序不一样
LinkedHashSet的有序是指元素的存储顺序和遍历顺序是一致的,元素怎么存就怎么取
TreeSet的有序是指集合内部会自动给元素进行排序(按照升序的方式)无论存入元素的顺序是什么,遍历的时候都会按照升序进行输出。TreeSet内部会自动按照升序对元素进行排序,所以添加到TreeSet集合中的元素必须具备排序的功能,无法排序的元素是无法添加进去的,那么我们自己定义的对象想要用这个怎么办呢,那就需要去实现Comparable,重写里面的comparableTo()方法,这个方法就是排序的规则
1.3 Map接口
Set list都是Collection的子接口,而Map接口是与Collection完全独立的另外一个体系
Set、List、Collection只能操作单个元素,Map可以操作一对元素,Map中的元素都是以key-value的键值对映射的形式存在的
| 方法 | 描述 |
|---|---|
| int size() | 获取集合长度 |
| boolean isEmpty() | 判断集合是否为空 |
| boolean containsKey(Object o) | 判断集合中时候存在某个key值 |
| boolean containsValue(Object o) | 判断集合中是否存在某个value值 |
| V get(Object key) | 取出集合中key 对应的value |
| V put(K key,V value) | 向集合中添加一组key-value 的元素 |
| V remove(Object key) | 删除集合中key对应的value |
| void clear() | 清除集合中所有的元素 |
| Set keySet() | 取出集合中所有的key,返回一个Set集合 |
| Collection values() | 取出集合中所有的value,返回一个Collection集合 |
| Set entrySet() | 将Map对象转为Set对象 |
| int hashCode() | 获取集合的散列值 |
| boolean equals(Object o) | 比较两个集合是否相等 |
Map是个接口,在实际开发中需要使用Map,必须要通过实现类来完成
HashMap:存储一组无序、Key不可重复,但value可以重复的元素
TreeMap:存储一组有序,key不可重复,但value可以重复的元素,可以按照key来排序
1.4 Collections工具类
集合除了可以存储数据之外,还提供了很多方法来对数据进行操作,但是这些方法都有其局限性,实际操作起来不是很方便,JDK提供了一个工具类Collections,专门用来操作集合,添加元素、元素排序、替换元素。
Collections常用方法
| 方法 | 描述 |
|---|---|
| sort | 根据集合泛型对应的类实现Comparable接口对集合进行排序 |
| binarySearch | 查找元素在集合中的下标,要求集合元素必须是升序排列 |
| get | 根据下标找到集合中的元素 |
| reverse | 对集合元素的顺序进行反转 |
| swap | 交换集合中的所有元素进行替换 |
| fill | 将集合中的所有元素进行替换 |
| min | 返回集合中最小的元素 |
| max | 返回集合中最大的元素 |
| replaceAll | 将集合中的所有该元素进行替换 |
| addAll | 向集合中添加元素 |
1.5 泛型
Generics 是指在类定义时不指定类中的信息的具体数据类型,而是用一个标识符来代替,当外部实例化对象时再指定具体的数据类型。
在定义类或者接口时不明确指定类中的信息的具体数据类型,在实例化时再来指定具体的数据类型,极大地提升了类的扩展性,一个类 可以装载各种不同的数据类型,泛型可以指代类中的成员变量数据类型,方法的返回值数据类型以及方法的参数数据类型。
java
public class Time <T>{
private T t;
public Time(){
}
public T getT(){
return t;
}
public void setT(T t){
this.t = t;
}
}
java
public class test {
public static void main(String[] args) {
Time<Integer> time1 = new Time<>();
time1.setT(10);
System.out.println(time1.getT());
Time<String> time2 = new Time<>();
time2.setT("Hello");
System.out.println(time2.getT());
}
}
在定义一个类时可以同时指定多个泛型标识
java
public class Time <H,M,S>{
private H h;
private M m;
private S s;
public Time(){}
public H getH() {
return h;
}
public void setH(H h) {
this.h = h;
}
public M getM() {
return m;
}
public void setM(M m) {
this.m = m;
}
public S getS() {
return s;
}
public void setS(S s) {
this.s = s;
}
}
java
public class test {
public static void main(String[] args) {
Time<String,Integer,Float> time = new Time<>();
time.setH("十二点");
time.setM(56);
time.setS(1.2f);
System.out.println("现在的时间是:" + time.getH() + ":" + time.getM() + ":" + time.getS());
}
}
泛型通配符
java
public class test {
public static void main(String[] args) {
ArrayList<Integer> list1 = new ArrayList();
list1.add(1);
ArrayList<String> list2 = new ArrayList();
list2.add("a");
test(list1);
test(list2);
}
public static void test(ArrayList<?> list) {
System.out.println(list);
}
}
泛型的上限和下限
我们在使用泛型的时候,数据类型有限制,只能使用一种具体的数据类型,如果希望在此基础上进行适量的扩容,可以通过泛型上限和下限来完成,泛型上限表示实例化时的具体数据类型,可以是上限类型的子类或者是上限类型本身,用extends关键字来修饰,泛型下限表示实例化时的数据类型可以是下限类型的父类或者是下限类型本身,用super关键字来修饰,基本语法如下:
泛型上限:类名<泛型标识 extends 上限类名>
泛型下限:类名<泛型标识 super 下限类名>
java
public class Time <T>{
/**
* 参数的泛型只能是Number或者其子类
*
* @param t
*/
public static void test(Time<? extends Number> t){
}
/**
* 参数的泛型只能是String或者其父类
* @param t
*/
public static void test2(Time<? super String> t){
}
}
泛型接口
定义类时可以添加泛型,定义接口时也可以添加泛型
java
public interface MyInterface<T> {
public T getValue();
}
实现泛型接口有两种方式,一种是实现类在定义时继续使用泛型标识,另一种是实现类在定义时直接给出具体的数据类型
java
public class MyInterfaceImpl<T> implements MyInterface<T> {
private T obj;
public MyInterfaceImpl(T obj) {
this.obj = obj;
}
public T getObj() {
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
@Override
public T getValue() {
return obj;
}
}
java
public class MyInterfaceImpl2 implements MyInterface<String> {
private String str;
public MyInterfaceImpl2(String str) {
this.str = str;
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
@Override
public String getValue() {
return str;
}
}
java
import java.util.ArrayList;
public class test {
public static void main(String[] args) {
MyInterface<String> myInterface = new MyInterfaceImpl<String>("接口");
System.out.println(myInterface.getValue());
MyInterface myInterface1 = new MyInterfaceImpl2("接口2");
System.out.println(myInterface1.getValue());
}
}

评论