java集合

本文深入解析Java集合框架,包括Collection接口及其子接口List、Set,还有Map接口的不同实现类的特点和应用场景,帮助开发者理解何时使用何种集合。

     java.util包中提供了一些集合类,这些集合类又被称为容器。集合类和数组的区别是数组的长度是固定的,集合的长度是可变的;数组用来存放基本类型的数据,集合一般用来存放对象的引用。常用的集合有list,set和map,其中list和set继承了collection接口,各个接口提供了不同的实现类。

    1.collection接口是层次结构中的根接口,构成collection的单位称为元素,collection接口通常不能直接使用

import java.util.ArrayList;
import java.util.Iterator;

public class Collection {
    public static void main(String[] args) {
        java.util.Collection<String> list=new ArrayList<String>();//向上转型
        list.add("a");
        list.add("b");
        list.add("c");
        System.out.println(list.size());//集合size
        //使用foreach遍历
        for (String string : list) {
            System.out.println(string);
        }
        //迭代器遍历It
        Iterator<String> it=list.iterator();
        while(it.hasNext()){
            String str=it.next();
            System.out.println(str);
            /*如果这样输出System.out.println(it.next());会报错
             * Exception in thread "main" java.util.NoSuchElementException
              at java.util.AbstractList$Itr.next(AbstractList.java:350)
             */
            
        }
    }
}

2.list集合:list集合中的元素可以重复,个元素的顺序就是对象插入时的顺序,类似于java数组,用户可以使用索引(元素在集合的位置)来访问集合中的元素,常用的实现类有arraylist,linkedlist.

3,ArrayList:实现了可变的数组,允许保存所有的元素,包括null,并可以根据索引的位置对集合进行快速的随机访问;缺点是向指定的索引位置插入对象或删除对象的速度较慢

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class TestList {
    
   public static void main(String[] args) {
    List<Integer> list=new ArrayList<Integer>();
    list.add(2);
    list.add(1);
    list.add(3);
    list.add(3);
    list.remove(3);
    for (Integer integer : list) {
        System.out.println(integer);
    }
    for (int i = 0; i < list.size(); i++) {
        System.out.println(list.get(i));
    }
    Iterator<Integer> it=list.iterator();
    while(it.hasNext()){
        int a=it.next();
        System.out.println(a);
    }
    
}
}

4,LinkedList:采用链表的结构保存对象,优点就是便于向集合中插入和删除对象,需要向集合中插入,删除对象时,使用LinkedList类实现list集合的效率较高;但是对于随机访问集合对象,使用LinkedList类实现list的效率较低

5,set集合:set集合的对象不按特定的方式排序,只是简单的把对象加入集合,不能包含重复对象,常用的实现类是hashset和treeset

6,hashSet:由哈希表(实际上是一个hashMap实例)支持,它不保证Set的迭代顺序,特别是不保证顺序恒久不变,允许一个null元素。

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class TestSet {
   public static void main(String[] args) {
    Set<String> set=new HashSet<String>();
    set.add("a");
    set.add("b");
    set.add("c");
    for (String string : set) {
        //System.out.println(string);
    }
    Iterator<String> it=set.iterator();
    while(it.hasNext()){
        String s=it.next();
        System.out.println(s);
    }
}
}

7,TreeSet类不仅实现了Set接口,还实现了java.util.SortedSet接口,因此,TreeSet类实现的Set集合在遍历集合时按照自然顺序递增排序,也可以指定的顺序排序,既可以通过比较器对用TreeSet类实现的Set集合中的对象进行排序,即实现comparable接口

import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class UpdateStu implements Comparable<Object> {
    private String name;
    private long id;
    public UpdateStu(String name,long id){//构造方法
        this.id=id;
        this.name=name;
    }
    //set,get方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    @Override
    public int compareTo(Object o) {
        // TODO Auto-generated method stub
        UpdateStu upstu=(UpdateStu) o;
        int result=id>upstu.id?1:(id==upstu.id?0:-1);
        //该接口中的compareTo(Object o)方法比较此对象与指定对象的顺序。如果该对象小于,等于或大于指定对象,则分别返回-1,0.1
        
        return result;
    }
   public static void main(String[] args) {
    UpdateStu stu1=new UpdateStu("小李", 4);
    UpdateStu stu2=new UpdateStu("小王", 22);
    UpdateStu stu3=new UpdateStu("小张", 7);
    UpdateStu stu4=new UpdateStu("小刘", 2);
    Set<UpdateStu> tree=new TreeSet<UpdateStu>();
    tree.add(stu1);
    tree.add(stu2);
    tree.add(stu3);
    tree.add(stu4);
    Iterator<UpdateStu> it=tree.iterator();
    //实现了安装id排序
    while(it.hasNext()){
        UpdateStu stu=it.next();
        //System.out.println(stu.getId()+"\t"+stu.getName());
    }
    //这里要强制转换为treeset,因为headSet是treeSet特有的方法
    Iterator<UpdateStu> it2=((TreeSet<UpdateStu>) tree).headSet(stu2).iterator();
    //截取排在stu2对象之前的对象,注意,截取的是排序后的
    while(it2.hasNext()){
        UpdateStu stuLast=it2.next();
        //System.out.println(stuLast.id+"\t"+stuLast.name);
    }
    //截取排在stu2和stu1之间的对象,注意stu要排在stu2之前,否则报错
    Iterator<UpdateStu> it3=((TreeSet<UpdateStu>)tree).subSet(stu1, stu2).iterator();
    while(it3.hasNext()){
        UpdateStu stuMidd=it3.next();
        System.out.println(stuMidd.id+"\t"+stuMidd.name);
    }
    //返回set中第一个(最低)元素
   System.out.println(((TreeSet<UpdateStu>) tree).first().id);
   //返回set中最后一个(最高)元素
   System.out.println(((TreeSet<UpdateStu>) tree).last().id);
}
}

8.map集合:

   map集合没有继承collection接口,其提供的是key到value的映射。map中不能包含相同的key,每个key只能映射一个value,key还决定了存储对象在映射中的存储位置,但不是由key对象本身决定的,而是通过一种“散列技术”进行处理,产生一个散列码的整数值,散列码通常用作一个偏移量,该偏移量对应分配给映射的内存区域的起始位置,从而确定存储对象在映射中的存储位置。实现类有hashMap,treeMap.建议使用hashMap类实现map集合,因为有hashmap类实现的map集合添加和删除映射关系效率更高。hashMap是基于哈希表的Map接口的实现,hashMap通过哈希码对其内部的映射关系进行快速查找;而TreeMap中的映射关系存在一定的顺序,如果希望Map集合中的对象也存在一定的顺序,应当使用TreeMap来实现Map集合

9.HashMap类是基于哈希表的Map接口实现,此实现提供所有可选的映射操作,并允许使用null值和null键,但必须保证键的唯一性。hashMap通过哈希表对其内部的映射关系进行快速查找。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。

10.TreeMap类不仅实现了Map接口,还实现了java.util.SortedMap接口,因此,集合中的映射关系具有一定的顺序。但是在添加,删除和定位映射关系时,TreeMap类比HashMap类性能稍差,由于TreeMap类实现的Map集合中的映射关系是根据键对象按照一定顺序排列的,所以不允许键对象为空。可以通过HashMap类创建Map集合,当需要顺序输出时,再创建一个TreeMap

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class TestMap {
  public static void main(String[] args) {
    Map<Integer, String> map=new HashMap<Integer, String>();
    map.put(1, "a");
    map.put(2, "b");
    map.put(3, "c");
    map.put(4, "c");
    //输出键值对
    System.out.println(map);//{1=a, 2=b, 3=c, 4=c}
    //输出该集合中所有值对象形成的Collection集合
    System.out.println(map.values());//[a, b, c, c]
    Set<Integer> set=map.keySet();
    Iterator<Integer> it=set.iterator();
    while(it.hasNext()){
        int key=it.next();
        //集合中所有key集合
        //System.out.println(key);
        //遍历集合
        System.out.println(key+"\t"+map.get(key));
    }
    
}
}


  总结:如果涉及到堆栈,队列等操作,应该考虑用List,对于需要快速插入,删除元素,应该使用LinkedList,如果需要快速随机访问元素,应该使用ArrayList。
  如果程序在单线程环境中,或者访问仅仅在一个线程中进行,考虑非同步的类,其效率较高,如果多个线程可能同时操作一个类,应该使用同步的类。LinkedList,ArrayList也是非同步的(unsynchronized)。Vector是同步
  要特别注意对哈希表的操作,作为key的对象要正确复写equals和hashCode方法。
  尽量返回接口而非实际的类型,如返回List而非ArrayList,这样如果以后需要将ArrayList换成LinkedList时,客户端代码不用改变。这就是针对抽象编程。

相互区别

注:文章出处:http://blog.youkuaiyun.com/fyang2007/article/details/51517662

Vector和ArrayList

1,vector是线程同步的,所以它也是线程安全的,而arraylist是线程异步的,是不安全的。如果不考虑到线程的安全因素,一般用

arraylist效率比较高。
2,如果集合中的元素的数目大于目前集合数组的长度时,vector增长率为目前数组长度的100%,而arraylist增长率为目前数组长度

的50%.如过在集合中使用数据量比较大的数据,用vector有一定的优势。
3,如果查找一个指定位置的数据,vector和arraylist使用的时间是相同的,都是0(1),这个时候使用vector和arraylist都可以。而

如果移动一个指定位置的数据花费的时间为0(n-i)n为总长度,这个时候就应该考虑到使用linklist,因为它移动一个指定位置的数据

所花费的时间为0(1),而查询一个指定位置的数据时花费的时间为0(i)。

ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许直接序号索引元素,但是插入数据要设计到数组元素移动 等内存操作,所以索引数据快插入数据慢,Vector由于使用了synchronized方法(线程安全)所以性能上比ArrayList要 差,LinkedList使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项的前后项即可,所以插入数度较快!

arraylist和linkedlist

1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
    这一点要看实际情况的。若只对单条数据插入或删除,ArrayList的速度反而优于LinkedList。但若是批量随机的插入删除数 据,LinkedList的速度大大优于ArrayList. 因为ArrayList每插入一条数据,要移动插入点及之后的所有数据。


HashMap与TreeMap
        (注)
       文章出处:http://www.diybl.com/course/3_program/java/javaxl/200875/130233.html

       1、HashMap通过hashcode对其内容进行快速查找,而TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的)。

HashMap中元素的排列顺序是不固定的)。

        2、  HashMap通过hashcode对其内容进行快速查找,而TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该 使用TreeMap(HashMap中元素的排列顺序是不固定的)。集合框架”提供两种常规的Map实现:HashMap和TreeMap (TreeMap实现SortedMap接口)。

         3、在Map 中插入、删除和定位元素,HashMap 是最好的选择。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。使用HashMap要求添加的键类明确定义了hashCode()和 equals()的实现。  这个TreeMap没有调优选项,因为该树总处于平衡状态。

      结过研究,在原作者的基础上我还发现了一点,二树map一样,但顺序不一样,导致hashCode()不一样。
      同样做测试:
      在hashMap中,同样的值的map,顺序不同,equals时,false;
      而在treeMap中,同样的值的map,顺序不同,equals时,true,说明,treeMap在equals()时是整理了顺序了的。

hashtable与hashmap

一.历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现

二.同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的

三.值:只有HashMap可以让你将空值作为一个表的条目的key或value


   

   
















  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值