黑马程序员_Java基础_集合框架

来源:互联网 发布:淘宝女式拖鞋 编辑:程序博客网 时间:2024/03/28 16:33

---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------

一、总体介绍

在Java中集合框架中有基础的两大派系:Collection接口与Map接口,Collection是单值存放的最大接口,可以向其中保存多个单值数据,此接口在开发中很少使用,一般情况下会使用其子接口List,Set,而Map接口则是存放键值对的集合类。常用类的总体继承关系如下:

Collection  提供了集合操作的基本方法

| List    对集合操作的方法做了大量的扩充 【可以存放重复元素】 

| ArrayList   非线程安全,查询、修改速度非常快,添加、删除速度稍慢

| LinkedList  非线程安全,添加、删除速度非常快,查询、修改速度稍慢

| Vector      线程安全,效率略慢,但是很容易得到迭代集合早期的接口:Enumeration,通过v.elements();方法获取

| Set    没有对集合方法做扩充【不可以存放重复元素】

| HashSet   该类中不允许存放重复的元素,其比较元素是否重复是调用被添加对象的hashCode()方法,如果hashCode()方法的返回值相同,就会调用对象的equals方法

| TreeSet 本类中判断是否是重复元素的条件是通过判断Comparable接口的compareTo()方法,或者是Comparator接口的cmpare()方法。返回0则表示同一元素

Map        

| HashMap  通过判断hashCode() equals()方法判断key值是否重复,如果key值重复,则后添加的方法就会覆盖最先添加的方法。允许key为空

| HashTable 与上述方法一致,key值与value值都不允许为空。

| TreeMap TreeMap与TreeSet一样都要求对象实现Comparable接口或者手动创建具有排序功能的TreeMap(也就是new TreeMap(new Comparator(){public int compateTo()}));



二、对于List操作案例
ArrayList:去除ArrayList中的重复元素

package com.itheima.collection;import java.util.ArrayList;import java.util.List;/** * ArryList练习1:去除ArrayList中的重复元素 * */public class CollectionDemo {public static void main(String[] args) {List<String> list = new ArrayList<String>();for(int i = 0 ;i <10; i++){list.add("元素   "+ i%2);}list = removeRepeat(list);for (String e : list) {System.out.println(e);}}/** * 去掉List中重复数据 * @param list * @return */public static <T> List<T> removeRepeat(List<T> list){if(list == null){throw new NullPointerException("list cannot empty.");}List<T> newList = new ArrayList<T>();for (T t : list) {//如果新的List集合中包含了该元素,结束本次循环继续下次循环。if(newList.contains(t)){continue;}//如果新的List集合中没有该元素,直接把该元素添加到新的集合之中。newList.add(t);}return newList;}}

当然,上述操作只是最简单的练习,List中contains(obj)方法在实现过程中需要调用对象obj的equals(Object obj)方法,如果没有在子类中重写Object的boolean equals(Object obj)方法,那么就会直接使用Object类的equals()方法,对于自定义对象,如果想要判断List中是否包含(contans(obj))则需要重写equals方法,否则,结果可能会与预想的不太一样。


LinkedList练习:模拟栈与队列的数据结构

package com.itheima.collection;import java.util.LinkedList;/** * LinkedList练习:模拟一个堆栈与队列 * 栈:先进后出 * 队列:先进先出 */public class CollectionDemo2 {public static void main(String[] args) {/*MyQueue<String> mQueue = new MyQueue<String>();mQueue.add("ccc");mQueue.add("aaa");mQueue.add("bbb");while(!mQueue.isEmpty()){System.out.println(mQueue.remove());}*/MyStack<String> mStack = new MyStack<String>();mStack.add("111");mStack.add("222");mStack.add("333");while(!mStack.isEmpty()){System.out.println(mStack.remove());}}}/** * 自定义队列的实现,采用LinkedList * 特点:先进先出 */class MyQueue<T>{private LinkedList<T> mQueue;public MyQueue(){mQueue = new LinkedList<T>();}public void add(T t){mQueue.addFirst(t);}public T remove(){if(mQueue == null || mQueue.isEmpty()){return null;}return mQueue.removeLast();}public boolean isEmpty(){if(mQueue == null){return true;}return mQueue.isEmpty();}}/** * 模拟实现栈的结构  * @param <T> */class MyStack<T>{private LinkedList<T> mStack ;public MyStack(){mStack = new LinkedList<T>();}public void add(T t){mStack.addFirst(t);}public T remove(){if(mStack.isEmpty()){return null;}return mStack.removeFirst();}//判断是否为栈中是否存在元素public boolean isEmpty(){return mStack.isEmpty();}}
三、Set操作

在Set接口中有两个比较重要的实现类:HashSet与TreeSet

package com.itheima.collection;import java.util.Comparator;import java.util.HashSet;import java.util.Set;import java.util.TreeSet;/** * Set操作 */public class CollectionDemo3 {public static void main(String[] args) {Set<Person> set = new HashSet<Person>();set.add(new Person("zhansan", "----"));set.add(new Person("zhansan", "----"));set.add(new Person("zhansan", "----"));//在没有重写hashCode与equals方法之前这里输出的set的数据数量为3,因为hashSet在判断两个对象是否相等时,是首先根据hashCode()的返回值来判断//如果hashCode()方法的返回痣相同,则会继续调用equals()方法。System.out.println(set.size());////////////////TreeSet操作//Set<Person> mTreeSet = new TreeSet<Person>();//这里添加元素异常,原因是Person类不能强制转换为Comparable//所以要想添加元素成功,可以实现Comparable接口//--//mTreeSet.add(new Person("111", "ewe"));//如果想要在TreeSet中添加没有实现Comparable接口的对象?//可以手动创建一个具有排序功能的TreeSetSet<Person> mSet = new TreeSet<Person>(new Comparator<Person>() {@Overridepublic int compare(Person o1, Person o2) {int resuleCode = o1.getAddr().compareTo(o2.getAddr());if(resuleCode == 0){return o1.getName().compareTo(o2.getName());}return resuleCode;}});//尽管Person没有实现Comparable接口,也可以实现元素向TreeSet中的添加。mSet.add(new Person("23", "3333"));}}class Person/*TreeSet支持,实现Comparable接口之后,在添加元素就不再报错 implements Comparable<Person>*/{private String name;private String addr;public Person(String name,String addr) {this.name = name;this.addr = addr;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAddr() {return addr;}public void setAddr(String addr) {this.addr = addr;}/*@Overridepublic int compareTo(Person p) {int resultCode = this.getName().compareTo(p.getName());if(resultCode == 0){return this.addr.compareTo(p.getAddr());}return resultCode;}*/@Overridepublic int hashCode() {System.out.println("hashCode() execute.");final int prime = 31;int result = 1;result = prime * result + ((addr == null) ? 0 : addr.hashCode());result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic boolean equals(Object obj) {System.out.println("equals() execute.");if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Person other = (Person) obj;if (addr == null) {if (other.addr != null)return false;} else if (!addr.equals(other.addr))return false;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;return true;}}
四、Map操作

对于Map接口,最长用的类就是HashMap,其次是TreeMap,还要知道一个与HashMap功能完全一样的类就是HashTable【这样说可能不太合理】

关于HashMap与Hashtable,底层都是使用了hash算法,HashMap是异步的,HashTable是同步的,所以HashMap的效率要比HashTable的效率要高,还有就是HashMap允许存放null的key与value,而HashTable的key与value都不能为null,否则,会出现空指针异常。

1.HashMap的基本操作--map的数据迭代,不能直接使用Iterator。

package com.itheima.collection;import java.util.HashMap;import java.util.Map;public class CollectionDemo4 {public static void main(String[] args) {Map<String,String> map = new HashMap<String, String>();for(int i = 0;i<10;i++){//添加元素map.put("key"+i, "value"+i);}//使用加强for循环输出Map中的元素,也可以使用map.entrySet();得到Map.Entry<String,String>的getKey(),getValue()//方法获取key 与valuefor (String key : map.keySet()) {System.out.println(map.get(key));}//注意hashMap中,如果key值相同,后添加的元素的value值会覆盖前面的元素,比较key值是否相同,hashMap//会首先调用被操作对象的hashCode()方法,如果hashCode()方法的返回值相同的话,会继续调用被操作对象//的equals()方法,如果此时equals()方法的返回值为true,则hashMap就会认为这 是不同的key//map的其他操作,可以多加练习,慢慢熟练。//HashTable与HashMap基本操作一致的。最后,关于TreeMap的使用,自我感觉很少使用,但是需要注意一点,TreeMap添加元素时,如果元素对象没有实现  //Comparable接口的话,需要建立具有比较功能的TreeMap对象才能进行元素的添加。不管是TreeMap,TreeSet都是会对元素进行二叉树排序的,第一个添加的元素作为根节点///,而后添加的元素,如果比根节点的元素大,就会插入到根节点的右侧,否则左侧。。}}
五、集合框架的工具类

在集合框架中有两个非常常用的工具类Collections与Arrays,关于这两个工具类的使用,只利用很常用的两个方法来说明下:Collections.sort(List,Comparetor)排序,Arrays.asList(T...t) ;其他方法,查看JavaAPI文档可以慢慢练习。

六、总结

1.List扩展了Collection接口,里面允许存放重复数据,List接口常用的子类有ArrayList、LinkedList、Vector在开发中ArrayList的性能要比Vector的性能高,因为ArrayList是异步的,Vector是同步的。

2.Set接口与Collection接口是一致的,里面不允许存放重数据,判断数据是否重复,需要调用对象的hashCode()与equals()方法,常用的子类有HashSet,TreeSet,前者是散列存放,后者依靠Comparable接口排序后有序存放。注意:set集合可以求出两个即可得差集与交集

3.集合的输出需要使用到Iterator接口完成,Iterator接口数据迭代输出接口

4.在jdk1.5之后可以使用加强for循环进行输出

5.Enumeration接口是早期的迭代输出接口,现在很少使用,类集中Vector可以使用其迭代输出

6.ListIterator接口可以迭代list元素,并且可以使用里面的增、删方法修改list

7.Map接口是存放一组key--value的数据的容器,其中每个实例都是一个Map.Entry,Map常用子类有HashMap,TreeMap,HashTable

8.集合框架中有两个常用的非常重要的工具类,Collections与Arrays,里面封装了大量的集合操作类,例如排序等。


---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------

详细请查看:http://edu.csdn.net


0 0
原创粉丝点击