黑马程序员_java学习笔记 8.集合框架

来源:互联网 发布:女装原单淘宝店 编辑:程序博客网 时间:2024/05/18 17:45

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


集合框架





一、什么是集合


1、集合框架
为什么出现集合类?
对象是对数据的封装,而集合是对对象的封装。编程中除了对单个象的操作外,
常常还需要对多个对象进行统一操作,这时就需用一个容器将这些对象存储起来,这样的容器就是集合。
其实,String类也是一个特殊的容器,它存储的是char类型的元素。集合的共性操作就是CRUD。集合的应用比数组更广泛。

集合与数组的区别
他们都是容器,都可以存储对象,他们的区别是:数组的长度是固定的,而集合的长度的可变的;
数组既能存储基本数据类型也能存储引用数据类型,而集合只能存储引用数据类型,
如果给集合添加基本数据类型的元素,这些基本数据类型会自动装箱成对应的引用数据类型;数组存储的元素都是同一类型,而集合可以存储不同类型的元素。

集合的特点: 集合只用于存储对象,它的长度可变,能够存储不同类型的对象。
集合框架为什么有这么多的容器?
因为每一个容器对数据的存储方式都有不同,这个存储方式称之为:数据结构。

二、集合的构成

List接口:

List有序(元素存入集合的顺序和取出的顺序一致),元素都有索引。元素可以重复。

    |--ArrayList底层的数据结构是数组,线程不同步,ArrayList替代了Vector,查询元素的速度非常快。

    |--LinkedList底层的数据结构是链表,线程不同步,增删元素的速度非常快。

    |--Vector底层的数据结构就是数组,线程同步的,Vector无论查询和增删都巨慢。


Set接口

Set接口中的方法和Collection中方法一致的。Set接口取出方式只有一种,迭代器

  |--HashSet底层数据结构是哈希表,线程是不同步的无序,高效;

      |--LinkedHashSet有序,hashset的子类。

  |--TreeSet对Set集合中的元素的进行指定顺序的排序。不同步。TreeSet底层的数据结构就是二叉树。


Map集合:

Collection一次存一个元素;Map一次存一对元素,存储一堆有映射关系的键与值

|--Hashtable底层是哈希表数据结构,是线程同步的。不可以存储null键,null值。

|--HashMap底层是哈希表数据结构,是线程不同步的。可以存储null键,null值。替代了Hashtable.

|--TreeMap底层是二叉树结构,可以对map集合中的键进行指定顺序的排序。


1、 遍历集合有几种方法?

Iterator(迭代器)
集合中的的元素取出动作,不足以用一个函数来描述(取出前要先判断有没有),同时不同的存储结构,其取出的方式也不同,
所以定义了一个接口Iterator专门用来实现其取出操作。因为要访问集合内部的元素,所以迭代器的实现放在了具体集合的内部。

第一种:通过迭代器Iterator

Iterator it =  coll.iterator();

while(it.hasNext())

       System.out.println(it.next());

for(Iterator it=coll.iterator();it.hasNext();)

       System.out.println(it.next());

第二种:高级for循环

for(Object obj:coll)

       obj = coll.next();

第三种(只针对list)对list,size()进行遍历:

for(int i= 0;i<coll.size();i++)

       list.get(i);

遍历举例:

[java] view plaincopy
  1. import java.util.*;  
  2. import org.junit.Test;  
  3.   
  4. public class CollectionTest {  
  5.     /* 单列集合的遍历 */  
  6.     // List集合的遍历  
  7.     // 传统方式遍历  
  8.     public void traverseList1()  
  9.     {  
  10.         List<String> list = new ArrayList<String>();  
  11.         list.add("a");  
  12.         list.add("b");  
  13.         list.add("c");  
  14.         list.add("d");   
  15.         Iterator<String> iterator = list.iterator();// 遍历集合获得迭代器  
  16.         while (iterator.hasNext()){  
  17.             String value = iterator.next();  
  18.             System.out.print(value + " ");  
  19.         }  
  20.     }  
  21.     public void traverseList2()  
  22.     {  
  23.         List<String> list = new ArrayList<String>();  
  24.         list.add("a");  
  25.         list.add("b");  
  26.         list.add("c");  
  27.         list.add("d");  
  28.         for (String value : list)// 使用java5新特性,增强for循环遍历  
  29.         {  
  30.             System.out.print(value + " ");  
  31.         }  
  32.     }  
  33.     // Set集合的遍历  
  34.     public void traverseSet1()// 方式一,使用传统方式  
  35.     {  
  36.         Set<String> set = new HashSet<String>();  
  37.         set.add("a");  
  38.         set.add("b");  
  39.         set.add("c");  
  40.         set.add("d");         
  41.         Iterator<String> iterator = set.iterator();// 获得迭代器  
  42.         while (iterator.hasNext()) {  
  43.             String value = iterator.next();  
  44.             System.out.print(value + " ");  
  45.         }  
  46.     }  
  47.     public void traverseSet2()// 方式二,使用增强for循环方式遍历  
  48.     {  
  49.         Set<String> set = new HashSet<String>();  
  50.         set.add("a");  
  51.         set.add("b");  
  52.         set.add("c");  
  53.         set.add("d");  
  54.         for (String value : set) {  
  55.             System.out.print(value + " ");  
  56.         }  
  57.     }  
  58.     /* 双列集合 */  
  59.     public void traverseMap1()// 方式一,使用传统方式遍历  
  60.     {  
  61.         Map<String, String> map = new HashMap<String, String>();  
  62.         map.put("a""aaa");  
  63.         map.put("b""bbb");  
  64.         map.put("c""ccc");  
  65.         map.put("d""ddd");      
  66.         Set<String> set = map.keySet();  
  67.         Iterator<String> iterator = set.iterator();// 获得迭代器  
  68.         while (iterator.hasNext()) {  
  69.             String key = iterator.next();  
  70.             String value = map.get(key);  
  71.             System.out.println(key + "=" + value);  
  72.         }  
  73.     }  
  74.     public void traverseMap2() // 方式二,使用传统方式二遍历  
  75.     {  
  76.         Map<String, String> map = new HashMap<String, String>();  
  77.         map.put("a""aaa");  
  78.         map.put("b""bbb");  
  79.         map.put("c""ccc");  
  80.         map.put("d""ddd");      
  81.         Set<Entry<String, String>> setEntry = map.entrySet();  
  82.         Iterator<Entry<String, String>> iterator = setEntry.iterator();  
  83.         while (iterator.hasNext()) // 获得迭代器  
  84.         {  
  85.             Entry<String, String> entry = iterator.next();  
  86.             String key = entry.getKey();  
  87.             String value = entry.getValue();  
  88.             System.out.println(key + "=" + value);  
  89.         }  
  90.     }  
  91.       
  92.     public void traverseMap3() // 方式三,使用增加for循环遍历  
  93.     {  
  94.         Map<String, String> map = new HashMap<String, String>();  
  95.         map.put("a""aaa");  
  96.         map.put("b""bbb");  
  97.         map.put("c""ccc");  
  98.         map.put("d""ddd");          
  99.         for (Entry<String, String> entry : map.entrySet())// 获得迭代器   
  100.         {  
  101.             String key = entry.getKey();  
  102.             String value = entry.getValue();  
  103.             System.out.println(key + "=" + value);  
  104.         }  
  105.     }  
  106.     public void deleteElement()// 迭代过程中删除元素   
  107.     {  
  108.         List<String> list = new ArrayList<String>();  
  109.         list.add("a");  
  110.         list.add("b");  
  111.         list.add("c");  
  112.         list.add("d");    
  113.         Iterator<String> iterator = list.iterator();// 在迭代的过程中删除集合中元素,只能使用迭代器对象删除元素  
  114.         while (iterator.hasNext()) {  
  115.             String value = iterator.next();  
  116.             if (value.equals("d"))  
  117.                 iterator.remove();  
  118.         }  
  119.         for (String value : list) {  
  120.             System.out.print(value + " ");  
  121.         }  
  122.     }  
  123.     public void addElement() // 迭代过程中增加元素  
  124.     {  
  125.         List<String> list = new ArrayList<String>();  
  126.         list.add("a");  
  127.         list.add("b");  
  128.         list.add("c");  
  129.         list.add("d");  
  130.         /* 
  131.          * 集合迭代过程中,添加元素也只能用迭代器对象添加 
  132.          * Iterator类中没有add()方法,ListIterator是Iterator的子类,有add()方法 
  133.          */  
  134.         ListIterator<String> iterator = list.listIterator();  
  135.         while (iterator.hasNext()) {  
  136.             iterator.next();  
  137.             iterator.add("e");  
  138.         }  
  139.         for (String value : list) {  
  140.             System.out.print(value + " ");  
  141.         }  
  142.     }  
  143.     // 增强for循环要注意的问题  
  144.     // 增强for循环只适合访问容器的元素,不能对元素做修改  
  145.     public void testUpdate() // 测试代码  
  146.     {         
  147.         int[] arr = { 12 };  
  148.         for (@SuppressWarnings("unused"int num : arr){  
  149.             num++;  
  150.         }  
  151.         System.out.println(arr[0]);// 1  
  152.         System.out.println(arr[1]);// 2  
  153.     }  
  154. }  

2、List中方法的介绍和LinkedListDemo的特有方法

List中的方法:

增加:add(Element e),addAll()

获得:get(int index)subList(start,end).indexOf(obj)

删除:remove(),removeAll()

修改:set(Object obj,int index)

查询:同伙的

判断:contains(obj),isEmpty()

LinkedListDemo的特有方法

增加:addFirst(),addLast()àofferFirst(),offerLast()。

获得:getFirst(),getLast()àpeekFirst(),peekLast()。

无元素则抛出NosuchElemtnExceptionà返回null

获得并删除:removeFirst(),removeLast()àpollFirst(),pollLast()。

无元素则抛出NosuchElemtnExceptionà返回null

 

2、 使用LinkedList模拟一个堆栈或者队列数据结构。

注意:

1、  目的为以LinkedList为容器,构造队列。

2、  建立其中的元素入队和出队方法。

3、  注意判断队列是否为空的方法,方便取出队列元素。

4、 注意包的导入。

3、一个ArrayList对象aList中存有若干个字符串元素,现欲遍历该ArrayList对象,删除其中所有值为"abc"的字符串元素,请用代码实现(3)。examTest/Test17

使用iterator进行操作

4.说下set集合。具体分析下特点。

特点:无序,不能存储重复元素。

子类:

TreeSet:底层数据结构是二叉树。可以按照指定顺序对元素进行排序,线程不同步。

HashSet:底层数据结构是哈希表。可以通过hashCode和equals方法来判断是否是同一个元素。

5.TreeSet有几种排序方法?分别说明?

两种比较方式

第一种:让元素自身实现Comparable接口,复写compareTo方法

第二种:让集合实现Comparator接口,复写其中的compare方法。并将该类建立对象,作为实际参数传递给TreeSet集合。


Map集合:


★ 把map集合转成set的方法

1,如何取出Map中的元素,遍历map的方式

第一种keySet

Set keySet = map.KeySet();

Iterator it = keySet.iterator();

while(it.hasNext())

{

       Objectkey = it.next();

       Objectvalue = map.get(key);

}

第二种EntrySet

Set<Map.Entry<K,V>> EntrySet =map.EntrySet();

Iterator<Map.Entry<K,V>> it =EntrySet.iterator();

while(it,hasNext())

{

       Map.Entry<K,V>me = it.next()

K key = me.getKey();

       Vvalue = me.getValue();

}

注意:

a)       没有keySet集合,只有Set集合和Map.Entry<K,V>(一般作为泛型使用)

b)      K,V指的是键和值的类型。

 

2,集合框架 list下面有哪些类,各自的特点,map的特点和下面有哪些子类和特点(2)

List集合下的类:

ArrayList 以数组为底层数据结构,查询速度非常快,线程不同步;

LinkedList 以链表为底层数据结构,添加删除速度非常快,线程不同步;

Vector 以数组为底层数据结构,添加删除,查询速度都非常慢,线程同步。

Map集合下的类:

HashTable 以哈希表作为底层数据结构,线程同步,不能存入null键,或null值;

HashMap 以哈希表作为底层数据结构,线程不同步,能存入null键和null值。

TreeMap 以二叉树作为底层数据结构,线程不同步。可以对map中的键指定顺序排序。

1、 每一个学生都有对应的归属地。学生Student,地址String。学生属性:姓名,年龄。

姓名和年龄相同的视为同一个学生。在保证学生的唯一性的情况下,对学生对象的年龄进行升序排序。。MapTest2

1、将不止一个对象一起存入map集合时,该如何取出?

        *   1.1 泛型的使用。将Iterator设定泛型为MapEntry<Student,String>

        *   1.2 直接使用规定的泛型对象作为迭代器取出值后转换对象。

        * 2、使用if(!(obj instanceof Student)) 用来判断是否为Student类型。

        * 3、实现比较器Comparator接口,复写其中compare(Object obj1,Object obj2)方法。

2、 "sdfgzxcvasdfxcvdf"获取该字符串中的字母出现的次数。笔试题

* 思路:

        * 1、使用TreeMap集合,因为TreeMap是有顺序的。

        * 2、可以将字符串转变为数组,方便操作

        * 3、还是之前的思路,以字符为键,同时记录字符出现的次数

        * 注意:

        * 1、因为map集合中可以直接通过value get(Key)的方法,通过键返回相对应的值,无需手动遍历map集合,就能知道其中字符的次数

        * 2、 Map.Entry<K,V>中的类型不可以是基本数据类型,而必须是引用数据类型?

        *3、对非字符进行判断


三、JDK1.5新特性


      泛型:jdk1.5版本以后出现的新特性,用于解决安全问题,是一个安全机制,类型安全机制;
好处:①将运行时的异常转移到了编译时期,方便程序员解决问题,让问题减少,提高安全性;
      ② 避免了强制类型转换的麻烦。
泛型的格式:通过“<>”定义要操作的引用数据类型,<>是接受类型的,当使用集合时,将集合中要
存储的数据类型作为参数传递到<>中即可。

泛型类:当定义的类中要操作的引用数据类型不确定的时候,早起定义Object来完成,现在定义泛型来完成,
泛型类定义的泛型在整个类中有效,如果某方法使用,那么泛型的对象明确要操作的具体类型后,
所有操作的类型就固定了,为了让不同的方法可以操作不同的类型,可以将泛型定义在方法上;
泛型类:class Demo<T> {public void show(T t)}
泛型方法:public <Q> void show(Q,q);

<> 定义在返回值类型的前面,修饰符的后面;
注意:静态函数不可以访问类上定义的泛型,如果静态方法操作应用的对象数据类型不确定,可以将泛型
定义在方法上。





0 0
原创粉丝点击