首页 > 代码库 > 第10篇-JAVA 集合框架-JAVA 泛型

第10篇-JAVA 集合框架-JAVA 泛型

第10篇-JAVA 集合框架-JAVA 泛型

  • 每篇一句 :所有的不甘,都是因为还心存梦想

  • 初学心得: 不是每件事都注定会成功,但是每件事都值得一试

  • (笔者:JEEP/711)[JAVA笔记 | 时间:2017-04-15| JAVA 集合框架/JAVA 泛型 ]

1.JAVA 集合框架概念

通俗的说,集合就是一个存放数据的容器,准确的说,就是放数据对象引用的容器 
数组和集合都是容器,有何不同? 
数组长度固定,集合长度可变 
数组只能存放相同类型的数据,集合可以存放不同类型的数据 
数组可存放简单数据类型和类类型的数据,集合只能存放类类型数据 
JAVA集合框架:java中用来表示集合,和操作集合的所有类库的统称 

技术分享

JAVA中的集合从大方向分有两种:Collection 集合,Map 集合,它们都继承自Object 

Collection又有两个分支 
1.List(列表),2.Set(集合),List和Set也都是接口 
List接口的特点: 集合中的元素有顺序,能重复

集合中分为三大接口
Collcction、Map(映射)、Itcrator(迭代的父类接口) 
集合框架的接口和类在java.util包中 
Collcction分支为两个子接口list(列表接口),set(集合接口)

集合框架List接口 
有序的接口,此接口的用户可以对列表中的每个元素的插入位置进行 
精确的控制,用户可以根据元素的整数索引(在列表中的位置)访问元素,并索列表中的元素 
List实现类ArrayListVectorLinkedList 
1.ArrayList是底层用数组实现的List 
特点:查询效率高,增删效率低, 线程不安全 
2.LinkedList是底层用双向循环链表实现的List 
特点:查询效率低,增删效率高 
3.Vector: 底层用数组实现List接口的另一个类 
特点:重量级,占据更多的系统开销,线程安全

集合框架Set接口 
Set接口特点是集合中的元素无顺序(存入和取出的顺序不一定一致),不能重复 
Set接口一个不包含重复元素的collection,更确切的讲,set不包含满足e1.euuals(e2)的元素 
对e1和e2,并且最多包含一个null元素,正如其名称所暗示的,此接口模仿了数学上的ste抽象 
HashSet类实现Set接口,由哈希表(实际上是一个HashMap实例)支持,它不保证set的迭代顺序,特别是它不保证该顺序恒久不变,此类允许使用null元素 
TreeSetLinkedHashSet

Set和List的区别 
● 1. Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,可以重复的元素 
● 2. Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet> 
● 3. List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector> 
Set分支的常用类有:HashSet,TreeSet 
1.HashSet:底层数据结构是哈希表 
特点:增、删集合中的元素速度快 
2.TreeSet集合中的元素除了没有顺序和不能重复外,还会自然排序,这便是该集合的特点

集合框架Map接口 
Map接口 
特点:K与V,键值对,映射所维护的键的类型,映射值得类型 
将键映射到值得对象,一个映射不能包含重复的键,每个键最多只能映射一个值 
HashMapHashtableTreeMapLinkedHashMap 
1.HashMap:特点:线程不安全 允许key或者value是null值 
2.TreeMap特点:按照键值排序,线程不安全

2.JAVA 集合实现类(集合类)

Java提供了一套实现了Collection接口的标准集合类。其中一些是具体类,这些类可以直接拿来使用,而另外一些是抽象类,提供了接口的部分实现

序号类描述
1AbstractCollection 实现了大部分的集合接口
2AbstractList 继承于AbstractCollection 并且实现了大部分List接口
3AbstractSequentialList 继承于 AbstractList ,提供了对数据元素的链式访问而不是随机访问
4LinkedList该类实现了List接口,允许有null(空)元素。主要用于创建链表数据结构,该类没有同步方法,如果多个线程同时访问一个List,则必须自己实现访问同步,解决方法就是在创建List时候构造一个同步的List。例如:Listlist=Collections.synchronizedList(newLinkedList(…));LinkedList 查找效率低
5ArrayList该类也是实现了List的接口,实现了可变大小的数组,随机访问和遍历元素时,提供更好的性能。该类也是非同步的,在多线程的情况下不要使用。ArrayList 增长当前长度的50%,插入删除效率低
6AbstractSet 继承于AbstractCollection 并且实现了大部分Set接口
7HashSet该类实现了Set接口,不允许出现重复元素,不保证集合中元素的顺序,允许包含值为null的元素,但最多只能一个
8LinkedHashSet具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现
9TreeSet该类实现了Set接口,可以实现排序等功能
10AbstractMap 实现了大部分的Map接口
11HashMap HashMap 是一个散列表,它存储的内容是键值对(key-value)映射,该类实现了Map接口,根据键的HashCode值存储数据,具有很快的访问速度,最多允许一条记录的键为null,不支持线程同步
12TreeMap 继承了AbstractMap,并且使用一颗树
13WeakHashMap 继承AbstractMap类,使用弱密钥的哈希表
14LinkedHashMap 继承于HashMap,使用元素的自然顺序对元素进行排序
15IdentityHashMap 继承AbstractMap类,比较文档时使用引用相等

3.迭代器

什么是迭代器?迭代器就是取出集合元素的方式 
遍历一个集合中的元素,例如,显示集合中的每个元素 
一般遍历数组都是采用for循环或者增强for,这两个方法也可以用在集合框架,但是还有一种方法是采用迭代器遍历集合框架,它是一个对象,实现了Iterator 接口或ListIterator接口 
迭代器,使你能够通过循环来得到或删除集合的元素 
ListIterator 继承了Iterator,以允许双向遍历列表和修改元素

1.迭代器方法:
2.使用 Java Iterator,通过实例列出Iterator和listIterator接口提供的所有方法

遍历 ArrayList:

1.public class Demo{
2.public static void main(String[] args) {
3.    List<String> list=new ArrayList<String>(); //实例化List集合
4.    list.add("Hello"); //添加元素
5.    list.add("World");
6.    list.add("HAHAHAHA");
7.    //第一种遍历方法使用foreach遍历List
8.    for (String str : list) {            
9.    //也可以改写for(int i=0;i<list.size();i++)这种形式
10.       System.out.println(str);
11.    }
12.    //第二种遍历,把链表变为数组相关的内容进行遍历
13.    String[] strArray=new String[list.size()];
14.    list.toArray(strArray);
15.    for(int i=0;i<strArray.length;i++) //这里也可以改写为  foreach(String str:strArray)这种形式{
16.       System.out.println(strArray[i]);
17.    }
18.  //第三种遍历 使用迭代器进行相关遍历
19.  Iterator<String> ite=list.iterator();
20.    while(ite.hasNext()){ //判断下一个元素之后有值
21.        System.out.println(ite.next());
22.   }
23. }
24.}

三种方法都是用来遍历ArrayList集合 
第三种方法是采用迭代器的方法,该方法可以不用担心在遍历的过程中会超出集合的长度


遍历 Map:

1.public class Demo2{
2.    public static void main(String[] args) {
3.     Map<String, String> map = new HashMap<String, String>(); //实例化Map集合
4.     map.put("1", "value1"); //添加元素
5.     map.put("2", "value2");
6.     map.put("3", "value3");
7.     //NO1.:普遍使用,二次取值
8.     System.out.println("通过Map.keySet遍历key和value:");
9.     for (String key : map.keySet()) {
10.      System.out.println("key= "+ key + " and value=http://www.mamicode.com/ " + map.get(key));
11.     }
12.      //NO2.
13.     System.out.println("通过Map.entrySet使用iterator遍历key和value:");
14.     Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
15.     while (it.hasNext()) {
16.      Map.Entry<String, String> entry = it.next();
17.      System.out.println("key= " + entry.getKey() + " and value=http://www.mamicode.com/ " + entry.getValue());
18.     }
19.     //NO3.:容量大时推荐使用此方法
20.     System.out.println("通过Map.entrySet遍历key和value");
21.     for (Map.Entry<String, String> entry : map.entrySet()) {
22.      System.out.println("key= " + entry.getKey() + " and value=http://www.mamicode.com/ " + entry.getValue());
23.     }
24.      //NO4.
25.     System.out.println("通过Map.values()遍历所有的value,但不能遍历key");
26.     for (String v : map.values()) {
27.      System.out.println("value=http://www.mamicode.com/ " + v);
28.      }
29.    }
30.}

集合是一个对象,可容纳其他对象的引用。集合接口声明对每一种类型的集合可以执行的操作,集合框架的类和接口均在java.util包中 
任何对象加入集合类后,自动转变为Object类型,所以在取出的时候,需要进行强制类型转换

4.JAVA 泛型

泛型的本质是参数化类型,所操作的数据类型被指定为一个参数 
泛型方法:方法在调用时可以接收不同类型的参数。根据传递给泛型方法的参数类型,编译器适当地处理每一个方法调用 
定义泛型方法的规则: 
● 所有泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数声明部分在方法返回类型之前 
● 每一个类型参数声明部分包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用指定一个泛型类型名称的标识符 
● 类型参数能被用来声明返回值类型,并且能作为泛型方法得到的实际参数类型的占位符 
● 泛型方法体的声明和其他方法一样。注意类型参数只能代表引用型类型

1.public class Demo3{
2.  // 泛型方法 printArray                         
3.  public static < E > void printArray( E[] inputArray ){
4.     // 输出数组元素            
5.        for ( E element : inputArray ){        
6.           System.out.printf( "%s ", element );
7.        }
8.        System.out.println();
9.   }
10.
11. public static void main( String args[] ){
12.       // 创建不同类型数组: Integer, Double 和 Character
13.       Integer[] intArray = { 1, 2, 3, 4, 5 };
14.       Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
15.       Character[] charArray = { ‘H‘, ‘E‘, ‘L‘, ‘L‘, ‘O‘ };
16. System.out.println( "整型数组元素为:" );
17.       printArray( intArray  ); // 传递一个整型数组
18. System.out.println( "\n双精度型数组元素为:" );
19.       printArray( doubleArray ); // 传递一个双精度型数组
20.  System.out.println( "\n字符型数组元素为:" );
21.       printArray( charArray ); // 传递一个字符型数组
22.   } 
23.}

泛型类 
泛型类的声明和非泛型类的声明类似,除了在类名后面添加了类型参数声明部分 
和泛型方法一样,泛型类的类型参数声明部分也包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符,接受一个或多个参数,这些类被称为参数化的类或参数化的类型

1.public class Demo4<T> {  
2. private T t;
3.public void add(T t) {
4.   this.t = t;
5. }
6. public T get() {
7.   return t;
8. }
9. public static void main(String[] args) {
10.   Demo4<Integer> integerDemo = new Demo4<Integer>();
11.   Demo4<String> stringDemo = new Demo4<String>();
12.  integerDemo.add(new Integer(10));
13.   stringDemo.add(new String("泛型类"));
14. System.out.printf("整型值为 :%d\n\n", integerDemo.get());
15.   System.out.printf("字符串为 :%s\n", stringDemo.get());
16.  }
17.}

初学(JAVA 集合框架/JAVA 泛型 高级阶段) 难点: ★★★★★

希望每一篇文章都能够对读者们提供帮助与提升,这乃是每一位笔者的初衷


感谢您的阅读 欢迎您的留言与建议

  • FaceBook:JEEP SevenEleven

  • Twitter:@JEEP7ll

  • 新浪官方微博: @中國熱點影視傳媒

  • Github博客: https://github.com/jeep711/jeep711.github.io

  • Blog Garden:http://www.cnblogs.com/JEEP711/

  • W3C/Blog:http://www.w3cschool.cn/jeep711blog/

  • CSDN/Blog:http://blog.csdn.net/jeep911

  • 51CTO/Blog:http://jeep711.blog.51cto.com/

  • 码云:http://git.oschina.net/JEEP711/jeep711.github.io

  • 邮箱: jeep711@qq.com,JEEP-711@outlook.com



本文出自 “JEEP711” 博客,请务必保留此出处http://jeep711.blog.51cto.com/12970787/1941723

第10篇-JAVA 集合框架-JAVA 泛型