HashSet和TreeSet HashMap以及TreeMap的介绍

HashSet 以及 TreeSet的介绍

HashSet

特点: HashSet 底层数据结构是哈希表. HashSet 不是线程安全的 集合元素可以是 null
​ 哈希表:是一个元素为链表的数组,综合了数组和链表的优点

存储数据的过程:当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的 hashCode 值,
然后根据 hashCode 值决定该对象在 HashSet 中的存储位置。(HashSet 保证元素唯一性是靠元素重写hashCode()和equals()方法来保证的,如果不重写则无法保证。)

public class Text1 {
  
    public static void main(String[] args) {
        HashSet list = new HashSet<>();
        list.add(new Student("zhangsan", 19));//利用add方法向内添加对象
        list.add(new Student("zhangsan", 19));
        list.add(new Student("lisi", 20));
        list.add(new Student("wangwu", 22));
        for (Student student : list) {//遍历学生对象
            student.show();
        }
    }
}
//输出时因为前两条输入相同对象所以会发生覆盖来保证元素的唯一

TreeSet

特点:存储自定义对象,并保证元素唯一性。如果两个对象的成员变量都相同我们认为是同一个对象.一般有序的实现需要我们去实现他的自然排序或者比较器排序

自然排序

  使用TreeSet集合进行元素的自然排序,那么对元素有要求,要求这个元素
  必须实现Comparable接口 否则无法进行自然排序

  保证元素的唯一性是靠compareTo方法的返回值来确定如果返回0 表示两个元素相等
		则不重复存储
    @Override
    public int compareTo(Student o) {
        int num=this.getAge()-o.getAge();
        int num2=num==0?this.getName().compareTo(o.getName()):num;
        return num2;
    }
在定义对象时实现Comparable接口 ,从而改写其中的compareto方法

比较器排序

	TreeSet保证元素唯一和比较器排序的原理及代码实现
	在创建TreeSet对象的时候,传递一个比较器对象、
public class Text2 {
    //3、请编写程序,存储自定义对象到TreeSet集合中,并遍历
    public static void main(String[] args) {
        TreeSet treeSet = new TreeSet<>(new Comparator() {
            @Override
            public int compare(Student o1, Student o2) {
                int num=o1.getAge()-o2.getAge();
                int num2=num==0?o1.getName().compareTo(o2.getName()):num;
                return num2;
            }
        });
        treeSet.add(new Student("zhangsan", 19));
        treeSet.add(new Student("zhangsan", 19));
        treeSet.add(new Student("lisi", 20));
        treeSet.add(new Student("wangwu", 22));

        for (Student student : treeSet) {
            System.out.println(student);
        }
    }
}

讲述HashMap以及TreeMap之前我们先了解一下Map

Map的介绍:拥有键值与所存数据两部分构成(将键映射到值的对象 一个映射不能包含重复的键每个键最多只能映射到一个值)

Map接口和Collection接口的不同:
Map是双列的,Collection是单列的
Map的键唯一,Collection的子体系Set是唯一的
Map集合的数据结构针对键有效,跟值无关;Collection集合的数据结构是针对元素有效

方法的介绍:

   a:添加功能 
		V put(K key,V value):添加元素。这个其实还有另一个功能?替换
			如果键是第一次存储,就直接存储元素,返回null
			如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
	b:删除功能
		void clear():移除所有的键值对元素
		V remove(Object key):根据键删除键值对元素,并把值返回
	c:判断功能
		boolean containsKey(Object key):判断集合是否包含指定的键
		boolean containsValue(Object value):判断集合是否包含指定的值
		boolean isEmpty():判断集合是否为空
	d:获取功能
		Set> entrySet(): 返回一个键值对的Set集合
		V get(Object key):根据键获取值
		Set keySet():获取集合中所有键的集合
		Collection values():获取集合中所有值的集合
	e:长度功能
		int size():返回集合中的键值对的对数

HashMap

HashMap的介绍:为保证对键值唯一的判断需要重写hashCode方法 和 equals 方法;

HashMap和Hashtable的区别:

    HashMap和Hashtable的区别:	查看API可以知道
	HashMap: 线程不安全,效率高.允许null值和null键
	Hashtable: 线程安全 , 效率低.不允许null值和null键
public class MyTest {
    public static void main(String[] args) {
        HashMap map = new HashMap<>();
        map.put("陈思成", "佟丽娅");
        map.put("文章", "马伊琍");
        map.put("贾乃亮", "李小璐");
        Set keySet = map.keySet();//获取键集
        
        for (String key : keySet) {//遍历键集通过get键找值
            System.out.println(key+"=="+map.get(key));
        }
    }
}

另外的遍历方式是通过entryset()获取键值和数据的一个Set集合遍历集合用每一个对象调用getkey和getvalue从而得到键值和数据

Set> entries = hashMap.entrySet();
for (Map.Entry entry : entries) {
    System.out.println(entry.getKey()+"==="+entry.getValue());
}

TreeMap

Treemap的介绍:
键的数据结构是红黑树,可保证键的排序和唯一性 (TreeMap 键不允许插入null)
排序分为自然排序和比较器排序
线程是不安全的效率比较高

我们利用 TreeMap的特性可以实现我们的需求比如存入数据后的根据我们的需求可以自己实现排序。

例题:把学生对象当做键值,按照学生的年龄从小到大排序

public class MyTest6 {
    public static void main(String[] args) {
        //Map集合的数据结构,只跟键有关

        TreeMap treeMap = new TreeMap<>(new Comparator() {
            @Override
            public int compare(Student s1, Student s2) {
                int i = s1.getAge() - s2.getAge();
                int j=i==0?s1.getName().compareTo(s2.getName()):i;
                return j;
            }
        });

        
        treeMap.put(new Student("zhangsan",1),1);
        treeMap.put(new Student("zhangsan", 10), 1);
        treeMap.put(new Student("zhangsan", 12), 1);
        treeMap.put(new Student("zhangsan", 122), 1);
        treeMap.put(new Student("zhangsan", 144), 1);
        treeMap.put(new Student("zhangsan", 109), 1);
        treeMap.put(new Student("zhangsan", 156), 1);
        treeMap.put(new Student("zhangsan", 124), 1);
        treeMap.put(new Student("zhangsan", 124), 1);

        Set> entries = treeMap.entrySet();

        for (Map.Entry en : entries) {
            Student key = en.getKey();
            Integer value = en.getValue();
            System.out.println(key.getName()+"=="+key.getAge()+"======="+value);
        }

    }
}

集合的嵌套:
基础班
张三 20
李四 22
就业班
王五 21
赵六 23
利用HashMap嵌套
将姓名作为键值 年龄作为数据作为存储值

外层班级作为键值 学生作为存储值

  public static void main(String[] args) {
        HashMap studentHashMap = new HashMap<>();
        studentHashMap.put("张三",20);
        studentHashMap.put("李四",22);
        HashMap student1HashMap = new HashMap<>();
        student1HashMap.put("王五",21);
        student1HashMap.put("赵六",23);
        HashMap> stringHashMapHashMap = new HashMap<>();
        stringHashMapHashMap.put("基础班",studentHashMap);
        stringHashMapHashMap.put("就业班",student1HashMap);

        Set>> entries = stringHashMapHashMap.entrySet();
        for (Map.Entry> entry : entries) {
            System.out.println(entry.getKey());
            HashMap value = entry.getValue();
            Set> entries1 = value.entrySet();
            for (Map.Entry stringIntegerEntry : entries1) {
                System.out.println("\t"+stringIntegerEntry.getKey()+"  "+stringIntegerEntry.getValue());
            }

        }


    }
}

你可能感兴趣的:(HashSet和TreeSet HashMap以及TreeMap的介绍)