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

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

  • 每篇一句 :所有的不甘,都是因为还心存梦想
  • 初学心得: 不是每件事都注定会成功,但是每件事都值得一试
  • (笔者:JEEP/711)[JAVA笔记 | 时间:2017-04-15| JAVA 集合框架/JAVA 泛型 ]

目录导航


1.JAVA 集合框架概念

通俗的说,集合就是一个存放数据的容器,准确的说,就是放数据对象引用的容器
数组和集合都是容器,有何不同?
数组长度固定,集合长度可变
数组只能存放相同类型的数据,集合可以存放不同类型的数据
数组可存放简单数据类型和类类型的数据,集合只能存放类类型数据
JAVA集合框架:java中用来表示集合,和操作集合的所有类库的统称
JAVA中的集合从大方向分有两种:Collection 集合,Map 集合,它们都继承自Object
Alt text
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,以允许双向遍历列表和修改元素

迭代器方法:
使用 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 泛型 高级阶段) 难点: ★★★★★

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

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值