JAVA从入门到进阶(九)——集合类框架基础二

续…集合类框架基础一
三 Set集合
特点:元素不重复,存入的元素无序。
1.1.HashSet 内部由哈希表实现,无序,需要重写hashcode方法和equal方法,来确保存入对象的唯一性。是不同步的。
Example

class Box
{
	private int data;
	private String name;
	public Box() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Box(int data, String name) {
		super();
		this.data = data;
		this.name = name;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + data;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Box other = (Box) obj;
		if (data != other.data)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	public int getData() {
		return data;
	}
	public void setData(int data) {
		this.data = data;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}
public class HashSetdemo2 {
public static void main(String []args)
{
	HashSet<Box> hs=new HashSet<Box>();
	hs.add(new Box(12,"fsr"));
	hs.add(new Box(15,"fs23"));
	hs.add(new Box(16,"fsr3"));
	hs.add(new Box(13,"fsr4"));
	hs.add(new Box(15,"fs23"));
	hs.add(new Box(16,"fsr3"));
	for(Iterator<Box> in =hs.iterator();in.hasNext();)
	{   
		Box b=in.next();
		System.out.println(b.getData()+":"+b.getName());
	}
}
}

15:fs23
13:fsr4
12:fsr
16:fsr3

通过重写hashcode方法和equal方法是HashSet中的元素保持唯一性。
1.2.HashSet的确定元素唯一性的方式:
①通过哈希函数计算出一个地址值,若此地址没有元素,则存入
②如果计算出的地址已经被占用,则继续调用equals方法把当前存入的元素和占用位置的元素进行比较。在通过equals方法比较后,如果返回值为零。就视为两个元素相同,只保留中的一个进行存储。注意哈希值不同是不需要判断equals方法。
1.3 LinkedHashSet集合
具有可预知迭代顺序的Set接口,由哈希表和链表实现。
HashSet中存储的元素是迭代无序的,而LinkedHashSet可以使迭代有序(即怎么存储的怎么拿出来)。其他方法与Hashset一致。

2.1 TreeSet集合
特点:可以对集合中元素排序。是不同步的。
它的内部数据结构是二叉树。对TreeSet集合中的元素进行排序有两种方式。
方式一:在存入的TreeSet中对象的类中实现Comparable接口,重写ComparaTo方法。

class Person implements Comparable<Person>
{
	private String name;
	private int age;
	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}

	Person(String name ,int age)
	{
		this.name=name;
		this.age=age;
	}
	public void  show()
	{
		System.out.println(this.getName()+this.getAge());
	}


	@Override
	public int compareTo(Person o) {
		int temp=this.getAge()-o.getAge();
		return temp==0?this.getName().compareTo(o.getName()):temp;
	}
	
}
public class TreeSetDemo1 {
public static void main(String []args)
{
  TreeSet<Person> ts =	new TreeSet<Person>();
  ts.add(new Person("zhang",23));
  ts.add(new Person("zhu",13));
  ts.add(new Person("wang",21));
  ts.add(new Person("liu",63));
  ts.add(new Person("liu",62));
  for(Iterator<Person> in =ts.iterator();in.hasNext();)
  {   
	  Person p=in.next();
	  System.out.println(p.getName()+":"+p.getAge());
  }
  
}
}

方式二:在构造器中传入自定义比较器进行比较
①自定义一个类实现Comparator接口
②实现Compare方法

class MycomparaByName implements Comparator<Person>
{

	@Override
	public int compare(Person o1, Person o2) {
		
		return o1.getAge()-o2.getAge();
	}
	
}

注意:方式一是按照对象中的自然顺序进行排序,如果不需要按照对象中的自然顺序,可以自定义比较器,自定义排序方式。

四 Map集合
Map集合是双列集合,由键值对的方式进行存储。
1hashtable
内部结构是哈希表,是同步的。不允许null作为键,不允许null作为值,和Vector一样,由于效率问题,新出了hashmap和Treemap。在实现的子类Prorities中用来存储键值对的配置文件的信息,可以与IO技术相结合。
2 hashmap
内部结构是哈希表,是不同步的。允许null作为键,允许null作为值。
与HashSet一样也需要重写euqals方法和hashcode方法,确保键的唯一性。
2.1Example

class Car
{
	private String type;
	private int password;
	public Car() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Car(String type, int password) {
		super();
		this.type = type;
		this.password = password;
	}
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public int getPassword() {
		return password;
	}
	public void setPassword(int password) {
		this.password = password;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + password;
		result = prime * result + ((type == null) ? 0 : type.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Car other = (Car) obj;
		if (password != other.password)
			return false;
		if (type == null) {
			if (other.type != null)
				return false;
		} else if (!type.equals(other.type))
			return false;
		return true;
	}
}
public class HashMapdemo {
public static void main(String []args)
{
	HashMap<Car,Integer> hs=new HashMap<Car,Integer>();
	hs.put(new Car("ford",5134), 25000);
	hs.put(new Car("auto",4224), 25000);
	hs.put(new Car("avdi",5354), 225000);
	hs.put(new Car("ford",5134), 125000);
	
	Set<Car> keyset=hs.keySet();
	Iterator<Car> in=keyset.iterator();
	while(in.hasNext())
	{
		Car c=in.next();
		System.out.println(c.getPassword()+c.getType()+":"+hs.get(c));
	}
}
}


3.1Treemap
内部结构是二叉树,是不同步的,可以对map集合中的键进行排序
与TreeSet一样,也有两种方法来进行排序操作。
方式一:在存入的TreeSet中对象的类中实现Comparable接口,重写ComparaTo方法。
方式二:在构造器中传入自定义比较器进行比较
①自定义一个类实现Comparator接口
②实现Compare方法

练习1
通过HashMap来计算出一段字符串的字符出现次数

public class HashMaptest {
public static void main(String []args)
{
	String str="datwejgdsdfasdfhqaz";
	char [] ch=str.toCharArray();
	TreeMap<Character,Integer> hs=new TreeMap<Character,Integer>();	
	for(int i=0;i<ch.length;i++)
	{
		Integer value=hs.get(ch[i]);
		if(value==null)
		{
			hs.put(ch[i], 1);
		}
		else
		{
			hs.put(ch[i], value+1);
		}
		}
	Set<Map.Entry<Character, Integer>> EntrySet=hs.entrySet();
	Iterator<Map.Entry<Character, Integer>>  in=EntrySet.iterator();
	while(in.hasNext())
	{
		Map.Entry<Character, Integer> map=in.next();
		System.out.println( "key:"+ map.getKey() +    "value:"+map.getValue());
	}
}
}

练习二 处理一个键对应多个值的情况,我们可以把值当做为单列集合存入Map集合。

class Person
{
	private String name;

	public Person() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Person(String name) {
		super();
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}
class Area
{
	private String location;
}
public class Maptest {
public static void main(String []args)
{
     TreeMap<String,Person> ts=new TreeMap<String,Person>();
     ts.put("beijing", new Person("liqiang"));
     ts.put("beijing", new Person("wuwang"));
     ts.put("beijing", new Person("fanqi"));
     Set<Map.Entry<String, Person>> st=ts.entrySet();
     Iterator<Map.Entry<String, Person>> in= st.iterator();
     while(in.hasNext())
     {  
    	 Map.Entry<String, Person> map=in.next();
    	 System.out.println(map.getKey()+":"+map.getValue().getName());
     }
}
}
打印结果为:beijing:fanqi
可以看到map中键相同,值覆盖。

所以我们如果在相同键存储多个值的时候 可以把值设为单列集合

class Person
{
	private String name;

	public Person() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Person(String name) {
		super();
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}
class Area
{
	private String location;
}
public class Maptest {
public static void main(String []args)
{     
	 LinkedList<Person> link=new LinkedList<Person>();
	 link.add(new Person("liqiang"));
	 link.add(new Person("wuwang"));
	 link.add(new Person("fanqi"));
     TreeMap<String,LinkedList> ts=new TreeMap<String,LinkedList>();
     ts.put("beijing",link);
     Set<Entry<String,LinkedList>> st=ts.entrySet();
     Iterator<Entry<String, LinkedList>> in= st.iterator(); 
     while(in.hasNext())
     {  
    	 Entry<String, LinkedList> map=in.next();
    	 
    	 for(Iterator<Person> in2=map.getValue().iterator();in2.hasNext();)
         {
        	 Person pp=in2.next();
         
    	    
        	 System.out.println(map.getKey()+":"+pp.getName());
         }
     
     
     }
  输出结果:   
     beijing:liqiang
     beijing:wuwang
     beijing:fanqi

     

四 collections工具类 是集合的工具类里面的方法都是静态的。

static
<T> boolean	addAll(Collection<? super T> c, T... elements) 
          将所有指定元素添加到指定 collection 中。
static
<T> Queue<T>	asLifoQueue(Deque<T> deque) 
          以后进先出 (Lifo) Queue 的形式返回某个 Deque 的视图。
static
<T> int	binarySearch(List<? extends Comparable<? super T>> list, T key) 
          使用二分搜索法搜索指定列表,以获得指定对象。
static
<T> int	binarySearch(List<? extends T> list, T key, Comparator<? super T> c) 
          使用二分搜索法搜索指定列表,以获得指定对象。
static
<E> Collection<E>	checkedCollection(Collection<E> c, Class<E> type) 
          返回指定 collection 的一个动态类型安全视图。
static
<E> List<E>	checkedList(List<E> list, Class<E> type) 
          返回指定列表的一个动态类型安全视图。
static
<K,V> Map<K,V>	checkedMap(Map<K,V> m, Class<K> keyType, Class<V> valueType) 
          返回指定映射的一个动态类型安全视图。
static
<E> Set<E>	checkedSet(Set<E> s, Class<E> type) 
          返回指定 set 的一个动态类型安全视图。
static
<K,V> SortedMap<K,V>	checkedSortedMap(SortedMap<K,V> m, Class<K> keyType, Class<V> valueType) 
          返回指定有序映射的一个动态类型安全视图。
static
<E> SortedSet<E>	checkedSortedSet(SortedSet<E> s, Class<E> type) 
          返回指定有序 set 的一个动态类型安全视图。
static
<T> void	copy(List<? super T> dest, List<? extends T> src) 
          将所有元素从一个列表复制到另一个列表。
static boolean	disjoint(Collection<?> c1, Collection<?> c2) 
          如果两个指定 collection 中没有相同的元素,则返回 true。
static
<T> List<T>	emptyList() 
          返回空的列表(不可变的)。
static
<K,V> Map<K,V>	emptyMap() 
          返回空的映射(不可变的)。
static
<T> Set<T>	emptySet() 
          返回空的 set(不可变的)。
static
<T> Enumeration<T>	enumeration(Collection<T> c) 
          返回一个指定 collection 上的枚举。
static
<T> void	fill(List<? super T> list, T obj) 
          使用指定元素替换指定列表中的所有元素。
static int	frequency(Collection<?> c, Object o) 
          返回指定 collection 中等于指定对象的元素数。
static int	indexOfSubList(List<?> source, List<?> target) 
          返回指定源列表中第一次出现指定目标列表的起始位置;如果没有出现这样的列表,则返回 -1。
static int	lastIndexOfSubList(List<?> source, List<?> target) 
          返回指定源列表中最后一次出现指定目标列表的起始位置;如果没有出现这样的列表,则返回 -1。
static
<T> ArrayList<T>	list(Enumeration<T> e) 
          返回一个数组列表,它按返回顺序包含指定枚举返回的元素。
static
<T extends Object & Comparable<? super T>> 
T	max(Collection<? extends T> coll) 
          根据元素的自然顺序,返回给定 collection 的最大元素。
static
<T> T	max(Collection<? extends T> coll, Comparator<? super T> comp) 
          根据指定比较器产生的顺序,返回给定 collection 的最大元素。
static
<T extends Object & Comparable<? super T>> 
T	min(Collection<? extends T> coll) 
          根据元素的自然顺序 返回给定 collection 的最小元素。
static
<T> T	min(Collection<? extends T> coll, Comparator<? super T> comp) 
          根据指定比较器产生的顺序,返回给定 collection 的最小元素。
static
<T> List<T>	nCopies(int n, T o) 
          返回由指定对象的 n 个副本组成的不可变列表。
static
<E> Set<E>	newSetFromMap(Map<E,Boolean> map) 
          返回指定映射支持的 set。
static
<T> boolean	replaceAll(List<T> list, T oldVal, T newVal) 
          使用另一个值替换列表中出现的所有某一指定值。
static void	reverse(List<?> list) 
          反转指定列表中元素的顺序。
static
<T> Comparator<T>	reverseOrder() 
          返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。
static
<T> Comparator<T>	reverseOrder(Comparator<T> cmp) 
          返回一个比较器,它强行逆转指定比较器的顺序。
static void	rotate(List<?> list, int distance) 
          根据指定的距离轮换指定列表中的元素。
static void	shuffle(List<?> list) 
          使用默认随机源对指定列表进行置换。
static void	shuffle(List<?> list, Random rnd) 
          使用指定的随机源对指定列表进行置换。
static
<T> Set<T>	singleton(T o) 
          返回一个只包含指定对象的不可变 set。
static
<T> List<T>	singletonList(T o) 
          返回一个只包含指定对象的不可变列表。
static
<K,V> Map<K,V>	singletonMap(K key, V value) 
          返回一个不可变的映射,它只将指定键映射到指定值。
static
<T extends Comparable<? super T>> 
void	sort(List<T> list) 
          根据元素的自然顺序 对指定列表按升序进行排序。
static
<T> void	sort(List<T> list, Comparator<? super T> c) 
          根据指定比较器产生的顺序对指定列表进行排序。
static void	swap(List<?> list, int i, int j) 
          在指定列表的指定位置处交换元素。
static
<T> Collection<T>	synchronizedCollection(Collection<T> c) 
          返回指定 collection 支持的同步(线程安全的)collection。
static
<T> List<T>	synchronizedList(List<T> list) 
          返回指定列表支持的同步(线程安全的)列表。
static
<K,V> Map<K,V>	synchronizedMap(Map<K,V> m) 
          返回由指定映射支持的同步(线程安全的)映射。
static
<T> Set<T>	synchronizedSet(Set<T> s) 
          返回指定 set 支持的同步(线程安全的)set。
static
<K,V> SortedMap<K,V>	synchronizedSortedMap(SortedMap<K,V> m) 
          返回指定有序映射支持的同步(线程安全的)有序映射。
static
<T> SortedSet<T>	synchronizedSortedSet(SortedSet<T> s) 
          返回指定有序 set 支持的同步(线程安全的)有序 set。
static
<T> Collection<T>	unmodifiableCollection(Collection<? extends T> c) 
          返回指定 collection 的不可修改视图。
static
<T> List<T>	unmodifiableList(List<? extends T> list) 
          返回指定列表的不可修改视图。
static
<K,V> Map<K,V>	unmodifiableMap(Map<? extends K,? extends V> m) 
          返回指定映射的不可修改视图。
static
<T> Set<T>	unmodifiableSet(Set<? extends T> s) 
          返回指定 set 的不可修改视图。
static
<K,V> SortedMap<K,V>	unmodifiableSortedMap(SortedMap<K,? extends V> m) 
          返回指定有序映射的不可修改视图。
static
<T> SortedSet<T>	unmodifiableSortedSet(SortedSet<T> s) 
          返回指定有序 set 的不可修改视图。

主要的有 collection.synchronizedxx方法
在Vector和hashtable中都是线程安全的,而其他集合都不是线程安全的,我们怎么获得一个线程安全的集合呢?
通过调用静态的collection.synchronizedXX方法,返回一个线程安全的集合。
synchronizedxx方法原理

class MyCollection
{
	public static  Collection synchronizedxx()  
	{
		return new SynCollection();
	}
	class SynCollection implements Collection
	{  
		 private Collection  coll;
		 private SynCollection(Collection coll)
		 {
			 this.coll=coll;
		 }
		synchronized boolean add(Collection coll)
		{
			return coll.add();
		}
		synchronized boolean remove (Collection coll)
		{
			return coll.remove(o)
		}
	}
}

其实调用Synchronized方法返回的是一个内部类对象。

五 arrays工具类 里面的方法都是静态的
有许多对数组进行操作的方法。开发更加便捷
1.其中List asList(数组)能将数组转化为List集合
好处:可以使用集合的方法来操作数组元素。
注意:①数组的长度是固定的,对于集合的增加,删除是不可以使用的。
②如果数组的元素是基本数据类型,转化成集合是直接将数组作为集合对象存储。如果数组的元素是对象,转化成集合是直接将数组中对象存储到集合。
2.也可以把集合转化为数组。Collection.toArray方法
目的:限制对集合的操作,使使用者不能对集合进行修改。
注意:toArray方法需要传递一个指定类型的数组,如果长度小于集合的元素,则会自动扩充,如果长度大于结合的元素,则大于部分存储的是null。

猜你喜欢

转载自blog.csdn.net/weixin_43752167/article/details/87457661