第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实现类:ArrayList,Vector,LinkedList
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元素
TreeSet,LinkedHashSetSet和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,键值对,映射所维护的键的类型,映射值得类型
将键映射到值得对象,一个映射不能包含重复的键,每个键最多只能映射一个值
HashMap,Hashtable,TreeMap,LinkedHashMap
1.HashMap:特点:线程不安全 允许key或者value是null值
2.TreeMap特点:按照键值排序,线程不安全
2.JAVA 集合实现类(集合类)
Java提供了一套实现了Collection接口的标准集合类。其中一些是具体类,这些类可以直接拿来使用,而另外一些是抽象类,提供了接口的部分实现
序号 类描述 1 AbstractCollection 实现了大部分的集合接口 2 AbstractList 继承于AbstractCollection 并且实现了大部分List接口 3 AbstractSequentialList 继承于 AbstractList ,提供了对数据元素的链式访问而不是随机访问 4 LinkedList该类实现了List接口,允许有null(空)元素。主要用于创建链表数据结构,该类没有同步方法,如果多个线程同时访问一个List,则必须自己实现访问同步,解决方法就是在创建List时候构造一个同步的List。例如:Listlist=Collections.synchronizedList(newLinkedList(…));LinkedList 查找效率低 5 ArrayList该类也是实现了List的接口,实现了可变大小的数组,随机访问和遍历元素时,提供更好的性能。该类也是非同步的,在多线程的情况下不要使用。ArrayList 增长当前长度的50%,插入删除效率低 6 AbstractSet 继承于AbstractCollection 并且实现了大部分Set接口 7 HashSet该类实现了Set接口,不允许出现重复元素,不保证集合中元素的顺序,允许包含值为null的元素,但最多只能一个 8 LinkedHashSet具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现 9 TreeSet该类实现了Set接口,可以实现排序等功能 10 AbstractMap 实现了大部分的Map接口 11 HashMap HashMap 是一个散列表,它存储的内容是键值对(key-value)映射,该类实现了Map接口,根据键的HashCode值存储数据,具有很快的访问速度,最多允许一条记录的键为null,不支持线程同步 12 TreeMap 继承了AbstractMap,并且使用一颗树 13 WeakHashMap 继承AbstractMap类,使用弱密钥的哈希表 14 LinkedHashMap 继承于HashMap,使用元素的自然顺序对元素进行排序 15 IdentityHashMap 继承AbstractMap类,比较文档时使用引用相等
3.迭代器
什么是迭代器?迭代器就是取出集合元素的方式
遍历一个集合中的元素,例如,显示集合中的每个元素
一般遍历数组都是采用for循环或者增强for,这两个方法也可以用在集合框架,但是还有一种方法是采用迭代器遍历集合框架,它是一个对象,实现了Iterator 接口或ListIterator接口
迭代器,使你能够通过循环来得到或删除集合的元素
ListIterator 继承了Iterator,以允许双向遍历列表和修改元素
迭代器方法: 使用 Java Iterator,通过实例列出Iterator和listIterator接口提供的所有方法
遍历 ArrayList:
public class Demo{ public static void main(String[] args) { List<String> list=new ArrayList<String>(); //实例化List集合 list.add("Hello"); //添加元素 list.add("World"); list.add("HAHAHAHA"); //第一种遍历方法使用foreach遍历List for (String str : list) { //也可以改写for(int i=0;i<list.size();i++)这种形式 System.out.println(str); } //第二种遍历,把链表变为数组相关的内容进行遍历 String[] strArray=new String[list.size()]; list.toArray(strArray); for(int i=0;i<strArray.length;i++) //这里也可以改写为 foreach(String str:strArray)这种形式{ System.out.println(strArray[i]); } //第三种遍历 使用迭代器进行相关遍历 Iterator<String> ite=list.iterator(); while(ite.hasNext()){ //判断下一个元素之后有值 System.out.println(ite.next()); } } }
三种方法都是用来遍历ArrayList集合
第三种方法是采用迭代器的方法,该方法可以不用担心在遍历的过程中会超出集合的长度遍历 Map:
public class Demo2{ public static void main(String[] args) { Map<String, String> map = new HashMap<String, String>(); //实例化Map集合 map.put("1", "value1"); //添加元素 map.put("2", "value2"); map.put("3", "value3"); //NO1.:普遍使用,二次取值 System.out.println("通过Map.keySet遍历key和value:"); for (String key : map.keySet()) { System.out.println("key= "+ key + " and value= " + map.get(key)); } //NO2. System.out.println("通过Map.entrySet使用iterator遍历key和value:"); Iterator<Map.Entry<String, String>> it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, String> entry = it.next(); System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } //NO3.:容量大时推荐使用此方法 System.out.println("通过Map.entrySet遍历key和value"); for (Map.Entry<String, String> entry : map.entrySet()) { System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } //NO4. System.out.println("通过Map.values()遍历所有的value,但不能遍历key"); for (String v : map.values()) { System.out.println("value= " + v); } } }
集合是一个对象,可容纳其他对象的引用。集合接口声明对每一种类型的集合可以执行的操作,集合框架的类和接口均在java.util包中
任何对象加入集合类后,自动转变为Object类型,所以在取出的时候,需要进行强制类型转换
4.JAVA 泛型
泛型的本质是参数化类型,所操作的数据类型被指定为一个参数
泛型方法:方法在调用时可以接收不同类型的参数。根据传递给泛型方法的参数类型,编译器适当地处理每一个方法调用
定义泛型方法的规则:
● 所有泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数声明部分在方法返回类型之前
● 每一个类型参数声明部分包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用指定一个泛型类型名称的标识符
● 类型参数能被用来声明返回值类型,并且能作为泛型方法得到的实际参数类型的占位符
● 泛型方法体的声明和其他方法一样。注意类型参数只能代表引用型类型
public class Demo3{ // 泛型方法 printArray public static < E > void printArray( E[] inputArray ){ // 输出数组元素 for ( E element : inputArray ){ System.out.printf( "%s ", element ); } System.out.println(); } public static void main( String args[] ){ // 创建不同类型数组: Integer, Double 和 Character Integer[] intArray = { 1, 2, 3, 4, 5 }; Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 }; Character[] charArray = { 'H', 'E', 'L', 'L', 'O' }; System.out.println( "整型数组元素为:" ); printArray( intArray ); // 传递一个整型数组 System.out.println( "\n双精度型数组元素为:" ); printArray( doubleArray ); // 传递一个双精度型数组 System.out.println( "\n字符型数组元素为:" ); printArray( charArray ); // 传递一个字符型数组 } }
泛型类
泛型类的声明和非泛型类的声明类似,除了在类名后面添加了类型参数声明部分
和泛型方法一样,泛型类的类型参数声明部分也包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符,接受一个或多个参数,这些类被称为参数化的类或参数化的类型
public class Demo4<T> { private T t; public void add(T t) { this.t = t; } public T get() { return t; } public static void main(String[] args) { Demo4<Integer> integerDemo = new Demo4<Integer>(); Demo4<String> stringDemo = new Demo4<String>(); integerDemo.add(new Integer(10)); stringDemo.add(new String("泛型类")); System.out.printf("整型值为 :%d\n\n", integerDemo.get()); System.out.printf("字符串为 :%s\n", stringDemo.get()); } }
初学(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