动态引用存储——集合&&精确的集合定义——泛型
- 2019 年 10 月 6 日
- 筆記
前言:
对于面向对象的语言来说,为了方便对多个对象进行操作,就必须要对对象进行存储。
使用数组来存储对象的最大问题就是数组长度的固定性。(不灵活,难扩展)
Java集合又称容器,可以动态的将对象的引用存储在容器中。(灵活可扩展)
集合和数组区别
数组:
- 可以存储同一类型的基本数据类型或者引用数据类型
- 长度固定
集合:
- 可以存储不同类型的元素,但必须是引用数据类型
- 长度可变
集合概览
Java集合类主要由Collection和Map派生而出。Collection是一个接口,是高度抽象出来的集合,它包含了集合的基本操作和属性;Map是一个映射接口,即key-value键值对。

Collection
- List 有序可重复
- ArrayList
- LinkedList
- Vector
- Stack
- Set 无序不可重复
- HashSet
- LinkedSet
- TreeSet
ArrayList – LinkedList – Vector- Stack特点
- ArrayList : 异步,线程不安全,执行效率高;底层使用数组,存读效率高,插入删除效率低
- LinkedList:异步,使用双向链表,插入删除效率高
- Vector: 同步,线程安全,执行效率较低
- Stack:继承Vector
从数据增长的角度看:
ArrayList和Vector都是使用数组(Array)来控制集合中的对象。
当你向两种类型中增加元素的时候,如果元素的数目超过了内部数组目前的长度他们都需要扩展内部数组的长度。
Vector缺省情况下自动增长原来一倍的数组长度,ArrayList是原来的50%。
所以如果你要在集合中保存大量的数据,那么使用Vector有一些优势。
HashSet- LinkedSet-TreeSet特点
HashSet由HashMap实现,存取,查找性能强。
LinkedHashSet继承HashSet。
TreeSet提供一个使用树结构存储Set接口的实现,对象以升序顺序存储,访问和遍历的时间很快。底层是TreeMap。
Map
- HashMap
- TreeMap
HashMap – TreeMap特点
HashMap通常比TreeMap快一点(树和哈希表的数据结构使然),建议多使用HashMap,在需要排序的Map时候才用TreeMap。
HashMap的结果是没有排序的,而TreeMap输出的结果是排好序的。
Collection接口和Iterator接口常用方法


简单使用:
1.HashSet
import java.util.Date; import java.util.HashSet; import java.util.Iterator; public class Main { public static void main(String[] args) { Date currentDate = new Date(); HashSet hs= new HashSet(); //添加元素 hs.add(currentDate.toString()); hs.add(new String("2")); hs.add("3"); hs.add("3");//不能包含重复元素,被自动覆盖 System.out.println("for 迭代输出"); for(Object element:hs) {System.out.println(element); } System.out.println("Iterator 迭代输出"); Iterator iterator=hs.iterator(); while(iterator.hasNext()) { System.out.println(iterator.next()); } //删除元素 hs.remove("2"); hs.remove(currentDate.toString()); System.out.println("删除元素后输出:"); for(Object element:hs) { System.out.println(element); } } }
2.TreeSet
//TreeSet默认自动排序 import java.util.TreeSet; import java.util.Iterator; public class Main { public static void main(String args[]) { TreeSet tr = new TreeSet(); tr.add("B"); tr.add("A"); tr.add("D"); tr.add("E"); System.out.println("直接输出集合对象"); System.out.println(tr); System.out.println("for遍历输出"); for (Object element : tr) { System.out.println(element); } System.out.println("Iterator迭代输出"); Iterator iterator = tr.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } }
3.LinkedList
import java.util.LinkedList; import java.util.Iterator; public class Main { public static void main(String []args) { LinkedList li= new LinkedList(); li.addFirst("C"); li.addLast("D"); li.addFirst("B"); li.addLast("E"); li.addFirst("A"); li.addLast("F"); System.out.println( "直接输出"); System.out.println(li); System.out.println("--------------------"); System.out.println( "用for输出"); for(Object str:li) {System.out.println(str);} System.out.println("--------------------"); System.out.println( "用迭代器输出"); Iterator iterator= li.iterator(); while(iterator.hasNext()) {System.out.println(iterator.next());} System.out.println("--------------------"); System.out.println("访问"); System.out.println("peekFirst:"+li.peekFirst());//getFirst,getLast System.out.println("peekLast:"+li.peekLast()); System.out.println("删除"); System.out.println(li.removeFirst());//pollFirst,pollLast System.out.println(li.removeLast()); System.out.println("--------------------"); System.out.println("用for输出"); for(Object str:li) {System.out.println(str);} System.out.println("--------------------"); } }
4.ArrayList
import java.util.ArrayList; import java.util.Iterator; public class Main { public static void main(String []args) { ArrayList list = new ArrayList(); list.add("A");//将指定的元素追加到此列表的尾部 list.add(1,"B");//插入列表的指定位置 list.add("C"); list.add("D"); list.add("E"); //for遍历 System.out.println("for遍历"); for(Object element:list) { System.out.println(element); } System.out.println("------------------"); //用迭代器遍历 //获取迭代器 System.out.println("迭代器遍历"); Iterator iterator = list.iterator(); //如果仍有元素可以迭代,则返回 true。 while(iterator.hasNext()) { System.out.println(iterator.next());// 返回迭代的下一个元素。 } System.out.println("------------------"); //删除元素remove System.out.println("删除前:"); for(Object element:list) { System.out.println(element); } list.remove(0); list.remove(2); System.out.println("------------------"); System.out.println("删除后:"); for(Object element:list) { System.out.println(element); } } }
5.HashMap
import java.util.HashMap; public class Main { public static void main(String []args) { HashMap hs = new HashMap<>(); //写入数据 System.out.println("写入数据..."); System.out.println("..."); hs.put(1,"华晨宇"); hs.put(2,"周杰伦"); hs.put(3,"刘若英"); hs.put(4,"许嵩"); //读取数据 System.out.println("读取数据..."); System.out.println("..."); System.out.println(hs.get(1)); System.out.println(hs.get(2)); System.out.println(hs.get(3)); System.out.println(hs.get(4)); //删除数据 System.out.println("..."); System.out.println("删除数据..."); hs.remove(1); System.out.println(hs.get(1)); } }
小结:
集合的实现类多种多样,但有一点不变,集合的主要作用是存储对象,操作对象;根据具体实现类的存储方式和操作性能特点来配合具体的应用场景是集合的正确打开方式。
集合通用性导致的问题
当把一个元素丢进集合后,集合为了更好的通用性,都会编译成Object类。
导致的问题:
- 不同对象保存到同一指定集合的异常
- 取出集合中元素导致的强制类型转换异常
什么是泛型?
参数化类型!!! 什么是参数化类型??? 将具体的类型(如String,Integer)抽象成参数。
泛型的作用
- 消除了集合中的强制类型转换,减少异常。
- 指定了对象的限定类型,实现了Java的类型安全。
- 合并代码。提高重用率。
泛型的表现形式
菱形语法:
List<String> list = new List<>(); Map<Integer , String > = new Map<>();
泛型类
//泛型类 public class Main<T> { private T data; public Main(T data) { this.data=data; } public T getData() { return data; } public static void main(String []args) { Main<Integer> g1 = new Main<Integer>(1222); System.out.println(g1.getData()); Main<Double> g2 = new Main<Double>(1222.1222); System.out.println(g2.getData()); Main<String> g3 = new Main<String>("cat"); System.out.println(g3.getData()); } }

泛型方法
public class Main { public static <E> void printArray(E inputArray[]) { for(E element:inputArray) { System.out.printf("%s",element); } } public static void main(String args[]) { Integer intArray[]= {1,2,3,4,5}; Double doubleArray[]= {1.1,2.2,3.3,4.4,5.5}; Character charArray[]= {'A','B','C'}; System.out.printf("整型数组为:n"); printArray(intArray); System.out.printf("n"); System.out.printf("双精度数组为:n"); printArray(doubleArray); System.out.printf("n"); System.out.printf("字符型数组为:n"); printArray(charArray); System.out.printf("n"); } }

泛型接口
public interface TestInterface<T> { public T next(); }
import java.util.Random; public class Main implements TestInterface<String> { String list[]={"L","A","C"}; @Override public String next() { Random rand = new Random(); return list[rand.nextInt(2)]; } public static void main(String[] args) { Main obj = new Main(); System.out.println(obj.next()); } }
