-->

Java集合类——2017.08.05

2020-10-31 09:23发布

一 Java集合类

是什么?干什么用?是一种工具类,可用于储存数量不等的对象,可以实现常见的数据结构。

有什么东西?主要是四大类Set、List、Queue、Map四种体系

集合类与数组类的区别?集合类只能保存对象,数组元素即可以保存基本数据类型,又可以保存对象。

Set:无序、不可重复的集合

List:有序,可重复的集合

Queue:队列

Map:具有映射关系的集合

这四个都是集合类的接口,其中Set、List、Queue是Collection的子接口,Map是一个接口

 

Iterator和Iterable的区别?

Iterable是接口,从JDK1.1就开始存在,Iterator是也是接口从JDK1.2开始。Iterable是超级接口,Collection和Map都继承它,而Iterator主要是迭代接口,有三个主要方法分别是hasNext():如果仍有元素可以迭代,返回true。next():返回迭代的下一个元素。remove():从迭代器指向collection中移除迭代器返回的最后一个元素。JDK1.8之前,Iterable接口里面只有一个方法:生成iterator()。可以理解为Iterable是Iterator的父类。

 

二 Set集合

Set集合是什么:类似一个罐子,无序、不可重复。不能保证装入的顺序是否一致,接口都这样定义了,所以实现类HashSet、TreeSet、LinkedSet、EnumSet等都遵循这个规律。

HashSet是Set的典型实现类具有以下特点:1 不能保证元素的排列顺序 2HashSet是不同步的 3集合元素的值可以是null。储存原理:向HashSet集合中存入一个元素,HaseSet会调用该对象的hascode()方法,根据hasCode值来存储该对象的位置。注意两个或两个以上的元素通过equals()方法比较返回true,但他们的hascCode()如果不同的化,HashSet集合也是可以储存的。

概括为:HashSet()判断两个对象的标准有两个:1 equals()方法 2hashCode值

 

LinkedHashSet

根据集合元素的hashCode值来决定元素的存储位置,并提供链表来维护元素的次序。元素是以插入的顺序保存,但是性能降低了.

package CollectionTest;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Set;

public class CollectionTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Collection c=new ArrayList();
		
		//添加元素
		c.add(6);
		c.add("孙悟空");
		c.add("田建科");
		c.add("高婕");
		c.add("林景佳");
		c.remove(6);
	
		//如何遍历集合元素
		//1 使用增强for
		for(Object c1:c)
		{
			System.out.println(c1);
			
		}
		System.out.println("----------------");
		
		//使用迭代器Iterator
		//使用的是Iterator<T>:iterator()
		Iterator it=c.iterator();
		//判断迭代器里面是否有元素
		while(it.hasNext())
		{
		//将容器里面的元素打印出来
			System.out.println(it.next());
		}
		
		System.out.println("----------------");
		//HashSet的常见方法
	    Set s1=new HashSet();
	    //add()方法
	    s1.add("tian");
	    s1.add("jian");
	    s1.add("ke");
	    //size()方法,此处的size()方法只显示3个大小
	    System.out.println(s1.size());
	    
	    //remove()方法
	    s1.remove("tian");
	    System.out.println(s1.size());
	    
	    //迭代器遍历与增强for循环
	    Iterator it1=s1.iterator();
	    while(it1.hasNext())
	    {
	    	System.out.println(it1.next());
	    }
	    
	    for(Object ob1:s1)
	    {
	    	System.out.println(ob1);
	    }
	    		
	  //LinkedHashSet类
	    LinkedHashSet  L1=new LinkedHashSet();
	    L1.add("fengkuang");
	    L1.add("fengk2");
	    System.out.println(L1);
	    
	    		
		
	

	}

}

  

TreeSet

是SortedSet接口的实现类,能够让元素处于排序状态。为什么能够实现排序状态呢?因为实现了Comparable接口,Comparable接口里面只有一个方法就是compareTo()方法来比较元素之间的关系。

排序的几种方式?1自然排序:按照自然升序方式

2定制排序:想要实现自己的想法进行排序,此时就是定制排序,通过Comparator接口帮助,这个接口里面有一个compare()方法

package CollectionTest;

import java.util.TreeSet;

public class TreeSetTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		TreeSet  ts1=new TreeSet();
		ts1.add("kobe");
		ts1.add("durant");
		ts1.add("james");
		ts1.add("westbooks");
		ts1.add("duran");
		System.out.println(ts1);
		//[duran, durant, james, kobe, westbooks]
		
		for(Object oj:ts1)
		{
			System.out.println(oj);
		}
		
		

	}

}

 

EnumSet类

是枚举类设计的集合类,EnumSet中的所有的元素必须是指定枚举类型的枚举值,也是有顺序的,只不过这个顺序是以枚举值在Enum类内的定义顺序来决定集合元素的顺序。

package CollectionTest;

import java.util.EnumSet;

enum Season
 {
   Spring,Summer,Fall,Winner	 
 }
     

public class EnumTest {

	public static void main(String[] args) {
		
		EnumSet es1=EnumSet.allOf(Season.class);
		EnumSet es2=EnumSet.noneOf(Season.class);
		
		
		System.out.println(es1);
		System.out.println(es2);
		
		
		

	}

}

 

        Set实现类型的性能分析

        HashSet的性能是最好的,TreeSet需要红黑树算法来维护集合元素的次序,只要需要保持排序的Set才需要用到。LinkedHashSet是通过链表和哈希表来维护的,通过链表来维护插入的顺序。EnumSet是Set性能中最好的,但它只能同时保存同一个枚举类的枚举值作为集合元素。Set的三个实现类HashSet、TreeSet和EnumSet都是线程不安全的,如果要保证线程安全需要通过Collections工具类的synchronizedSortedSet方法来"包装"该Set集合。

 

三 List集合

是什么?干什么用?代表有序、可重复的集合。可以按照添加顺序记录索引元素。

如何判断两个对象的方法是equals()方法。

package CollectionTest;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class ListIteratorTest {

	public static void main(String[] args) {
	      String[ ] books={"tian","jian","ke","feng"};
	      //上面是一个数组,如何加入List中呢
	      List l1=new ArrayList();
	      for( String  s :books)
	      {
	    	  l1.add(s);
	      }
	      ListIterator list1=l1.listIterator();
	      
	      while(list1.hasNext())
	      {
	    	  System.out.println(list1.next());
	    	  list1.add("------");
	      }
	      System.out.println("-----分隔符------");
	      while(list1.hasPrevious())
	      {
	    	  System.out.println(list1.previous());
	      }
	      /*
	       * tian
			 jian
			 ke
             feng
			 -----分隔符------
             ------
             feng
             ------
			 ke
			 ------
			 jian
			 ------
			 tian
	       */

	}

}

 

ArrayList和Vector的异同?

相同:二者都是List的实现类,二者都用了initalCapacity来指定容器的初始大小,二者都可以通过ensureCapacity(int minCapacity)来容纳最小参数所指定的元素数。

不同:Vector是一个古老的集合从JDK1开始,而ArrayList从JDK2开始 ,线程安全上来说,Vector是线程安全的,所以性能略低,ArrayList是线程不安全,性能高。Stack是Vector的一个子类,用于模拟"栈"这种数据结构,栈是一种"后进先出"(LIFO)的容器,可以这样形象打个比喻,后面进栈的把前面推出来,但是进栈出栈的都是Object对象。栈也是线程安全,因此性能比较低。

package CollectionTest;


import java.sql.Array;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;
import java.util.Vector;

public class ArrayList {

	public static void main(String[] args) {
        List v1=new Vector();
        v1.add("tianjianke");
        v1.add(0,1);
        System.out.println(v1.size());
        //2
        
        //使用Arrays的asList(Object...aaa)方法
        List fixedlist=Arrays.asList("tianjian","ke","wudi","tianxia");
      for(int i=0;i<fixedlist.size();i++)
      {
    	  System.out.println(fixedlist.get(i));
      }
        
      
     Stack S1=new Stack();
     S1.add("asdfa");
     S1.add("sxdaf");
     System.out.println(S1);
     S1.pop();
     System.out.println(S1);
//     2
//     tianjian
//     ke
//     wudi
//     tianxia
//     [asdfa, sxdaf]
//     [asdfa]

     

	}

}

LinkeList:

 

四 Queue集合

是什么?干什么用?是一种先进先出的集合,实现Queue(队列)这种数据结构,队列是怎么样的数据结构呢?一种特殊的线性表,只允许在表的front端进行删除操作,在表的rear端进行插入操作。

Queue接口定义了几个方法:1 add()与offer()添加元素   2  element()与peek()获取队列头部元素  3 poll()与remove()获取队列头部元素并删除

PriorityQueue:

package CollectionTest;

import java.util.PriorityQueue;

public class Queue {

	public static void main(String[] args) {

		
		//PriorityQueue(优先队列):保存的并不是队列的插入顺序,而是安装插入元素的大小顺序进行排序
		PriorityQueue q1=new PriorityQueue();
		q1.add("tianjianke");
		q1.add("fengkuang");
		q1.add("mengnong");
		q1.add("okc");
		System.out.println(q1);
		System.out.println(q1.peek());
		System.out.println(q1);
		q1.remove();
		q1.poll();
		System.out.println(q1);
		
		
//		[fengkuang, okc, mengnong, tianjianke]
//				fengkuang
//				[fengkuang, okc, mengnong, tianjianke]
//				[okc, tianjianke]
	}

}

ArrayDeque类:既可以当做双端队列也可以当做栈来实现,是一种实现类。

package CollectionTest;

import java.util.ArrayDeque;

public class ArrayDequeStack {

	public static void main(String[] args) {
		ArrayDeque stack=new ArrayDeque();
		//讲元素推进去
		stack.push("tian");
		stack.add("jianke");
		stack.add("meidi");
		System.out.println(stack);
		System.out.println(stack.peek());
		System.out.println(stack.poll());
		System.out.println(stack);

	}

}

 

各种Queue性能分析:ArrayDeque是双端队列也是栈,PriorityQueue是比较典型的Queue实现类,只不过按照元素大小属性进行排序,LinkeList即实现了List接口又实现了Deque接口,即是双端队列又是列表。

 

五 Map集合

        是什么?干什么用?Map是一种接口,用于保存具有映射关系的数据。一组值用于保存key,一组值保存value,key和value是一一对映的关系,其中Map中的key不允许重复,即同一个Map对象的任何两个key通过equals方法总是返回false。如果单独来看的,key基本组成了set集合。将Map中的value放在一起来看,那么就相当于List。

        比较一下Map和Set的区别?其实在Java底层代码,Java是先实现了Map,然后讲Map中的value通过全部赋为null,那么此时Map就变成了Set。

package CollectionTest;

import java.util.HashMap;
import java.util.Map;

public class MapTest {

	public static void main(String[] args) {
		
		Map map=new HashMap<>();
		map.put("疯狂",2);
		map.put("疯狂1",2);
		map.put("疯狂2",2);
		map.put("疯狂3",4);
		System.out.println(map);
		System.out.println(map.get("疯狂"));
		System.out.println(map.hashCode());
		map.remove("疯狂3");
		System.out.println(map);

	}

}

 

HashMap与Hashtable的区别?

Hashtable是从JDK1就开始出现,HashMap从JDK2开始,Hashtable是线程安全的,HashMap是线程不安全的。

Hashtable不允许使用null作为key和value值,否则会引发NullPointerException异常;但HashMap可以使用null作为key或value(注意此处的有个陷阱,HashMap能否用两个null作为key值,答案是否定的,因为HashMap里面的key值不能重复)。

 

Map的性能分析

      虽然HashMap和Hashtable来说,Hashtable是线程安全的,HashMap是线程不安全的,HashMap性能高于Hashtable,TreeMap采用了红黑树,能够对内部排好序,如果对Map的排序顺序有要求,可以使用TreeMap。LinkedHashMap的性能呢比HashMap要低,因为采用了链表来维护Map中key-value的添加属性。EnumMap性能最好。

 

标签: