您的位置:首页 > 职场人生

黑马程序员_集合框架

2014-05-29 23:14 155 查看
------------- android培训、java培训、java博客、java学习型技术博客、期待与您交流! -------------

集合

介绍Java中是用面向对象语言对事物进行描述,所以为方便对多个对象操作,就对对象进行存储,通过这个存储对象对其中元素进行操作,而集合是存储对象的一种方式。数组与集合   数组一建立,存储类型就明确,长度也固定,       集合一建立,现为泛型机制,长度可变化,数据多了用数组存,对象多了用集合存,数组与集合里面存储的都是地址。Collection<E>接口 |--List,集合中元素有序,因为元素都有索引即带有脚标,且元素可以重复。 |--Set,集合中元素无序,不可以存储重复元素,必须保证元素唯一性。方法1、添加 boolean add(E e) 返回值是布尔类型,不同集合类型有可能发生异常 boolean addAll(Collection c)2、判断 boolean contains(Object o) boolean isEmpty()3、删除 boolean remove(Object o)  删除元素有两个步骤,先判断有无、后删除; boolean removeAll(Collection c) boolean retainAll(Collection c) 相当于取交集 void clear()  清空集合4、读取 int size()   集合元素个数 Iterator<E> iterator()  返回该集合内部迭代器,用于集合内部元素读取|-- boolean hasNext() 若仍有元素可迭代,返回true|-- E next()  返回迭代的下一个元素,注调用一次该方法就会返回下一元素|-- remove() 注意,关于判断和删除方法,有以下几种情况 List  自动调用元素的equals方法,对元素是否相同进行判断 HashSet  先调用元素的hashCode方法,如相同,在调用equals方法 TreeSet  根据元素compareTo判断,若集合中有比较器,则按比较器中方法进行判断List<E>接口 |--ArrayList:1.2版本。底层数据结构是数组,线程不同步,查询修改元素的速度非常快。 |--Vector:1.0版本,底层的数据结构是数组,线程同步,Vector无论查询和增删都慢 |--LinkedList:1.2版本,底层的数据结构是链表,线程不同步,增删元素的速度非常快方法:凡是可以操作脚标的方法都是该集合特有方法1、添加   void add(int index,E e) 指定脚标位插入某元素2、删除 E remove(int index)  删除指定脚标位元素3、修改 E set(int index,E elment) 替换指定脚标位元素4、获取 E get(int index) 获取指定脚标位元素 List<E> subList(int fromIndex,int toIndex) 获取指定脚标位的子集合 ListIterator<E> listIterator()  返回此列表元素的列表迭代器(特有)|--void add(E e) 将指定元素插入列表|--void set(E e) 用指定元素替换next或previous返回的元素比一般迭代器多了添加和修改两个操作,注意:如果在Iterator迭代时,不可以加入集合操作方法,否则发生:ConcurrentModifationException 并发操作异常,若一定要有操作,则选用List集合中特有迭代器。ArrayList 与 Vector 区别1、前者为1.2版本,后者为1.0版本2、前者线程不同步,后者线程同步,所以前者效率相对较高3、两者内部数据数组大小为10,若所需存储元素超过默认大小,  前者每次增加50%,后者增100%,4、开发使用,前者基本替代了后者5、Vector取出元素用枚举 EnumerationhasMoreElements() nextElement() 另:该接口在IO包中的SequenceInputStream构造方法中有用到ArrayList 和 LinkedList 区别1、前者叫数组列表,后者叫链接列表,都为1.2版本2、前者底层数据结构式数组,后者为链表3、由于数据结构不同,前者查询和修改元素效率相对较高,  后者增加和删除元素效率相对较高。LinkedList 特有方法1、将指定元素添加到列表的开头或结尾 void addFirst(E e) void addLast(E e)2、获取开头或结尾元素,但不删除 E getFirst(); E getLast();3、获取开头或结尾元素,并删除,注意返回是元素 E removeFirst() E removeLast()另:若此列表为空,get/remove方法都会出现NoSuchElementException   JDK1.6版本用offer、peek、poll分别替代了上述三个方法,   若此列表为空,则返回null。Set<E>接口 |--HashSet 底层数据结构是哈希表,保证元素唯一性是先调用hashCode方法,若相等,在看equals方法;注意用该集合存储元素,元素一般需要复写以上两种方法。 |--TreeSet 底层数据结构为二叉树,保证元素唯一性是通过元素实现Compareable或Set自带比较器它们都是根据其内部方法返回值int的正负或零进行判断排序的;1、Comparable  此接口对实现它的类的每个对象进行强制排序,此排序也叫做自然排序,步骤:1、定义类实现Comparable<T>2、复写 int compareTo(T o) 方法 3、注意复写方法时要根据需要进行复写,通常有主要判断条件还有次要判断条件 4、诸如Integer、String类都有实现该接口,有时可巧妙借用其方法2、Comparator  强行对某个对象 collection 进行整体排序的比较函数,可将其传递给集合构造方法   步骤:1、定义类实现Comparator<T> 2、复写 int compare(T o1,T o2)  3、new该类对象并将该对象传递给TreeSet集合构造函数 4、当然也可以写成内部类格式两者都有的情况下,按照比较器方法进行排序。Map<K,V>接口将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。 通俗来讲,存储的是键值对,需要一对一对进行存储,必须保证键和值的唯一性。和Set很像,Set底层就是使用了Map集合。方法1、添加 V put(K key,V value) 注意返回的是该键原来值,若之前无该键,则返回null void putAll(Map<> m)2、删除 void clear() V remove(Object key) 若存在一个键的映射关系,则将其从映射中移除3、判断 boolean containsKey(Object key) boolean containsValue(Object value) boolean isEmpty()4、获取V get(Object key) 返回指定键所映射的值int size()  返回此映射中的键值映射关系数Collection<V> values() 返回此映射中的所有值-------------------------------------------------Set<K> keySet() 返回此映射中所包含键的Set视图Set<Map.entry<K,V>> entrySet() 返回...映射关系的Set视图entry其实就是Map接口内部的public static 接口  Map实现类TreeMap 底层是二叉树结构的,线程不同步,可以用于给Map集合中的键进行排序HashMap 基于哈希表的Map结构,底层是哈希表数据结构,允许存入Null键和Null值,该集合不同步,JDK1.2,效率高Hashtable 底层是哈希表数据结构,不可以存入Null键Null值,该集合是线层同步的,JDK1.0,效率低,后被HashMap取代。(注意两者区别描述)泛型概述泛型是JDK1.5版本新特性,其本质是参数化类型,即所操作的数据类型被指定为一个参数,这种参数可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。由来无泛型之前,是通过类型Object的引用来实现参数的任意化,但任意化的缺点是需要做强制类型转换,并且对于出现错误的情况编译器检查不到,在运行时候就会出现异常,泛型的出现省去了强制转换,且错误会显示在编译时期。(有点类似多态中父类调用子类特有方法情形)e.g:假设ArrayList集合先添加了若干String类对象,迭代器取出元素并获取长度,因为迭代器取出的元素是Object类型,所以需要强制转为String类型在操作,但是集合是可以存储任何对象的,假若集合加入Integer类型对象,编译时期是可通过的,但是运行就会出现异常,该为泛型示例,这样问题就会出现在编译时期,且省去了强转操作;ArrayList<String> al = new ArrayList<String>();Iterator<String> it = al.iterator();while(it.hasNext()){String s = it.next();s.length();}其实,泛型借助了数组思想,数组一建立就给该数组对象明确是存储什么类型数据的数组,同理,集合一建立,借助泛型机制明确它是存储什么类型的集合容器。一般应用通常情况下,在集合框架中很常见,只要见到 <> 号就需要定义泛型。特殊应用(自定义)泛型类自定义类后面加上泛型,称为泛型类,该类对象泛型一旦确定,在整个对象中有效。集合中泛型一般定义在类上,如 ArrayList<E>泛型方法泛型方法跟是否泛型类无关,定义泛型方法只需要将泛型参数类表加在返回值类型前面,这样该方法的拓展性得到了提高。另,静态方法不能访问类泛型,若要泛型,只能定义为静态方法泛型。泛型接口如 Comparator<T> Collection<E> ;另定义类实现接口的时候可明确类型,也可以继续用<T>。注意:泛型的出现大大提高了拓展性,但是操作的方法却只能是指定泛型内的共性方法。如:定义<?>则只能操作Object类方法,若<String>则能操作String类方法,<?>与<T>的区别都是代表任意类型1、 <T>可以接受对象并调用方法 T t = new T(); 2、写泛型限定的时候,需用?,如 <? extends Collection>;泛型限定即标明传入参数为某一个类型范围的;1、向上限定;<? extends E>   可以接受E类型或者E的子类型2、向下限定:<? super E>     可以接受E类型或者E的父类型集合工具类Collections专门操作集合对象的工具类,它的出现为集合操作提供了更多功能,内部方法都为静态方法1、对List集合中元素进行排序按照List集合中元素的默认排序方式进行排序  static <T extends Comparable<? super T>> void sort(List<T> list)按照传递的比较器排序方式进行排序 static <T> void sort(List<T> list,Comparator<? super T>)2、获取集合中最大元素或最小元素根据元素自然顺序,获取最大或最小元素static <Comparable<? super T>> T max(Collection<? extends T> coll)根据指定比较器产生的顺序,返回最大或最小元素static max(Collection<? extends T> coll,Comparator<? super T> comp)3、使用二分查找法搜索List,获得指定脚标自然顺序下的脚标static <T> int binarySearch(List<? exxtends Comparable> list,T key)指定比较器下的脚标static <T> int binarySearch(List<? extends T> list,T key,Comparator<? super T> c)4、反转,或对指定位置处List元素反转static void reverse(List<?> list) static void swap(List<?> list,int i,int j)5、逆转集合中的原有排序返回一个比较器,它强行逆转实现了Comparable的对象的自然排序static <T> Comparator<T>  reverseOrder()e.g:  Arrays.sort(a, Collections.reverseOrder());返回一个比较器,它强行逆转指定比较器的顺序static <T> Comparator<T> reverseOrder(Comparator<T> comp)6、用指定元素替换列表中的所有元素satic <T> void fill(List<? super T> list,T obj)7、随机打乱列表List中元素顺序static void shuffle(List<?> list)8、返回指定集合支持的同步集合static <T> Collection<T> synchronizedCollection(Collection<T> c)... synchronizedList (...)... synchronizedMap (...)... synchronizedSet (...)Arrays专门操作数组对象的工具类,内部方法都为静态方法1、数组转集合(T... 为JDK1.5新特性,见后文)static <T> List<T> asList(T... a)  返回的是固定长度的列表,不可对列表进行增删元素操作,但可调用集合其它方法。2、static int binarySearch(数组) 二分查找3、static void sort(数组) 排序4、static String toString(数组)  数组变字符串另:集合变数组方法Collection中 toArray(T[] a)1、指定类型的数组到底要定义多长呢?当指定类型的数组长度小于了集合的size,那么该方法内部会创建一个新的数组,长度为集合的size当指定类型的数组长度大于了集合的size,那么就直接使用传递来的数组,不够的返回null所以创建一个刚刚好的数组最优。[al.size()].2、为什么要将集合变成数组为了限定对元素的操作,不需要进行增删拓展forEach语句, 可遍历 数组和实现了迭代器的容器for(数据类型 变量名:被遍历的集合(Collection)或数组){ ....  }另:对集合进行遍历,只能获取集合中元素,但是不能对集合进行其它操作,迭代器除了遍历,还可以进行remove集合中元素的动作,如果使用listIterator还可以在遍历过程中对集合进行增删改查的动作。传统for循环和高级for循环区别高级for有一个局限性,必须有被遍历的目标建议在遍历数组的时候,还是希望使用传统for,因为传统for可以定义脚标可变参数   数组参数的简写形式 格式:(数据类型... a)不用每一次都手动的建立数组对象,只要将要操作的元素作为参数传递即可,隐式将这些参数封装成了数组可变参数一定要定义在参数列表最后面静态导入   e.g import static java.util.arrays.*;导入某个类中的静态成员,这样调用静态成员可省略类名了。需注意的是:类似于当类名重名时,需要指定具体的包名所以当方法重名时,需要指定所属的对象或者类。共性方法,其前面省略了this ,所以需注意。------------- android培训、java培训、java博客、java学习型技术博客、期待与您交流! -------------
详情请查看:http://edu.csdn.net/heima/

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息