java中collection接口中的集合

首先我们先来了解集合和数组相比的优点:

数组:一旦声明了数组长度无法改变,只能保持指定的数据类型,元素的数据类型必须相同,不能混排。
集合:长度和动态扩容,元素类型可以是任何类型,可以混合使用。

今天浅谈一下collection接口下的集合。

collection接口下有List和Set接口。

List接口:不唯一,有序(添加顺序)

List接口下有:ArrayList,LinkedList,vector,三种常用的实现类。我们一一说一下它们各自的特点。

Arraylist

* ----ArrayList类:可变长度的数组,本质上是通过数组实现的,在内存中存储空间是连续
* ------优点:随机访问或遍历时效率较高
* ------缺点:插入和删除时需要大量对元素的位置进行移动,效率较低。
* ` ArrayList常用的构造方法
* ArrayList() 构造一个初始容量为 10 的空列表。
* ArrayList(int initialCapacity) 构造一个具有指定初始容量的空列表。

*java.util.ArrayList类
*add(Object obj):添加元素
*Object get(int index):获取指定下标位置的元素.
*注意:在调用add方法添加元素时,该元素会向上转型为Object类型,所有使用get方法获取是返回值为Object 
*/

 1 public class TestArrayList {
 2     public static void main(String[] args) {
 3 //        Collection list = new ArrayList();
 4         List list = new ArrayList();
 5         //添加元素
 6         list.add("aa");
 7         list.add("bb");
 8         list.add("cc");
 9         list.add(2,"dd");
10         list.remove(0);
11         list.remove("bb");
12         ArrayList subList = new ArrayList();
13         subList.add("hello");
14         subList.set(0, "world");
15         list.addAll(subList);
16         //遍历输出
17         for(int i=0;i<list.size();i++){
18             String string =(String)list.get(i);//强制转换!
19             System.out.println(string);
20         }
21     }
22 }

 

* 常用的方法:
* add(Object e):将元素添加到集合中。
* add(int index, E element) 将指定的元素插入此列表中的指定位置。
* get(int index) 返回此列表中指定位置上的元素。下标从0开始
* addAll(Collection<? extends E> c) 按照指定 collection 的迭代器所返回的元素顺序,将该 collection 中的所有元素添加到此列表的尾部。
* set(int index, E element)用指定的元素替代此列表中指定位置上的元素。
* remove(int index)移除此列表中指定位置上的元素。
* remove(Object o) 移除此列表中首次出现的指定元素(如果存在)。

****** 其它一些方法可以通过api查看。

为了免除强制转换我们可以加入泛型,来通过一开始限制类型,完成输出

 

/**
* 泛型:限定集合中元素的类型。一旦对集合使用泛型,该集合中能容纳的元素类型就固定了。
* 语法:List<E> list = new ArrayList<E>();
* 优点:1.可以避免强制转换
* 2.可以消除黄色的警告。
*/eg:

 

public class TestArrayList3 {
    public static void main(String[] args) {
        Student student = new Student("zhangsan",20);
        Student student2 = new Student("zhangsan2",22);
        Student student3 = new Student("zhangsan3",24);
        List<Student> list = new ArrayList<Student>();
        list.add(student);
        list.add(student2);
        list.add(student3);
//        list.add(123);
//        list.add("abc");
        //遍历输出
        for(int i=0;i<list.size();i++){
            Student stu=list.get(i);//使用泛型后不需要强制转换
            System.out.println(stu.getName()+"---"+stu.getAge());
        }
        System.out.println("-----------");
        for(Student stu:list){
            System.out.println(stu.getName()+"---"+stu.getAge());
        }
     }

/**
* java.util.Iterator接口:对 collection 进行迭代的迭代器。
* boolean hasNext() 如果仍有元素可以迭代,则返回 true。
* E next() 返回迭代的下一个元素。
*
*/

可以通过迭代器进行遍历:eg

public class TestIterator {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("zhang");
        list.add("wang");
        list.add("li");
        list.add("zhao");
        //使用迭代器进行遍历
        Iterator<String> iter = list.iterator();
        //判断是否还有下一个元素可迭代
        while(iter.hasNext()){
            String str = iter.next();//获取下一个元素
            System.out.println(str);
        }
        System.out.println("---------老外习惯用for进行迭代--------");
        for(Iterator<String> iter2=list.iterator();iter2.hasNext();){
            String str2 = iter2.next();
            System.out.println(str2);
        }
        
    } 
}

  LinkedList类:

* ----LinkedList类:在内存中存储位置是不连续的,链表结构,

*插入和删除元素时效率较高,但随机访问或遍历效率较低。
* 常用方法:
* add(Object o):将指定元素添加到此列表的结尾。
* add(int index, E element)在此列表中指定的位置插入指定的元素。
* addFirst(E e) 将指定元素插入此列表的开头。(LinkedList特有的)
* addLast(E e)将指定元素添加到此列表的结尾。(LinkedList特有的)
* getFirst() 返回此列表的第一个元素。
* getLast() 返回此列表的最后一个元素。
* removeFirst() 移除并返回此列表的第一个元素。
* removeLast() 移除并返回此列表的最后一个元素。
*/eg:

public class TestLinkedList {
    public static void main(String[] args) {
//        List list = new LinkedList();
        LinkedList<String> linkedList = new LinkedList<String>();
        linkedList.add("java");
        linkedList.add("oracle");
        linkedList.addFirst("c");
        linkedList.addLast("html");
        linkedList.removeFirst();//移除第一个元素
        linkedList.removeLast();//移除最后一个元素
        //方法1:通过下标进行遍历
        for (int i = 0; i < linkedList.size(); i++) {
            String str = linkedList.get(i);
            System.out.println(str);
        }
        System.out.println("-------------");
        //方法2:通过foreach进行遍历
        for (String string : linkedList) {
            System.out.println(string);
        }
        System.out.println("-------------");
        //方法3:通过iterator进行遍历
        Iterator<String> iter = linkedList.iterator();
        while(iter.hasNext()){
            String string = iter.next();
            System.out.println(string);
        }
        
        
    }
}

  vector类:

 * ---Vector:线性结构,与ArrayList相似,Vector是线程安全的用在多线程程序中,相比ArrayList效率较低。

 ******用法和ArrayList一致。不多介绍!

其次List里面还有:栈LIFO和队列FIFO;

/**
*栈LIFO/FILO:后进先出(Last In First Out),先进后出(First In Last Out)
* 类似于玩具枪的弹夹,第一个压进去的子弹最后一个弹出
*入栈(压栈):将元素添加到栈中。
*出栈(弹栈):将元素从栈的顶部移除。
*队列FIFO:先进先出(First In First Out)
*/

Set接口:无序,唯一(不重复)

  HashSet类:

*----HashSet:采用hash表(散列表)方式进行存储数据。
* 优点:查询,添加,删除速度较快。
* 缺点:无序(添加顺序)

*常用的构造方法:
* HashSet() 构造一个新的空 set,其底层 HashMap 实例的默认初始容量是 16,加载因子是 0.75。
* HashSet(int initialCapacity) 构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和默认的加载因子(0.75)。
*常用的方法:

ublic class TestHashSet {
    public static void main(String[] args) {
        Set<String> set = new HashSet<String>();
        set.add("java");
        set.add("mysql");
        set.add("html");
        set.add("java");//添加时会去掉重复项
        System.out.println("共有"+set.size()+"个元素");
        //遍历1:通过for-each遍历
        for(String str:set){
            System.out.println(str);
        }
        System.out.println("---------------");
        Iterator<String> iter = set.iterator();
        while(iter.hasNext()){
            String str = iter.next();
            System.out.println(str);
        }
    }
}

 


* add(E e)如果此 set 中尚未包含指定元素,则添加指定元素。
* clear() 从此 set 中移除所有元素。
* contains(Object o) 如果此 set 包含指定元素,则返回 true。
* iterator() 返回对此 set 中元素进行迭代的迭代器。
* size()返回此 set 中的元素的数量(set 的容量)。
* remove(Object o)如果指定元素存在于此 set 中,则将其移除。
*/

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

/**
*如果向set结合添加对象时,想将内容相同的重复项去掉,需要重写hashCode()和equals()
*hashCode()和equals()的关系
*在向Set集合中添加元素时 ,先调用hashCode()方法获取当前对象的hash码,
*根据对象的hash码与集合中对象的hash码进行比较,如果hash码相同在调用equals()方法进行比较内容是否相同。
*如果hash码不同,将不再调用equals方法。
*如果equals相同,hash码肯定相同;hash码相同,equals结果不一定相同。
*/eg:

public class TestHashSet2 {
    public static void main(String[] args) {
        Student stu1 = new Student("zhangsan",20);
        Student stu2 = new Student("zhangsan2",22);
        Student stu3 = new Student("zhangsan",20);
        Set<Student> set = new HashSet<Student>();
        set.add(stu1);
        set.add(stu2);
        set.add(stu3);
        for (Student student : set) {
            System.out.println(student.getName()+"---"+student.getAge());
        }
    }
}

----LinkedHashSet:哈希表+链表结构进行存储。有序(添加顺序)。


*常用的构造方法
*LinkedHashSet() 构造一个带默认初始容量 (16) 和加载因子 (0.75) 的新空链接哈希 set
*LinkedHashSet(int initialCapacity) 构造一个带指定初始容量和默认加载因子 (0.75) 的新空链接哈希 set。
*常用的方法:
* add(Object a):添加元素
* remove(Object a):移除指定的元素
* contains(Object a):是否包含指定的元素
* size():获取元素的个数。
* iterator():返回一个迭代器

eg:

public class TestLinkedHashSet {
    public static void main(String[] args) {
        Set<String> set = new LinkedHashSet<String>();
        set.add("java");
        set.add("struts");
        set.add("hibernate");
        set.add("spring");
//        System.out.println(set);
        for (String string : set) {
            System.out.println(string);
        }
        System.out.println("-----------------");
        Iterator<String> iter = set.iterator();
        while(iter.hasNext()){
            String string = iter.next();
            System.out.println(string);
        }
    }
}

TreeSet类:采用的二叉树(红黑树)的方式存储,有序(大小顺序|自然顺序)。

* 原理:当向TreeSet容器添加元素时,会将当前元素的值与根节点/父节点的值进行比较,
* 如果比根节点/父节点的值大,保存在右子节点上。
* 如果比根节点/父节点的值小,保存在左子节点上。
* 优点:有序,查询速度比List要快(折半查找)。
* 常用的构造方法:
* TreeSet() 构造一个新的空 set,该 set 根据其元素的自然顺序进行排序。
* TreeSet(Comparator<? super E> comparator)构造一个新的空 TreeSet,它根据指定比较器进行排序。
* 常用的方法:
* add(Object o):添加元素
* remove(Object o):移除元素
* contains(Object o) 如果此 set 包含指定的元素,则返回 true。
* size():返回 set 中的元素数(set 的容量)。
* iterator():返回在此 set 中的元素上按升序进行迭代的迭代器
*/eg:

public class TestTreeSet {
    public static void main(String[] args) {
        Set<Integer> treeSet=new TreeSet<Integer>();
        treeSet.add(3);
        treeSet.add(13);
        treeSet.add(1);
        treeSet.add(20);
        //遍历:for-each
        for (Integer integer : treeSet) {
            System.out.println(integer);
        }
        System.out.println("--------------------");
        //遍历2:使用迭代器
        Iterator<Integer> iter = treeSet.iterator();
        while(iter.hasNext()){
            Integer i = iter.next();
            System.out.println(i);
        }
        
    }
}

总结:

* HashSet:采用的哈希表的方式进行存储,先调用hashCode()获取对象的hash码,
* 然后根据哈希码计算散列表的存储位置(索引),如果哈希码相同调用equals方法进行比较内容是否相同。
* TreeSet:采用的二叉树的方式进行存储,而二叉树添加节点是需要判断内容的大小,调用Comparable中compareTo方法
* 或Comparator中的compare方法比较内容的大小。 可以不重写hashCode和equals方法。
*
* TreeSet:使用元素的自然顺序对元素进行排序,
* 或者根据创建 set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。

Comparable和Comparator方法的重新,这章都不做详细的介绍了。

 

 

 

 

posted on 2017-06-14 22:25  助攻小分队  阅读(474)  评论(0)    收藏  举报

导航