JAVA笔记14-泛型

集合

简介:集合用于存储数量不等的对象(只能保存对象),集合类也叫容器类。

集合大致分为:Set、List、Queue、Map,四种体系;

  1. Set,无序 不可重复
  2. List  有序 可重复
  3. Queue 队列 
  4. Map 具有映射关系的集合

集合类都位于java.util包下,这些类都是从Collection和Map接口派生出来的。

Collection接口

collection是set、queue、list的父接口,定义了这三种集合体系都具有、通用的方法。

常用方法:

添加元素、删除元素、返回元素个数、遍历集合元素、判断是否包含某元素等。

Iterator

iterator(迭代器)是一个接口,用于遍历collection中的元素;

collection接口中的iterator()方法返回Iterator接口的实例;

Iterator主要提供如下方法:

  • boolean hasNext(),如果结合还没有迭代完,返回true。
  • Object next(),返回集合中的下一个元素。
  • void remove(),删除集合中上一次next方法返回的元素。

set

    set集合通常记不住元素的添加顺序;不允许包含相同的元素,向set中加入相同元素时会失败(方法返回false);set接口常用的实现类有HashSet、TreeSet、LinkedHashSet。

set实现类

HashSet

HashSet是Set接口的典型实现,它具有一下特点:

HashSet不能保证元素的排列顺序;HashSet集合元素的值可以是Null;HashSet是非线程安全的,多线程环境下须通过代码来保证其同步;

LinkHashSet是HashSet的子类,它具备HashSet的一切特点,同时LinkHashSet采用链表结构维护了元素的插入顺序!

TreeSet

TreeSet可以保证元素的排列顺序,它比HashS多了一些方法:

  1. 返回集合的第一个(最后一个)元素;
  2. 返回集合中位于指定元素之前(之后)的元素;
  3. 返回集合中某个限定范围内的元素组成的子集;

TreeSet采用红黑树的结构来存储元素,它支持两种排序方法:自然排序、定制排序。

自然排序

  1. 添加时,调用元素的compareto方法比较元素的大小,并按照升序排序元素;
  2. 添加到treeset中的对象必须实现comparable接口,该接口定义了compareto方法;
  3. java提供的很多类型均已实现了compareto接口,如包装类、string、data等。
obj1.compareTo(obj2)
该方法返回一个int类型的整数,返回0代表对象相等;
返回整数则表示Object1更大,返回负数表示object2更大。

定制排序

  1. 创建TreeSet时,传入Comparatoe接口的实例;
  2. Comparator接口定义了Compare方法,用于比较两个对象的大小;
  3. TreeSet不再调用compareTo(),转而调用compare()比较大小

例如:

list

List代表有序集合,它提供了根据索引来访问集合的方法:

  1. 将元素插入到集合指定的索引出;
  2. 将指定索引处的元素从集合中删除;
  3. 从集合中返回指定索引处的元素;
  4. 返回某个元素在集合中的索引值;
  5. 从集合中,返回起始索引和结束索引之间的元素所组成的子集。

ListIterator

ArrayList

  1. ArrayList是基于数组实现的List接口;
  2. ArrayList内部封装了一个长度可变的Object[]数组;
  3. 默认该数组的初始长度为10,也可以通过构造器参数显示指定其初始长度;
  4. 每当添加的元素个数超出数组的长度,ArrayList会自动对长度进行扩展。

Vector

  1. Vector也是基于数组的视线,与ArrayList用法相同;
  2. Vector是线程安全的,ArrayList则是非线程安全的;
  3. Vector有保证线程安全的开销,所以性能不如ArrayList;
  4. Vector的子类Stack,用于模拟栈这种数据结构(LIFO)。

Vector、Stack是古老的集合类,性能很差,不建议使用!。Collections工具类可以将ArrayList编程线程安全的类,当程序中需要使用栈的数据结构时,推荐使用ArrayDeque.

Arrays.ArrayList

List Arrays.asList(Object ... o)

该方法可以将多个对象或一个对象数组转换为一个List集合;实际返回的类型是Arrays的内部类,名字也叫ArrayList;Arrays.ArraysList是一个固定长度的集合,可以遍历,但不能增加、删除!

Queue

Queue用于模拟队列,它是一种先进先出的容器。

方法

实现类

Deque

代表双端队列,允许你从两端来操作队列中的元素,并支持入栈及出栈操作。

在Queue的基础上,增加了两类方法:双端队列方法、栈方法。

LinkedList

数组vs链表

  1. 数组需要占据连续的内存空间,访问效率高,增删效率低;
  2. 链表不必占据连续的内存空间,增删效率高,访问效率低,它以指针维护元素顺序,即上一个元素会指向下一个元素。
  3. LInkedList以双链表结构实现

Map

Map是用于保存具有映射关系的数据(key-value、键-值);key和value之间存在单向一对一的关系,通过指定的Key,总能够找到确定的value;map的key不允许重复,同一个map的任何两个Key通过equals比较总返回false。

Map实现类

  1. EnumMap专门用于处理枚举类型的映射关系;

  2. IdentityHashMap与HashMap类似,但该类以严格相等的方式(key1==key2)认定key的相等。

  3. WeakHashMap与HashMap类似,但该类的key采用的是弱引用,而HashMap的key采用的是强引用。

访问方法示例:

HashMap

HashMap是非线程安全的,其性能要高于Hashtable。

HashMap允许使用Null作为Key/value,而Hashtable不允许存入Null.

LinkedHashMap采用双向链表维护键值对的顺序;相对于HashMap,LInkedHashMap在迭代时性能略高,在插入时性能略低。

Properties

属性文件--存储属性名与属性值的文件,如".ini"、".properties"文件。

Properties

擅长处理属性文件,可以很方便地实现对属性文件的读写操作;

提供Load()方法加载属性文件,store()方法保存属性文件;

提供getProperty()方法读取某个属性,setProperty()方法修改某个属性。

TreeMap

TreeMap是一个红黑树的数据结构,在存储键值对时,它按照Key键值对排序。

自然排序

对key进行比较,并根据key按照由小到大的顺序排列键值对;所有的key应该是同一类型,且必须实现comparable接口.

定制排序

创建TreeMap时,传入一个Comparator类型的对象;该对象负责对所有的key,此时不要求key实现comparable接口。

Collections

Collections是一个操作集合的工具类,他提供四类集合操作:

  1. 强大的排序:针对List集合提供了众多的排序方法;
  2. 查找与替换:针对Collection提供了众多的查找和替换元素的方法;
  3. 创建不可变集合:提供三类方法(空的、唯一、只读)来创建一个不可变的集合;
  4. 线程同步的集合:将指定的集合包装秤线程同步的集合,以解决线程安全问题。

hashCode()

散列值

Hash一般翻译为散列,或者哈希;散列是一种算法,利用该算法可以将任意长度的输入转换为固定长度的输出,这是一种将任意长度的信息压缩成固定长度的消息的算法,其输出就是散列值。

hashcode()

  1. Object类中定义的hashCode()方法,就是用于返回该对象的散列值;
  2. Object类对此方法采用默认实现,即返回该对象在内存中的物理地址;
  3. 子类通常需要重写hashCode()方法,根据封装的数据,计算出合理的散列值。

散列表

hashtable,译为散列表,其内部利用散列值决定元素存放的位置;

hashMap,比hashtable更新的API,存储原理和Hashtable相同;

hashSet采用hashmap实现,因此存储原理也与hashtable一致。

散列表采用链表数组实现,数组的每个位置称为桶或槽;对象的散列值对桶个数求余,就是对象在数组中的索引;若桶中没有元素,则直接将对象存入; 若桶中已有元素,则将新对象与桶中元素进行比较,如果相等则放弃插入,若不相等则将其链接到桶中过的最后一个元素之后。

hashcode()&equals()

散列值可以是任何整数、包括正数和负数;

hashcode()、equals()的定义必须兼容,规则是:如果两个对象通过equals()比较返回true,这两个对象的hashcode()值也必须相同。

泛型

集合对元素类型没有任何限制,可能不小心存入你并不期望的数据类型,导致程序运行时报错;

在对象存入集合后,集合丢失了对象的类型信息,统一的当做object处理,经常需要强制类型转换。

参数化类型--泛型

泛型允许在创建集合时指定集合元素的类型,则集合中只能保存这种类型的对象。

//java7
List<String> list=new ArrayList<>();

泛型的定义

集合中的泛型定义

public interface List<E> extends COllections<E>{
          boolean add(E e);
           Iterator<E> iterator();
}

自定义泛型类(接口)

1.允许在定义接口、类、方法时声明类型形参,该类型形参可以在整个接口、类、方法中当成普通类型使用;

2.类型形参将在声明变量、创建对象、调用方法时动态地指定,即传入实际的类型参数(可称为类型实参)。

泛型类的子类(接口)

        为泛型类定义子类时,不能在父类上包含类型形参,但可以包含类型实参;因为这种情况下,不是在定义父类,而是在使用父类,使用时需要传入实参。

类型形参的上限

在定义类型形参时可以设置上限:

class Foo<T extends Number>{}

上述声明表示,传入的类型实参要么是Number类型,要么是Number的子类。

类型通配符及其上限

可以限制通配符的上限

List <? extends Number>

上述声明表示,该集合中存放的是Number类型的对象,或者是Number子类型的对象。

泛型方法

泛型方法,就是在声明方法时定义一个或多个类型形参;

修饰符<S,T> 返回值类型 方法名(参数列表)

  1. 类型形参的声明放在方法修饰符和返回值类型之间;
  2. 类型形参的声明放在尖括号内,多个类型形参之间加以逗号分隔;
  3. 调用方法时,无需显示传入类型实参,因为编译器会根据参数值推断出类型实参。
public static <T> void arrayToList(T[] array,List<T> list){..}

泛型方法与类型通配符

大多数时候都可以使用泛型方法来代替类型通配符!

  1. 方法的参数是集合,并在方法内要向集合中添加元素,则采用泛型方法;
  2. 方法的多个参数之间,或者返回值与参数之间,其类型存在依赖关系,则采用泛型方法。
  • 17
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值