java list api_Java核心API -- 6(Collection集合List、Set、ArrayList、HashSet)

1. Collection集合框架

Java.util.Collection接口

|--List子接口

|--ArrayList实现类

|--LinkedList实现类

|--Vector实现类

|--Stack(栈,继承Vector,先进后出)

|--Set子接口

|--HashSet实现类

|--TreeSet实现类

|--Queue接口(普通队列,先进先出)

|--Deque子接口(双端队列)

|--ArrayDeque实现类

2. 泛型

1)泛型是 JDK1.5引入的新特性,泛型的本质是参数化类型。在类、接口、方法的定义过程中,所操作的数据类型为传入的指定参数类型。所有的集合类型都带有泛型参数,这样在创建集合时可以指定放入集合中的对象类型。同时,编译器会以此类型进行检查。

2)ArrayList支持泛型,泛型尖括号里的符号可随便些,但通常大写E。

3)迭代器也支持泛型,但是迭代器使用的泛型应该和它所迭代的集合的泛型类型一致!

4)泛型只支持引用类型,不支持基本类型,但可以使用对应的包装类

5)如果泛型不指定类型的话,默认为Object类型。

案例6:

9a3c653425f319d40ef6bb2a7e999b63.png

3.List接口和Set接口

1)List接口:List接口是Collection的子接口,用于定义线性表数据结构,元素可重复、有序的;可以将List理解为存放对象的数组,只不过其元素个数可以动态的增加或减少。

(1) List接口的两个常见的实现类:ArrayList和LinkedList,分别用动态数组和链表的方式实现了List接口。List、ArrayList和LinkedList均处于java.util包下。

(2) 可以认为ArrayList和LinkedList的方法在逻辑上完全一样,只是在性能上有一定的差别,ArrayList更适合于随机访问,而LinkedList更适合于插入和删除,在性能要求不是特别苛刻的情形下可以忽略这个差别。

(3) 使用List我们不需要在创建的时候考虑容量集合的容量是根据其所保存的元素决定的换句话说,集合的容量是可以自动扩充的。

(4) List的实现类会重写toString方法,依次调用所包含对象的toString方法,返回集合中所包含对象的字符串表现 。

2)Set接口:Set接口是Collection的子接口,用于存储不重复的元素,元素是无序的。

(1) HashSet和TreeSet是Set集合的两个常见的实现类,分别用hash表和排序二叉树的方式实现了Set集合。HashSet是使用散列算法实现Set的。

(2) Set集合没有get(int index)方法,我们不能像使用List那样,根据下标获取元素。想获取元素需要使用Iterator。

(3) 向集合添加元素也使用add方法,但是add方法不是向集合末尾追加元素,因为无序。

4. ArrayList实现类的常用方法

(1) add(Object obj):向想集合末尾追加一个新元素,从该方法的参数定义不难看出,集合可以存放任意类型的元素,但在实际编程中我们发现,几乎不会向集合中存放一种以上的不同类型的元素。

(2) size()方法:返回当前集合中存放对象的数量。

(3) clear()方法:用于清空集合。

(4) isEmpty()方法:用于返回集合是否为空。

案例7:

4deec5a436b8e916baacba079a5f36f7.png

(5) contains(Object obj)方法:检查给定对象是否被包含在集合中,检查规则是将obj对象与集合中每个元素进行equals比较,若比对了所有元素均没有equals为true的则返回false。注意事项:根据情况重写equals:若比较是否是同一个对象,则不需要重写,直接用contains里的equals比较即可。若重写equals为内容是否相同,则按内容比较,不管是否同一个对象。是否重写元素的equals方法对集合的操作结果有很大的效果不同!

(6) boolean remove(Object obj)方法:删除一个元素,不重写equals,不会有元素被删除(因为比较的是对象的地址,都不相同),重写equals为按内容比较,则删除第一个匹配的就退出,其他即使内容相同也不会被删除。

973d45073b79cbd30d653da0f08c71a8.png

(7) Object remove(int index)方法:移除此列表中指定位置上的元素。向左移动所有后续元素(将其索引减1)。因此在做删除操作时集合的大小为动态变化的,为了防止漏删,必须从后往前删!

63831f925a438516317f2445b5689c12.png

(8)Object get(int index)方法:根据元素下标获取对应位置的元素并返回。

(9) Object set(int index,Object newElement)方法:将index位置的元素修改为newElement,修改后将被修改的元素返回。可实现将List中第i个和第j个元素交换的功能:list.set ( i , list.set ( j , list.get ( i ) ) ) ;

(10) add(int index,Object newElement)方法:使用add的重载方法,我们可以向index指定位置插入newElement,原位置的元素自动向后移动,即所谓的“插队”。

51ee80eebf3db08700960703472f13d2.png

(11) Object[] toArray()方法:该方法继承自Collection的方法,该方法会将集合以对象数组的形式返回。

(12) List subList(int fromIndex, int toIndex)方法:获取子集合,但在获取子集后,若对子集合的元素进行修改,则会影响原来的集合。

52640fd97b208f62ea7facf21848dd14.png

5. HashSet实现类常用常用方法

(1)  boolean add(E e) :如果此 set 中尚未包含指定元素,则添加指定元素。

(2) void clear() :从此 set 中移除所有元素。

(3) Object clone() :返回此 HashSet 实例的浅表副本:并没有复制这些元素本身。

(4) boolean contains(Object o) :如果此 set 包含指定元素,则返回 true。

(5) boolean isEmpty() :如果此 set 不包含任何元素,则返回 true。

(6) Iterator iterator():返回对此 set 中元素进行迭代的迭代器。

(7) boolean remove(Object o):如果指定元素存在于此 set 中,则将其移除。

(8) int size() :返回此 set 中的元素的数量(set 的容量)。

注意事项:

1)hashCode对HashSet的影响:若我们不重写hashCode,那么使用的就是Object提供的,而该方法是返回地址(句柄)!换句话说,就是不同的对象,hashCode不同。

2)对于重写了equals方法的对象,强烈要求重写继承自Object类的hashCode方法的,因为重写hashCode方法与否会对集合操作有影响!

3)重写hashCode方法需要注意两点:①与equals方法的一致性,即equals比较返回为true的对象其hashCode方法返回值应该相同(优肯不同)。②hashCode返回的数值应该符合hash算法要求,如果有很多对象的hashCode方法返回值都相同,则会大大降低hash表的效率。一般情况下,可以使用IDE(如Eclipse)提供的工具自动生成hashCode方法。

4)boolean contains(Object o)方法:查看对象是否在set中被包含。下例虽然有新创建的对象,但是通过散列算法找到了位置后,和里面存放的元素进行equals比较为true,所以依然认为是被包含的(重写equals了时)。

5)HashCode方法和equals方法都重写时对hashSet的影响:将两个对象同时放入HashSet集合,发现存在,不再放入(不重复集)。当我们重写了Point的equals方法和hashCode方法后,我们发现虽然p1和p2是两个对象,但是当我们将他们同时放入集合时,p2对象并没有被添加进集合。因为p1在放入后,p2放入时根据p2的hashCode计算的位置相同,且p2与该位置的p1的equals比较为true, hashSet认为该对象已经存在,所以拒绝将p2存入集合。

案例8:

3e87f4a58e90b0f83dd1bed735bd5428.png

6)不重写hashCode方法,但是重写了equals方法对hashSet的影响:两个对象都可以放入HashStet集合中,因为两个对象具有不用的hashCode值,那么当他们在放入集合时,通过hashCode值进行的散列算法结果就不同。那么他们会被放入集合的不同位置,位置不相同,HashSet则认为它们不同,所以他们可以全部被放入集合。

7)重写了hashCode方法,但是不重写equals方法对hashSet的影响:在hashCode相同的情况下,在存放元素时,他们会在相同的位置,hashSet会在相同位置上将后放入的对象与该位置其他对象一次进行equals比较,若不相同,则将其存入在同一个位置存入若干元素,这些元素会被放入一个链表中。由此可以看出,我们应该尽量使得多种类的不同对象的hashcode值不同,这样才可以提高HashSet在检索元素时的效率,否则可能检索效率还不如List。注意:两个对象值相同(x.equals(y) == true),但却可有不同的hash code。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可调整大小的数组的实现List接口。 实现所有可选列表操作,并允许所有元素,包括null 。 除了实现List 接口之外,该类还提供了一些方法来操纵内部使用的存储列表的数组的大小。 (这个类是大致相当于Vector,不同之处在于它是不同步的)。 该size,isEmpty,get,set,iterator和listIterator操作在固定时间内运行。 add操作以摊余常数运行 ,即添加n个元素需要O(n)个时间。 所有其他操作都以线性时间运行(粗略地说)。 与LinkedList实施相比,常数因子较低。 每个ArrayList实例都有一个容量 。 容量是用于存储列表中的元素的数组的大小。 它总是至少与列表大小一样大。 当元素添加到ArrayList时,其容量会自动增长。 没有规定增长政策的细节,除了添加元素具有不变的摊销时间成本。 应用程序可以添加大量使用ensureCapacity操作元件的前增大ArrayList实例的容量。 这可能会减少增量重新分配的数量。 请注意,此实现不同步。 如果多个线程同时访问884457282749实例,并且至少有一个线程在结构上修改列表,则必须在外部进行同步。 (结构修改是添加或删除一个或多个元素的任何操作,或明确调整后台数组的大小;仅设置元素的值不是结构修改。)这通常是通过在一些自然地封装了列表。 如果没有这样的对象存在,列表应该使用Collections.synchronizedList方法“包装”。 这最好在创建时完成,以防止意外的不同步访问列表: List list = Collections.synchronizedList(new ArrayList(...)); The iterators returned by this class's个 iterator和listIterator方法是快速失败的 :如果列表在任何时间从结构上修改创建迭代器之后,以任何方式除非通过迭代器自身remove种或add方法,迭代器都将抛出一个ConcurrentModificationException 。 因此,面对并发修改,迭代器将快速而干净地失败,而不是在未来未确定的时间冒着任意的非确定性行为。 请注意,迭代器的故障快速行为无法保证,因为一般来说,在不同步并发修改的情况下,无法做出任何硬性保证。 失败快速迭代器尽力投入ConcurrentModificationException 。 因此,编写依赖于此异常的程序的正确性将是错误的:迭代器的故障快速行为应仅用于检测错误。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值