Java语言:集合——Set、Map

Set接口概述:

           一个不包含重复元素的collection。
Collection
           
          List
                   有序(存储顺序和取出顺序一致),可重复
          Set
                    无序(存储顺序和取出顺序不一致),唯一
                    HashSet:它不保证Set的迭代顺序;特别是它不保证顺序恒久不变。
 

import java.util.HashSet;
import java.util.Set;

public class HashSetDemo {
	public static void main(String[] args) {
		//创建集合
		Set<String> set = new HashSet<String>();
		
//		set.add("hello");
//		set.add("world");
//		set.add("java");
//		
//		//增强for
//		for(String s : set) {
//			System.out.println(s);
//		}
//		world
//		java
//		hello
		
		
		set.add("hello");
		set.add("world");
		set.add("java");
		set.add("world");
		set.add("java");
		
		//增强for
		for(String s : set) {
			System.out.println(s);
		}
//		world
//		java
//		hello

		
	}
}

HashSet:存储字符串的唯一性

        查看add()方法源码,方法底层依赖两个方法:hashCode()和equals()。
        步骤:
               首先比较哈希值
               如果相同,继续比较地址值或者equals()
               如果不同,就直接添加到集合中
        先看hashCode()值是否相同
               相同:继续equals()方法。
                            返回true:说明元素重复,就不添加
                            返回false:说明元素不重复,就添加到集合
                不相同:就直接把元素添加到集合
         如果类没有重写这两个方法,默认使用Object类中方法。一般不会相同。
         而String类重写了hashCode()和equals()方法,所以,它就可以把内容相同的字符串去掉。保证唯一性。
                    

HashSet存储自定义对象

        注意:需要重写hashCode()方法和equals()方法(可自动生成)。优化hashCode()方法让对象的哈希值尽可能的不同。(由于哈希值和对象的成员变量值相关,所以,最终解决方案就是把对象的成员变量值进行相加:如果是基本类型,就直接加值;如果是引用类型,就加哈希值)

public class Student {
	
	private String name;
	private int age;
	
	public Student() {
		super();
	}

	public Student(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;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		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;
		Student other = (Student) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	
	
}

import java.util.HashSet;

public class HashSetDemo2 {
	public static void main(String[] args) {
		// 创建集合
		HashSet<Student> hashSet = new HashSet<Student>();

		// 创建学生对象
		Student s = new Student("刘备", 30);
		Student s2 = new Student("关羽", 27);
		Student s3 = new Student("张飞", 26);
		Student s4 = new Student("刘备", 30);
		Student s5 = new Student("关羽", 28);
		Student s6 = new Student("刘备", 27);
		Student s7 = new Student("张飞", 26);
		
		hashSet.add(s);
		hashSet.add(s2);
		hashSet.add(s3);
		hashSet.add(s4);
		hashSet.add(s5);
		hashSet.add(s6);
		hashSet.add(s7);
		
		for(Student ss : hashSet) {
			System.out.println(ss.getName()+"---"+ss.getAge());
		}
	}
}
----------------------------------------------------------------------
关羽---28
刘备---30
张飞---26
关羽---27
刘备---27

LinkedHashSet:底层数据结构由哈希表和链表组成。

          哈希表保证元素的唯一性。
          链表保证元素有序。(存储和取出是一致)

TreeSet类概述:能够对元素按照某种规则进行排序

           使用元素的自然顺序对元素进行排序
           或者根据创建set时提供的Comparator(比较器)进行排序
           具体取决于使用的构造方法。

TreeSet集合的特点:排序和唯一

排序的真正比较是依赖与元素的compareTo()方法,而这个方法是定义在Comparable接口里面的。所以,重写该方法,必须实现实现Comparable接口。这个接口表示的就是自然排序。

TreeSet:底层是二叉树结构。(红黑树是一种自平衡的二叉树)
            元素存储规则:
                         第一个元素存储时,直接作为根节点存储。
                         从第二个元素开始,每个元素从根节点开始比较
                                         若大       作为右孩子
                                         若小       作为左孩子
                                         若相等      则不存储
                          前序遍历输出,实现排序及唯一。

TreeSet存储自定义对象并保证排序和唯一。自定义对象需要根据自定义对象的自然排序规则实现自然排序Comparable接口并重写CompareTo()方法。

TreeSet集合保证元素排序和唯一性的原理
唯一性:是根据比较的返回是否是0来决定。
排序:
         A:自然排序(元素具备比较性)
                  让元素所属的类实现自然排序接口Comparable
         B:比较器排序(集合具备比较性)
                  让集合的构造方法接收一个比较器接口的子类对象Comparator

public class Student implements Comparable<Student> {

	private String name;
	private int age;

	public Student() {
		super();
	}

	public Student(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;
	}

	@Override
	public int compareTo(Student s) {
		int num = this.age - s.age;
		int num2 = num == 0 ? this.name.compareTo(s.name) : num;
		return num2;
	}
}
import java.util.TreeSet;

public class TreeSetDemo {
	public static void main(String[] args) {
		
		TreeSet<Student> treeSet = new TreeSet<Student>();
		
		Student s = new Student("刘备", 30);
		Student s2 = new Student("关羽", 27);
		Student s3 = new Student("张飞", 26);
		Student s4 = new Student("刘备", 30);
		Student s5 = new Student("关羽", 28);
		Student s6 = new Student("刘备", 27);
		Student s7 = new Student("张飞", 26);
		treeSet.add(s);
		treeSet.add(s2);
		treeSet.add(s3);
		treeSet.add(s4);
		treeSet.add(s5);
		treeSet.add(s6);
		treeSet.add(s7);
		
		for(Student ss : treeSet) {
			System.out.println(ss.getName()+"---"+ss.getAge());
		}
	}
}
---------------------------------------------------------------------------------------------------
张飞---26
关羽---27
刘备---27
关羽---28
刘备---30

匿名内部类实现比较器排序。

import java.util.Comparator;
import java.util.TreeSet;

public class TreeSetDemo {
	public static void main(String[] args) {
		
		TreeSet<Student> treeSet = new TreeSet<Student>(new Comparator<Student>() {
			@Override
			public int compare(Student s1, Student s2) {
				int num = s1.getAge() - s2.getAge();
				int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
				return num2;
			}
			
		});
		
		Student s = new Student("刘备", 30);
		Student s2 = new Student("关羽", 27);
		Student s3 = new Student("张飞", 26);
		Student s4 = new Student("刘备", 30);
		Student s5 = new Student("关羽", 28);
		Student s6 = new Student("刘备", 27);
		Student s7 = new Student("张飞", 26);
		treeSet.add(s);
		treeSet.add(s2);
		treeSet.add(s3);
		treeSet.add(s4);
		treeSet.add(s5);
		treeSet.add(s6);
		treeSet.add(s7);
		
		for(Student ss : treeSet) {
			System.out.println(ss.getName()+"---"+ss.getAge());
		}
	}
}


Map集合的特点:

       将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。

Map集合和Collection集合的区别?

        Map集合存储元素是成对出现的,Map集合的键是唯一的,值是可重复的。
       Collection集合存储元素是单独出现的,Collection的儿子Set是唯一的,List是可重复的。
       注意:
              Map集合的数据结构值针对键有效,跟值无关
              Collection集合的数据结构是针对元素有效

Map集合的功能概述:

       1、添加功能
                  V put(K key, V value):添加元素。
                           如果键是第一次存储,就直接存储元素,返回null
                           如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
       2、删除功能
                  void clear():移除所有的键值对元素
                  V remove(Object key):根据键删除键值对元素,并把值返回
       3、判断功能
                  boolean containsKey(Object key):判断集合是否包含指定的键
                  boolean containsValue(Object value):判断集合是否包含指定的值
                  boolean isEmpty():判断集合是否为空
       4、获取功能
                  Set<Map.Entry<K,V>> entrySet():返回的是键值对对象的集合
                  V get(Object key):根据键获取值
                  Set<K> keySet():获取集合中所有键的集合
                  Collection<V> values():获取集合中所有值的集合
       5、长度功能
                  int size():返回集合中的键值对的对数
 


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

//遍历Map集合的两种方法
public class HashMapDemo {
	public static void main(String[] args) {
		// 创建集合
		Map<String, String> map = new HashMap<String, String>();

		map.put("杨过", "小龙女");
		map.put("郭靖", "黄蓉");
		map.put("张无忌", "周芷若");
		map.put("梁山伯", "祝英台");
		map.put("杰克", "露西");
		
		//获取所有键的集合
		Set<String> set = map.keySet();
		
		//根据键获取值进行遍历
		for(String s : set) {
			System.out.println(s+"---"+map.get(s));
		}
		
		System.out.println("----------------------------");
		
		Set<Map.Entry<String, String>> set2 = map.entrySet();
		
		for(Map.Entry<String, String> map2 : set2) {
			System.out.println(map2.getKey()+"---"+map2.getValue());
		}
	}
}

HashMap类概述

        键是哈希表结构,可以保证键的唯一性

知识点:

       java中数值类型进制表示
            二进制:0b****;(*表示0或1)
            八进制:0****;(*表示0到7任意数字)
            十六进制:0x****;(*表示0到f任意数字)

LinkedHashMap:是Map接口的哈希表和链表实现,具有可预知的迭代顺序。

          由哈希表保证键的唯一性
          由链表保证键盘的有序(存储和取出的顺序一致)

TreeMap类概述:

       键是红黑树结构,可以保证键的排序和唯一性。


 


//嵌套集合

/*
 * 升达
 *      cj   财经学院
 *                kj     会计专业
 *                      林黛玉      25
 *                      薛宝钗      28
 *                cwgl   财务管理
 *                      贾宝玉       26
 *                      王熙凤       29
 *      xg   信工学院
 *                rjgc   软件工程 
 *                      赵云          26
 *                      马超          27
 *                jk     计科专业
 *                      关羽          28
 *                      黄忠          30
 *      jg   建工学院
 *                tmgc   土木工程
 *                      宋江          37
 *                      李逵          32
 *                gcgl   工程管理
 *                      吴用          28
 *                      鲁智深       33
 * 
 * 
 * */

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;

public class HashMapDemo2 {
	public static void main(String[] args) {
		// 创建升达集合
		HashMap<String, HashMap<String, ArrayList<Student>>> sdmap = new HashMap<String, HashMap<String, ArrayList<Student>>>();

		// 财经集合
		HashMap<String, ArrayList<Student>> cjmap = new HashMap<String, ArrayList<Student>>();
		// 会计集合
		ArrayList<Student> kjList = new ArrayList<Student>();
		Student s1 = new Student("林黛玉", 25);
		Student s2 = new Student("薛宝钗", 28);
		kjList.add(s1);
		kjList.add(s2);
		// 财务管理集合
		ArrayList<Student> cwglList = new ArrayList<Student>();
		Student s3 = new Student("贾宝玉", 26);
		Student s4 = new Student("王熙凤", 29);
		cwglList.add(s3);
		cwglList.add(s4);
		cjmap.put("会计专业", kjList);
		cjmap.put("财务管理", cwglList);

		// 信工集合
		HashMap<String, ArrayList<Student>> xgmap = new HashMap<String, ArrayList<Student>>();
		// 软工集合
		ArrayList<Student> rgList = new ArrayList<Student>();
		Student s5 = new Student("赵云", 26);
		Student s6 = new Student("马超", 27);
		rgList.add(s5);
		rgList.add(s6);
		// 计科集合
		ArrayList<Student> jkList = new ArrayList<Student>();
		Student s7 = new Student("关羽", 28);
		Student s8 = new Student("黄忠", 30);
		jkList.add(s7);
		jkList.add(s8);
		xgmap.put("软件工程", rgList);
		xgmap.put("计科专业", jkList);
		
		// 建工集合
		HashMap<String, ArrayList<Student>> jgmap = new HashMap<String, ArrayList<Student>>();
		// 土木工程集合
		ArrayList<Student> tmList = new ArrayList<Student>();
		Student s9 = new Student("宋江", 37);
		Student s10 = new Student("李逵", 32);
		tmList.add(s9);
		tmList.add(s10);
		// 工程管理集合
		ArrayList<Student> gcList = new ArrayList<Student>();
		Student s11 = new Student("吴用", 28);
		Student s12 = new Student("鲁智深", 33);
		gcList.add(s11);
		gcList.add(s12);
		jgmap.put("土木工程", tmList);
		jgmap.put("工程管理", gcList);
		
		sdmap.put("财经学院", cjmap);
		sdmap.put("信工学院", xgmap);
		sdmap.put("建工学院", jgmap);
		
		//遍历集合
		Set<String> sdSet = sdmap.keySet();
		for(String sdKey : sdSet) {
			System.out.println(sdKey);
			HashMap<String,ArrayList<Student>> sdValue = sdmap.get(sdKey);
			Set<String> xySet = sdValue.keySet();
			for(String xyKey : xySet) {
				System.out.println("\t"+xyKey);
				ArrayList<Student> zyList = sdValue.get(xyKey);
				for(Student s : zyList) {
					System.out.println("\t\t"+s.getName()+"---"+s.getAge());
				}
			}
		}
	}
}
---------------------------------------------------------------------------------------------------------------
财经学院
	会计专业
		林黛玉---25
		薛宝钗---28
	财务管理
		贾宝玉---26
		王熙凤---29
信工学院
	软件工程
		赵云---26
		马超---27
	计科专业
		关羽---28
		黄忠---30
建工学院
	工程管理
		吴用---28
		鲁智深---33
	土木工程
		宋江---37
		李逵---32


Hashtable和HashMap的区别?

          Hashtable:线程安全,效率低。不允许null键和null值
          HashMap:线程不安全,效率高。允许null键和null值

List,Set,Map等接口是否都继承自Map接口?

            List,Set不是继承自Map接口,它们继承自Collection接口
            Map接口本身就是一个顶层接口

Collections类概述

         针对集合操作的工具类,都是静态方法。

Collection和Collections的区别?

         Collection:是单列集合的顶层接口,有子接口List和Set。
         Collections:是针对集合操作的工具类,有对集合进行排序和二分查找的方法。

Collections类方法:

         public static <T> void sort(List<T> list):排序 默认情况下是自然排序。
         public static <T> int binarySearch(List<?> list,T key):二分查找
         public static <T> T max(Collection<?> coll):最大值
         public static void reverse(List<?> list):反转
         public static void shuffle(List<?> list):随机置换

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值