java中的容器类和接口总结(一):Set

    Collection接口

API文档中的描述是:public interface Collection<E> extends Iterable<E>.
Collection是一个接口,是高度抽象出来的集合,它包含了集合的基本操作和属性。

    常用的方法

boolean add(E e);//向容器中添加指定的元素
Iterator<E> iterator();//返回能够遍历当前集合中所有元素的迭代器
boolean contains(Object o);//判断容器中是否包含指定的元素
boolean remove(Object o);//删除容器中的元素o,如果容器中包含o,返回true
int size();//返回容器中元素的个数
Object[] toArray();//返回包含此容器中所有元素的数组

  • Set接口

Set顾名思义为集合,即不允许出现相同的元素。由于其内部存储结构的特点,不区分元素的顺序。

  • HashSet

实现了Set接口的类,内部使用HashMap来存储数据,数据存储在HashMap的key中,value都是同一个默认值。HashSet有四种构造方法:

HashSet( ):构造一个空的Set,底层HashMap实例的默认初始容量为16,装载因子是0.75

HashSet(Collection<? extends E> c):构造一个包含指定collection中的元素的新Set

HashSet(int initialCapacity):构造一个指定初始容量和默认装载因子0.75的新Set

HashSet(int initialCapacity, float loadFactor):构造一个指定容量和指定装载因子的新的Set

import java.util.*;
public class HashTest {
	@SuppressWarnings("unchecked")
	public static void main(String[] args){
		HashSet hashSet1 = new HashSet();
		hashSet1.add(1);
		hashSet1.add("abc");
		hashSet1.add("abc");
		int[] arr = new int[]{1,2,3};
		hashSet1.add(arr);
		HashTest ht = new HashTest();
		Apple apple1 = ht.new Apple();
		hashSet1.add(apple1);
		Iterator it = hashSet1.iterator();
		System.out.println(hashSet1.size());
		while(it.hasNext()){
			Object ob = it.next();
			if(ob instanceof Integer)
				System.out.println("Integer:" + ob);
			if(ob instanceof String)
				System.out.println("String:" + ob);
			if(ob instanceof Apple)
				System.out.println("Apple:" + ob);
			if(ob instanceof int[]){
				System.out.print("int[]:");
				System.out.println(Arrays.toString(arr));
			}
		}
	}
	public class Apple{
		static final int id = 1;

		@Override
		public String toString() {
			return "Apple " + id;
		}
		
	}
}

输出结果:

4
Integer:1
String:abc
int[]:[1, 2, 3]

Apple:Apple 1

  • LinkedHashSet

LinkedHashSet继承自HashSet,唯一的区别是LinkedHashSet内部使用的是LinkHashMap。这样做的意义或者好处就是LinkedHashSet中的元素顺序是可以保证的,也就是说遍历序和插入序是一致的。类HashSet和LinkedHashSet都是接口Set的实现,两者都不能保存重复的数据。主要区别是HashSet不保证集合中元素的顺序,即不能保证迭代的顺序与插入的顺序一致。而LinkedHashSet按照元素插入的顺序进行迭代,即迭代输出的顺序与插入的顺序保持一致。

如将上面例程稍作修改,对于HashSet:

import java.util.*;
public class HashTest {
	@SuppressWarnings("unchecked")
	public static void main(String[] args){
		HashSet hashSet1 = new HashSet();
		//hashSet1.add(1);
		hashSet1.add("abc");
		hashSet1.add("abc");
		int[] arr = new int[]{1,2,3};
		//hashSet1.add(arr);
		hashSet1.add(1);
		HashTest ht = new HashTest();
		Apple apple1 = ht.new Apple();
		hashSet1.add(apple1);
		hashSet1.add(arr);
		Iterator it = hashSet1.iterator();
		System.out.println(hashSet1.size());
		while(it.hasNext()){
			Object ob = it.next();
			if(ob instanceof Integer)
				System.out.println("Integer:" + ob);
			if(ob instanceof String)
				System.out.println("String:" + ob);
			if(ob instanceof Apple)
				System.out.println("Apple:" + ob);
			if(ob instanceof int[]){
				System.out.print("int[]:");
				System.out.println(Arrays.toString(arr));
			}
		}
	}
	public class Apple{
		static final int id = 1;

		@Override
		public String toString() {
			return "Apple " + id;
		}
		
	}
}

输出为:

4
Integer:1
String:abc
Apple:Apple 1

int[]:[1, 2, 3]

可见迭代顺序与插入顺序不一致

然后仅仅将

HashSet hashSet1 = new HashSet(); 改为:LinkedHashSet hashSet1 = new LinkedHashSet();

输出结果变为:

4
String:abc
Integer:1
Apple:Apple 1
int[]:[1, 2, 3]

与插入顺序一致!

  • SortedSet    TreeSet

SortedSet:

    1) 顾名思义就是有序的Set,但是它的有序和LinkedHashSet不一样,LinkedHashSet维护的是插入时的顺序,而SortedSet维护的是元素之间大小关系的顺序(比如升序、降序等,是根据大小关系来维护顺序的);

    2) 这种维护是时刻维护的(就跟堆维护堆序一样),每次插入元素的时候就会根据其大小放入合适的位置,删除一个元素后也会调整剩余元素的位置使之符合升序/降序状态;

    3) SortedSet的实现类不多,基本只会用TreeSet这个实现类,之所以叫TreeSet,是因为它使用红黑树实现的,因此内部是一个树的结构

TreeSet:

实现Set 接口,该接口由TreeMap 实例支持。此类保证排序后的 set 按照升序排列元素, 根据使用的构造方法不同,可能会按照元素的自然顺序 进行排序(参见 Comparable),或按照在创建 set 时所提供的比较器进行排序。四种构造方法:

TreeSet()
Constructs a new, empty tree set, sorted according to the natural ordering of its elements.
TreeSet(Collection<? extends E> c)
Constructs a new tree set containing the elements in the specified collection, sorted according to the  natural ordering of its elements.
TreeSet(Comparator<? super E> comparator)
Constructs a new, empty tree set, sorted according to the specified comparator.
TreeSet(SortedSet<E> s)
Constructs a new tree set containing the same elements and using the same ordering as the specified sorted set.

注意1:允许 null 元素.
注意2:实现不同步的,不是线程安全的。
注意3:TreeSet 实例将使用其 compareTo(或 compare)方法执行所有的键比较,
 认为两个对象的键相等就表示它们两个对象是相等的。它违背了 Set 接口的常规协定。
注意4:此类的iterator方法返回的迭代器是快速失败 的:在创建迭代器之后,如果对集合进行修改,
 除非通过迭代器自身的 remove 方法,否则在任何时间以任何方式对其进行修改,
 Iterator 都将抛出 ConcurrentModificationException
注意5:iterator()返回的迭代器,里面的元素是以升序排序的.
注意6:当试图添加一个重复元素到TreeSet时,新元素并不会把旧元素替换掉,
 而只是新元素不会添加到TreeSet(不会抛异常。)

注意7:TreeSet用了一种叫红黑树的数据结构【red-black tree data structure】来为元素排序,

例程:

import java.util.Comparator;
import java.util.Random;
import java.util.TreeSet;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
public class Test2 {
 /**
  * @param args
  */
 public static void main(String[] args) {
  PeopleComparator comparator=new PeopleComparator(); 
  TreeSet<People> set=new TreeSet(comparator);
  set.add(new People("robin",1,21));
  set.add(new People("hb",2,20));
  set.add(new People("harry",9,30));
  set.add(null);
  People p4=new People("robin",4,25);
  set.add(p4);
  set.add(new People("yp",5,28));
  set.add(new People("yp2",8,28));
  for(People p:set)
   System.out.println(p);
 }
}
class People{
	String name;
	int id;
	int age;
	public People(String name,int id){
		this(name,id,0);
	}
	public People(String name,int id,int age){
		this.name=name;
		this.id=id;
		this.age=age;
	}
	public String toString(){
		return id+name+age;
	}
}
class PeopleComparator implements Comparator<People>
{
 @Override
 public int compare(People p0, People p1) {
  if(p0==p1)
   return 0;
  if(p0!=null&&p1==null)
   return 1;
  else if(p0==null&&p1!=null)
   return -1;
  if (p0.id>p1.id)
   return 1;
  else if (p0.id<p1.id)
   return -1;
  else
  return 0;
 }
}

输出结果:

null
1robin21
2hb20
4robin25
5yp28
8yp228
9harry30

猜你喜欢

转载自blog.csdn.net/u010183728/article/details/79679439
今日推荐