java集合

Posted 未名胡

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java集合相关的知识,希望对你有一定的参考价值。

首先先截个图来看看集合所包含的类及接口:


Iterator接口                                                                                                                                                                                          

首先先了解Iterator迭代器接口

Collection 接口的iterator()方法返回一个 Iterator。Iterator接口方法能以迭代方式逐个访问集合中各个元素,并安全的从Collection 中除去适当的元素

方法:

boolean hasNext():判断是否存在另一个可访问的元素

Object next(): 返回要访问的下一个元素

remove():删除对象

/**
 * 迭代器的举例
 * @author hulin
 *
 */
public class IteratorDemo {
	public static void main(String[] args){  
	   List<String> list= new ArrayList<String>();  
	   		list.add("Hello");  
	   		list.add("你好!!");  
	   		list.add("World!!!");  
	    	Iterator<String> iter = list.iterator();  
	        while(iter.hasNext()){    //判断是否有内容  
	            System.out.println(iter.next());    //输出内容  
	        }  
	    }  
}
Hello
你好!!
World!!!


Collection接口:                                                                                                                                                                        

Collection的常见方法:

1,添加。

    boolean add(Object obj);

    boolean addAll(Collection coll);

2,删除。

    boolean remove(object obj);

    boolean remove(Collection coll);

    void clear();

3,判断:

    boolean contains(object obj);  

    boolean containsAll(Collection coll);

    boolean isEmpty();判断集合中是否有元素。

4,获取:

    int size();

    Iterator iterator();取出元素的方式,迭代器。

     该对象必须依赖于具体容器,因为每一个容器的数据结构不同。

    所以该迭代器对象是在容器中进行内部实现的。

    对于使用容器者而言,具体的实现不重要,只要通过容器获取到该实现的迭代器的对象即可。

    也就是iterator方法。

    Iterator接口就是对所有的Collection容器进行元素取出的公共接口。

5,其他:

    boolean retainAll(Collection coll);取交集。

    Object[]  toArray();将集合转成数组。

示例:

import java.util.ArrayList;
import java.util.Collection;

import javax.swing.text.html.HTMLDocument.Iterator;

public class IteratorDemo {

	public static void main(String[] args) {
		Collection coll=new ArrayList();
		coll.add("abc1");
		coll.add("abc2");
		coll.add("abc3");
		coll.add("abc4");
//		System.out.println(coll);
		//使用了Collection中的iterator方法。调用集合中的迭代器方法,是为了获取集合中的迭代器对象。
		Iterator it=coll.iterator();
//		while(it.hasNext()){
//			System.out.println(it.next());
//		}
		for(Iterator it=coll.iterator();it.hasNext();){//开发写这个
			System.out.println(it.next());
		}
//		System.out.println(it.next());//abc1
//		System.out.println(it.next());//abc2
//		System.out.println(it.next());//abc3
//		System.out.println(it.next());//abc4
//		System.out.println(it.next());//java.utilNoSuchElementException

	}

}

List和Set的特点

Collection

       |--List:有序(存入和取出的顺序一致),元素都有索引(角标),元素可以重复。

       |--Set:元素不能重复,无序。

List集合                                                                                                                                                                                        

List 接口继承了 Collection 接口以定义一个允许重复项的有序集合。该接口不但能够对列表的一部分进行处理,还添加了面向位置的操作。

List:特有的常见方法:有一个共性特点就是都可以操作角标。

1,添加

    void  add(index,element);

    void  add(index,collection);

2,删除

    Object  remove(index);

3,修改

    Object  set(index,element);

4,获取:

    Object  get(index);

    int indexOf(object);

    int lastIndexOf(object);

    List  subList(from,to);

list集合是可以完成对元素的增删改查。

示例:

public class ListDemo {
	public static void main(String[] args) {
		List list=new ArrayList();
		show(list);
	}
	public static void show(List list) {
		//添加元素
		list.add("abc1");
		list.add("abc2");
		list.add("abc");
		System.out.println(list);//[abc1, abc2, abc]
		//插入元素。
		list.add(1,"abc9");
		System.out.println(list);//[abc1, abc9, abc2, abc]
		//删除元素
		System.out.println("remove:"+list.remove(2));//remove:abc2
		System.out.println(list);//[abc1, abc9, abc]
		//修改元素
		System.out.println("set:"+list.set(1,"abc8"));//set:abc9
		System.out.println(list);//[abc1, abc8, abc]
		//获取元素
		System.out.println("get:"+list.get(0));//get:abc1
		//获取子列表
		System.out.println("sublist:"+list.subList(1, 2));//sublist:[abc8]

	}

}

ListIterator接口

public class ListDemo2 {

	public static void main(String[] args) {
		List list=new ArrayList();
//		show(list);
		
		list.add("abc1");
		list.add("abc2");
		list.add("abc3");
		System.out.println("list:"+list);//list:[abc1, abc2, abc3]
		
		
		ListIterator it=list.listIterator();//获取列表迭代器对象
		//它可以实现在迭代过程中完成对元素的增删改查。
		//注意:只有list集合具备该迭代功能。
		while(it.hasNext()){
			Object obj=it.next();
			if(obj.equals("abc2")){
				it.add("abc9");
			}
		}
		System.out.println("list:"+list);//list:[abc1, abc2, abc9, abc3]
		
		System.out.println("hasNext:"+it.hasNext());//hasNext:false
		System.out.println("hasPrevious:"+it.hasPrevious());//hasPrevious:true
		
		while(it.hasPrevious()){
			System.out.println("previous:"+it.previous());//previous:abc3  previous:abc9 previous:abc2 previous:abc1
		}
//		public boolean add(Object obj){
			
//		}
		/*
		Iterator it=list.iterator();
		while(it.hasNext()){
			Object obj=it.next();// java.util.ConcurrentModificationException
								//在迭代器过程中,不要使用集合操作元素,容易出现异常。
								//可以使用iterator接口的子接口ListIterator来完成在迭代中对元素进行更多的操作。
			if(obj.equals("abc2")){
				list.add("abc9");
			}
			else
			System.out.println("it.next()"+obj);
		}
		System.out.println(list);
	*/
	}

	public static void show(List list) {
		list.add("abc1");
		list.add("abc2");
		list.add("abc3");
		list.add("abc4");
		
		Iterator it=list.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}
		//list特有的取出元素方式之一。
		for(int x=0;x<list.size();x++)
		System.out.println("get:"+list.get(x));
	}

}

List常用子类的特点

list集合是可以完成对元素的增删改查。

(数据结构)

List:

         |--Vector:内部是数组数据结构,是同步的。增删查询都很慢。

         |--ArrayList:内部是数组数据结构,是不同步的,替代了Vector。查询速度快。

         |--LinkedList:内部是链表数据结构,是不同步的。增删元素的速度很快。

数组和链表:



Vector集合

内部是数组数据结构,是同步的。增删查询很慢。少用

public class VectorDemo {
	public static void main(String[] args) {
		Vector v=new Vector();
		v.addElement("abc1");
		v.addElement("abc2");
		v.addElement("abc3");
		v.addElement("abc4");
		
		Enumeration en=v.elements();
		while(en.hasMoreElements()){
			System.out.println("nextelment:"+en.nextElement());
		}
		Iterator it=v.iterator();
		while(it.hasNext()){
			System.out.println("next:"+it.next());
		}
	}

}
nextelment:abc1
nextelment:abc2
nextelment:abc3
nextelment:abc4
next:abc1
next:abc2
next:abc3
next:abc4  

LinkedList集合

内部是链表结构,是不同步的,增删元素的速度很快

方法:

void addFirst(Object o):将对象o添加到列表的开头

void addLast(Object o):将对象o添加到列表的结尾

Object getFirst():返回列表开头的元素

Object getLast(): 返回列表结尾的元素

Object removeFirst():删除并且返回列表开头的元素

Object removeLast():删除并且返回列表结尾的元素

LinkedList(): 构建一个空的链接列表

LinkedList(Collection c)构建一个链接列表,并且添加集合c的所有元素

public class LinkedListDemo {
	public static void main(String[] args) {
		LinkedList link=new LinkedList();
		link.addFirst("abc1");
		link.addFirst("abc2");
		link.addFirst("abc3");
		link.addFirst("abc4");
		System.out.println(link);
		
//		System.out.println(link.getFirst());//获取第一个元素但不删除
//		System.out.println(link.getFirst());
		
		System.out.println(link.removeFirst());//获取第一个元素但是会删除
		System.out.println(link.removeFirst());
		
		while(!link.isEmpty()){
			System.out.println(link.removeFirst());//[]
		}
			
			
		System.out.println(link);
		
		
//		Iterator it=link.iterator();
//		while(it.hasNext()){
//			System.out.println(it.next());
		}
	}

LinkedList集合-练习(堆栈和队列)

LinkedList:

        addFirst():

        addLast():

    jdk1.6

         offerFirst():

         offerLast():

         getFirst()://获取但不移除,如果链表为空,抛出NoSuchElementException

         getLast():

    jdk1.6

         peekFirst()://获取但不移除,如果链表为空,返回null.

         peekLast():

         removeFirst()://获取并移除,如果链表为空,抛出NoSuchElementException

         removeLast():

    jdk1.6

         pollFirst()://获取并移除,如果链表为空,返回null.

         pollLast():

ArrayList

内部是数组数据结构,是不同步的,代替了Vector。查询速度快

方法:(由于继承的是List,所以List的方法也适用,这里不多举例)

void ensureCapacity(int minCapacity):将ArrayList对象容量增加minCapacity

void trimToSize():整理ArrayList对象容量为列表当前大小。程序可使用这个操作减少ArrayList对象存储空间

public class Person {
	private String name;
	private int age;
	
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
}
public class ArrayListTest {
	public static void main(String[] args) {
		Person p1=new Person("lisi1",21);
		ArrayList a1=new ArrayList();
		a1.add(p1);
		a1.add(new Person("lisi2",22));
		a1.add(new Person("lisi3",23));
		a1.add(new Person("lisi4",24));
		
		Iterator it=a1.iterator();
		while(it.hasNext()){
//			System.out.println(((Person)it.next()).getName());
			Person p=(Person) it.next();
			System.out.println(p.getName()+"----"+p.getAge());
		}
//		a1.add(5);//a1.add(new Integet(5));
//		show(6);
	}

//	public static void show(Integer num) {//Object num=new Integer(6);//当基本数据类型值 与引用数据类型时  自动装箱
		
//		int x=num+8;//拆箱
//	}

}
Set接口                                                                                                                                                                                          
Set 接口继承 Collection 接口,而且它不允许集合中存在重复项,每个具体的 Set 实现类依赖添加的对象的 equals()方法来检查独一性。
Set接口没有引入新方法,所以Set就是一个Collection,只不过其行为不同。

Hash表是一种数据结构,用来查找对象。Hash表为每个对象计算出一个整数,称为Hash Code(哈希码)。

Hash表是个链接式列表的阵列。每个列表称为一个buckets(哈希表元)。

对象位置的计算 index = HashCode % buckets (HashCode为对象哈希码,buckets为哈希表元总数)。
当你添加元素时,有时你会遇到已经填充了元素的哈希表元,这种情况称为Hash Collisions(哈希冲突)。这时,你必须判断该元素是否已经存在于该哈希表中。
如果哈希码是合理地随机分布的,并且哈希表元的数量足够大,那么哈希冲突的数量就会减少。同时,你也可以通过设定一个初始的哈希表元数量来更好地控制哈 希表的运行。初始哈希表元的数量为 buckets = size * 150% + 1 (size为预期元素的数量)。
如果哈希 表中的元素放得太满,就必须进行rehashing(再哈希)。再哈希使哈希表元数增倍,并将原有的对象重新导入新的哈希表元中,而原始的哈希表元被删 除。load factor(加载因子)决定何时要对哈希表进行再哈希。在Java编程语言中,加载因子默认值为0.75,默认哈希表元为101。

HashSet
       |-----LinkedHashSet:LinkedHashSet的迭代器按照元素的插入顺序来访问各个元素。

方法:

   HashSet():构建一个空的哈希集

   HashSet(Collection c):构建一个哈希集,并且添加集合c中所有元素

   HashSet(int initialCapacity):构建一个拥有特定容量的空哈希集

    HashSet(int initialCapacity, float loadFactor):构建一个拥有特定容量和加载因子的空哈希集。LoadFactor是0.0至1.0之间的一个数

/**
 * HashSet实例
 * @author hulin
 *
 */
public class HashSetDemo {
	  public static void main(String[] args) {  
	        HashSet<String>  has=new HashSet<String>();  
	        has.add("1");  
	        has.add("1");  
	        has.add("2");  
	        has.add("3");  
	        has.add("4");  
	        has.add("2");  
	        Iterator<String>  it=has.iterator();   
	        while (it.hasNext()) {  
	            System.out.print(it.next()+" ");     
	        }  
	    }  
}
LinkedHashSet

LinkedHashSet的迭代器按照元素的插入顺序来访问各个元素。

/**
 * LinkedHashSet的实例
 * @author hulin
 *
 */
public class LinkedHashSetDemo {
	public static void main(String[] args) {
		LinkedHashSet<Integer> set = new LinkedHashSet<Integer>();
	     set.add(2);
	     set.add(4);
	     set.add(1);	      
	     Iterator<Integer> iter = set.iterator();      
	     System.out.println(set.isEmpty());
	     System.out.println(set.size());
	     System.out.println(set.contains(2));
	     System.out.println(set.remove(2));
	     set.clear();
	}
	
}
false
3
true
true
TreeSet

树集集合

方法:

TreeSet():构建一个空的树集

TreeSet(Collection c):构建一个树集,并且添加集合c中所有元素

TreeSet(Comparator c):构建一个树集,并且使用特定的比较器对其元素进行排序

/**
 * TreeSet的实例
 * @author hulin
 *
 */
public class TreeSetDemo {
	public static void main(String[] args) {
		TreeSet ts = new TreeSet(); 
		ts.add("张三");
		ts.add("李四");
		ts.add("王五");
		Iterator it=ts.iterator();
		while(it.hasNext()){
			System.out.print(it.next()+" ");
		}
	}
}
张三 李四 王五 

Map接口                                                                                                                                                                             

Map接口不是Collection接口的继承。Map接口用于维护键/值对(key/value pairs)。该接口描述了从不重复的键到值的映射。

方法:

(1) 添加、删除操作

Object put(Object key, Object value):将互相关联的一个关键字与一个值放入该映像。如果该关键字已经存在,那么与此关键字相关的新值将取代旧值。方法返回关键字的旧值,如果关键字原先并不存在,则返回null

Object remove(Object key):从映像中删除与key相关的映射

 void putAll(Map t): 将来自特定映像的所有元素添加给该映像

void clear():从映像中删除所有映射

(2) 查询操作

 Object get(Object key): 获得与关键字key相关的值,并且返回与关键字key相关的对象,如果没有在该映像中找到该关键字,则返回null

 boolean containsKey(Object key):判断映像中是否存在关键字key

boolean containsValue(Object value):判断映像中是否存在值value

 int size():返回当前映像中映射的数量

boolean isEmpty():判断映像中是否有任何映射

(3) 视图操作 :处理映像中键/值对组

Set keySet():返回映像中所有关键字的视图集(因为映射中键的集合必须是唯一的,用Set支持。还可以从视图中删除元素,同时,关键字和它相关的值将从源映像中被删除,但是不能添加任何元素)

Collection values():返回映像中所有值的视图集(“因为映射中值的集合不是唯一的,用Collection支持。还可以从视图中删除元素,同时,值和它的关键字将从源映像中被删除,但是不能添加任何元素)

Set entrySet(): 返回Map.Entry对象的视图集,即映像中的关键字/值对(“因为映射是唯一的,用Set支持。还可以从视图中删除元素,同时,这些元素将从源映像中被删除,但是不能添加任何元素)

HashMap类

使用HashMap要求添加的键类明确定义了hashCode()和 equals()的实现。
在Map 中插入、删除和定位元素,HashMap 是最好的选择。
但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好(下面讲到)

方法:

HashMap():构建一个空的哈希映像

 HashMap(Map m):构建一个哈希映像,并且添加映像m的所有映射

HashMap(int initialCapacity):构建一个拥有特定容量的空的哈希映像

HashMap(int initialCapacity, float loadFactor):构建一个拥有特定容量和加载因子的空的哈希映像

public class HashMapDemo {
	   
	 public static void main(String[] args){  
	  HashMap<String,Object> hm=new HashMap<String,Object>();  
	  People p1=new People();  
	  People p2=new People();  
	  People p3=new People();  
	  People p4=new People();  
	  hm.put("People3", p1);  
	  hm.put("People1", p2);  
	  hm.put("People4", p3);  
	  hm.put("People2", p4);    	    
	  Iterator<String> it=hm.keySet().iterator();  
	    
	  while(it.hasNext()){  
	   System.out.println(it.next());  
	  }    
	 }  
	}  
	class People {  
	 private String name;  
	 private int age;  
	 public int getAge() {  
	  return age;  
	 }  
	 public void setAge(int age) {  
	  this.age = age;  
	 }  
	 public String getName() {  
	  return name;  
	 }  
	 public void setName(String name) {  
	  this.name = name;  
	 }  
}
People1
People2
People3
People4	
	
 LinkedHashMap类

LinkedHashMap扩展HashMap,以插入顺序将关键字/值对添加进链接哈希映像中。象LinkedHashSet一样,LinkedHashMap内部也采用双重链接式列表。

方法:

 LinkedHashMap():构建一个空链接哈希映像

LinkedHashMap(Map m):构建一个链接哈希映像,并且添加映像m中所有映射

LinkedHashMap(int initialCapacity): 构建一个拥有特定容量的空的链接哈希映像

 LinkedHashMap(int initialCapacity, float loadFactor):构建一个拥有特定容量和加载因子的空的链接哈希映像

 LinkedHashMap(int initialCapacity, float loadFactor,boolean accessOrder): 构建一个拥有特定容量、加载因子和访问顺序排序的空的链接哈希映像

protected boolean removeEldestEntry(Map.Entry eldest):如果你想删除最老的映射,则覆盖该方法,以便返回true。当某个映射已经添加给映像之后,便调用该方法。它的默认实现方法返回false,表示默认条件 下老的映射没有被删除。但是你可以重新定义本方法,以便有选择地在最老的映射符合某个条件,或者映像超过了某个大小时,返回true。

TreeMap类

TreeMap没有调优选项,因为该树总处于平衡状态。
在Map 中插入、删除和定位元素,HashMap 是最好的选择。
但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好

方法:

TreeMap():构建一个空的映像树

TreeMap(Map m):构建一个映像树,并且添加映像m中所有元素

TreeMap(Comparator c): 构建一个映像树,并且使用特定的比较器对关键字进行排序

TreeMap(SortedMap s):构建一个映像树,添加映像树s中所有映射,并且使用与有序映像s相同的比较器排序

/**
 * TreeMap实例
 * @author hulin
 *
 */
public class TreeMapDemo {
	 public static void main(String[] args) throws Exception {

	        // 逆序
	        TreeMap<String, String> treeMap = new TreeMap<String, String>(
	                Collections.reverseOrder());
	        treeMap.put("aaa","aaa");
	        treeMap.put("bbb","bbb");
	        treeMap.put("ccc","ccc");
	        treeMap.put("ddd","ddd");
	        treeMap.put("eee","eee");
	        treeMap.put("fff","fff");
	        Iterator<String> iter = treeMap.keySet().iterator();
	        while (iter.hasNext()) {
	            Object key = iter.next();
	            Object value = treeMap.get(key);
	            System.out.print("K: " + key);
	            System.out.println("V: " + value);
	        }

	        System.out.println("======================");
	        Iterator<?> it1 = treeMap.entrySet().iterator();
	        while (it1.hasNext()) {
	            System.out.println(it1.next());
	        }
	    }
}
K: fffV: fff
K: eeeV: eee
K: dddV: ddd
K: cccV: ccc
K: bbbV: bbb
K: aaaV: aaa
======================
fff=fff
eee=eee
ddd=ddd
ccc=ccc
bbb=bbb
aaa=aaa


以上是关于java集合的主要内容,如果未能解决你的问题,请参考以下文章

Java Review (二十集合----- Iterator接口)

Java集合框架Iterable接口

Java自用Java集合-Iterator迭代器接口(为容器而生)

Java的集合Iterator迭代器

7.2 Java 11新增的Collection和Iterator接口

java集合