黑马程序员-2-java-Collection集合类知识串讲(1)-List及Set
2015-05-26 17:06
369 查看
</pre><p></p><p style="text-align:center"><strong><span style="font-family:Simsun; font-size:14px">------- </span><a target=_blank target="_blank" href="http://www.itheima.com/" style="font-family:Simsun; font-size:14px">android培训</a><span style="font-family:Simsun; font-size:14px">、</span><a target=_blank target="_blank" href="http://www.itheima.com/" style="font-family:Simsun; font-size:14px">java培训</a><span style="font-family:Simsun; font-size:14px">、期待与您交流! ----------</span></strong></p><p><strong></strong></p><p><strong>集合</strong></p><p> Collection类接口所定义的集合是单列集合,较之Map类所定义的双列集合,他只有一个类型的可操纵元素。该接口有以下几个常见的声明:</p><p> Collection接口实现了Iterable接口,该接口主要抽象了iterator()方法</p><p> add(e):添加至末尾;</p><p> iterator():生成本对象的迭代器;</p><p> addAll(c):添加所有至调用对象的末尾;</p><p> remove(Object):从调用它的对象中,移除对应单个实例; </p><p> retainAll():取交集,存入调用它的一方</p><p> addAll():将参数方的所有元素都添加到调用方</p><p> removeAll():移除调用一方中与参数相同的数据</p><p> containAll():检查调用方是否包含参数中的所有数据,真则反悔true,反之为false</p><p> interator():调用迭代器,迭代器是集合取出元素的方式 </p><p> Interator是一个接口,常用方法:hasNext():集合中是否还有元素;</p><p> next():提取下一个</p><p> remove()移除迭代器指向元素</p><p> 注意:next()每调用一次,就得用hasNext()判断一次,避免异常产生 </p><p> Interator it=a1 . interator():表明interator()函数返回值为Interator接口的一个子类对象,实现了多态。常用的Interator类具有局限性,并不提供添加操作。所以,我们对于复杂操作的迭代器使用根据需求,可选取ListIterator类来完成操作。较之Iterator类,ListIterator类多出了前驱判定、返回、回溯操作,以及对数据的增、改操作。但同时,ListIterator类也只能由List类调用。</p><p> iterator方法是在接口类Iterable之中的,这是在jdk1.5后,java出现的新特性。提高程序的扩展性。而且,我们有了新的简化使用方法,输出集合类的所有元素: </p><p></p><pre name="code" class="java"> for(String s : a) { System.out.println(s); }
当然,简化都会导致局限性,这种用法的局限性就是,该方法只能获取元素,而不能对元素进行修改,不能对集合进行操作。这就是他的弊端。这样的用法,必须对元素进行限定(即,如果是集合的话,就不许在上面有声明元素的类型,这样for使用的时候才能有明确的元素类型,共它操作),必须得有便利目标。所以,对数组的便利,还是使用未简化的传统用法比较好。
Collection中为抽象方法,具体实现的列入ArrayList类,ArrayList类继承了AbstractList类,而抽象类AbstractList抽象类实现了对应的interator()接口调用函数。
常用的接口一般使用for循环来写,为的是在循环结束后释放已经使用过的对象资源。
ArrayList 继承自AbstractList类,而AbstractList类实现了Collection接口,AbstractList类提供了interator()迭代器方法,从Collection接口中继承了抽象的增、删、改、查方法。当然,Collection类中只是初步的定义了增和删两个操作,而没有涉及到改、查,对应改、查方法的定义与部分实现,是有AbstractList来完成的,并在他的两个子类ArrayList和LinkedList当中完全实现的。
对应的关系由父到子:Collection->AbstractList->ArrayList
图1.Java中集合类的关系图
List:元素是有序的,因为该集合有索引,元素可以重复。
List类中的特有方法:
set(index , element):改变指定位置的元素为element值
add(index , element):添加元素到指定位置,位于该位置的元素依次向右移动一位,同时,该方法也是List类的独有方法。;
listIterator():生成List类独有的迭代器。常用的Interator类具有局限性,并不提供添加操作。所以,我们对于复杂操作的迭代器使用根据需求,可选取ListIterator类来完成操作。
subList(fron, end):List的独有方法,可以类比subString()方法;
remove(index):移除制定位置的元素;
根据底层数据存储结构的不同,我们把表分为了顺序表、链表。对应的,我们的类也分为了ArrayList类与LinkedList类。而根据底层的数据存储结构的不同,这两个类对于增、删、改、查的速度也是不同的。ArrayList类,查询速度快,增删速度慢;LinkedList类,查询速度慢,增删速度快。
对于这两种类的使用,我们可以根据下表来选择:
表1 ArrayList与LinkedList使用条件简表
情况 | 主要查询 | 主要增删 |
次要查询 | ArrayList | 优先ArrayList可考虑LinkedList |
次要增删 | ArrayList | LinkedList |
对应Vector类下的特有方法,addElement、elementAt、removeElement、insertElement、firstElement、lastElement、removeAllElement、setElement、removeElementAt。
其中,最重要的是elements()方法,此方法返回一个此向量组的枚举类,即Enumeration类,此类有两个类独有方法,hasMoreElements()和nextElement(),其作用可以类比迭代器Interator类和ListIterator类在集合框架中的作用
ArrayList类的延长,采用的是50%延长的特点;Vector则是采用的100%,更加的浪费空间。
我们来说一下LinkedList类的不同,他比ArrayList类多出了addFirst、addLast、removeFirst、removeLast、peekFirst、peekLast、offerFirst、offerLast、getFirst、getLast、pollFirst、pollLast,应该善加使用LinkedList类的头尾操作方法,这是最能体现链表特点的应用。其中offer系列、peek系列和poll系列的方法分别是add系列、get系列与remove系列的升级版,避免了NoSuchElementException异常。
需要提的是,对于有限定条件的顺序表结构,即队列和栈,我们分别有对应的方法:
队列:offer、peek、poll;
栈:pop、push。
注意:在使用equals()方法比较自定义类,或复杂的类对象的时候,equals方法只比较对象地址值。可以用 instanceof 来判断类型是否是想要的类型。List方法判断元素是否相同,依据的是元素自身的equals方法。同理,remove(e)、indexOf(e)等这类的包含类型对象的方法,都是调用equals方法来判定索取对象是否是想要的对象的。因此,自定义类的话,如果需要,还是有必要重载equals方法的。
Set:元素是无序的,即存取无序,元素不可重复。
该类为接口。equals()是元素对象的equals函数,在未覆盖的情况下,比较的是元素对象的地址值。所以,两个HashSet类对象中存储的数据,哈希值是可以相同的,但是如果是不同的元素,其地址值是不一样的。
Set类的方法和Collection类是一致的,也就是说Set类没有set、get系列方法。这样就使得我们想要取出元素,就只能采用迭代器这种方法了。
HashSet类,底层数据结构存储方式为哈希表存储,该存储的特点是没有顺序,存储的时候根据给定的哈希算法,利用公式与法则来计算存储位置。并得出对处对象的hash值。
哈希值得计算使用的是hashCode()函数生成。
如果发生哈希值一样的情形,那么同哈希值的元素,在存储的时候会在同哈希值上发生罗列,即不通地址值对应同哈希值。该值可以通过。这点可以参考数据结构中,对于哈希表重叠问题的处理方法。同时,需要注意的是,这种叠加使用的是栈。如何验证HashSet类的无序性,我们可以通过先添加元素,再用迭代器依次输出,来验证顺序性。迭代器的next(),取的是地址顺序。
由此可推广,为什么Set是不能存储相同值的数据。对于HashSet来说,他的元素唯一性是由次HashSet类对象所添加的元素类的hashCode和元素equals两个方法类决定的。所以,一般都要覆写这两个方法。
如果对HashSet类对象做删除、查找操作,则先判断对应要查找的元素的哈希值,即使用hashCode方法,然后在比较内容是否相等,即调用equals方法。像这样的情况,犹如:对于contains()方法的调用,最先先比较哈希值,即调用hsahCode方法,然后再调用equals方法。同理,涉及元素比对的都是这样。
TreeSet类,可以对Set集合中的元素进行排序,默认的是自然排序,即ASCII表排序。而对于排序,我们一定涉及比较,当我们比较的对象为自定义类时,我们就需要实现Comparable接口,并覆写compareTo()方法。如此,才可以比较而不出现异常。这里有一点,当主条件相同时,比较次要条件是否相同。
class Personimplements Comparable { private String name; private int age; public int compareTo (Object obj) { if (!(instanceof Person)) throw newRuntimeException("非人"); Person p=(Person)obj; if (this.age>p.age) return 1; if (this.age==p.age) { returnthis.name.compareTo(p.name); } return -1; } }
对于TreeSet类,一次一比显得比较麻烦,因此,该类的数据结构并不是线性的,而是一个LDR二叉树。建立的小根堆为ASC排序,大根堆为DESC排序。根据此二叉树的特性,如果保持原有序列,则,对应元素类中的compareTo方法的返回值取1即可,建立只有右子树的二叉树。如果想要倒序,则,对应元素类中的compareTo方法的返回值取-1即可,建立只有左子树的二叉树。这是元素自身具备比较性时,可以使用的方法。
当然,TreeSet类不止具有这一种比较方法。当元素自身不具有比较性,或者是比较性是已经定义好的不可更改,且并不是我们需要的时,我们采用的方法是让集合,即TreeSet类,本身具有比较性。这样,我们需要做的就是在该类对象初始化时,就直接为期制定比较方式。这样,我们需要参与的就是类的构造函数了。
TreeSet(Comparator<?
super E> comparator)
构造一个新的空TreeSet,它根据指定比较器进行排序。
这就是我们需要的构造函数。
Comparetor接口有两个方法声明:compare(o1, o2)和equals(obj)
compare(o1, o2):用于比较两个参数o1与o2是否相同;
equals(obj):用于判断对象obj是否等于次Cpmparator类对象。
需要强调的是,如果两种特性同时具备,以容器自身所携带的Comparator比较器为主,来排列顺序。
总的来说,TreeSet类的顺序,是由Comparator比较器和元素对象的compareTo方法来决定的。前者为主,后者为辅。
class Comp implementsComparator { public int compare (Object o1,Object o2) { if (!(o1 instanceof Person&& o2 instanceof Person)) { throw newRuntimeException("人名错误"); } Person p1=(Person)o1; Person p2=(Person)o2; /* 因为比较器使用时,是使o1在前o2在后的 所以我们想要和String自带比较方法相反 就得用p2来调用compareTo方法了 */ return p2.name.compareTo(p1.name); /*下面是一种复杂的写法, 当然我们也可以向上面的那样,简写 if(p1.name.compareTo(p2.name)==1) return -1; if(p1.name.compareTo(p2.name)==-1) return 1; return 0; */ } } /* 调用时如下: TreeSet ts = newTreeSet (new Comp()); */
------- android培训、java培训、期待与您交流!
----------
相关文章推荐
- 黑马程序员-5-java-Collection集合类知识串讲(4)-集合框架工具类Utilities
- 黑马程序员-3-java-Collection集合类知识串讲(2)-泛型及其应用规则
- 黑马程序员_Java第14天知识总结_集合类(集合框架)_Collection_迭代器_List_Set_HashSet
- 黑马程序员-4-java-Collection集合类知识串讲(3)-Map及其子类
- 黑马程序员_java_集合框架_Collection_List_Set_Map_泛型
- 黑马程序员——Java基础——集合类、Collection、List体系、集合框架LinkedList操作等
- 黑马程序员_JAVA学习日记_JAVA中API:集合框架1(Collection,List,Set及其子类和迭代器的应用)
- 黑马程序员_java_集合框架_Collection_List_Set_泛型
- 黑马程序员——Java学习之Collection、List、Set
- 黑马程序员——Java基础---集合(一)---Collection、set、list
- 黑马程序员_java基础_集合(Collection和List、Set)
- 黑马程序员_毕向东JAVA基础_集合(2)Collection&&List&&Set&&泛型
- 黑马程序员_java集合(1) Collection & List & Set & Map
- 黑马程序员--11集合类的学习List&Hash&Array)Set&泛型
- java 集合架构--[Collection] [List] [Set] [Map] [集合工具类]
- Java基本概念:集合类 List/Set/Map 的区别和联系
- 黑马程序员-----Java基础-----Collection-list
- Java--集合类Collection--List和Set
- Java中的Map List Set等集合类
- Java中collection set list map