JavaSE-day17- 哈希表-HashSet LinkedHashSet

回眸只為那壹抹淺笑 提交于 2019-12-01 13:59:59

哈希表原理:

特点: 

  此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代顺序(无序的);特别是它不保证该顺序恒久不变。此类允许使用 null 元素

package cn.itcast.p4.hashset.test;

import java.util.HashSet;
import java.util.Iterator;

import cn.itcast.p.bean.Person;


/*
 * 往hashSet集合中存储Person对象。如果姓名和年龄相同,视为同一个人。视为相同元素。
 */
public class HashSetTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		
		HashSet hs = new HashSet();
		
		/*
		 * HashSet集合数据结构是哈希表,所以存储元素的时候,
		 * 使用的元素的hashCode方法来确定位置,如果位置相同,在通过元素的equals来确定是否相同。
		 * 
		 */
		
		hs.add(new Person("lisi4",24));
		hs.add(new Person("lisi7",27));
		hs.add(new Person("lisi1",21));
		hs.add(new Person("lisi9",29));
		hs.add(new Person("lisi7",27));
		
		
		Iterator it = hs.iterator();
		
		while(it.hasNext()){
			Person p = (Person)it.next();
			System.out.println(p);
//			System.out.println(p.getName()+"...."+p.getAge());
		}
	}

}

上面程序为什么可以插入两个new Person("lisi7",27) ;原因是:

1.

Person 默认是继承Object  ,Object 的hashCode   ,equals:

本地比较的是地址,因为是new 所以不同对象,地址不同。所以存了五个对象每个对象equals 都不相同。所以HashSet 认为不同。

HashSet存储自定对象

demo:

package day18;

public class Person {

    String name;
    int  num;
    Person(String name, int num){
        this.name=name;
        this.num=num;
    }

    public String getName() {
        return name;
    }
}
------------------
package day18;

import java.util.concurrent.CancellationException;

public class Person2 {
    String name;
    int  age;
    Person2(String name, int age){
        this.name=name;
        this.age=age;
    }
    public String getName() {
        return name;
    }
    //1.覆写
    @Override
    public int hashCode() {

        System.out.println(this.name +this.age+"------ hashCode");
        return    name.hashCode()+age*39;
    }
    // 2.覆写
    @Override
    public boolean equals(Object o) {
         if(this==o){//1.同一个对象不存储
             System.out.println("同一个对象");
             return   true;
         }
       if(!(o  instanceof Person2)){
           throw  new ClassCastException("类型错误");//2.不是Person2 类型就抛出
        }
        Person2  person2 =(Person2)o;
        System.out.println(this.name +this.age+"------ equals");
        return (this.name.equals(person2.name))&&(this.age==person2.age);
    }
}
-------------
package day18;

import java.util.HashSet;
import java.util.Iterator;

public class HashSetDemo {


    public static void main(String[] args) {
        //test1();
        test2();
    }

    /**
     * HashSet  集合结构是哈希表,所以存储元素的时候。使用的是hashCode 来确定位置,如果位置相同通过元素的equals来确定是否相同。
     */
    public static void test1(){

        HashSet  hashSet =new HashSet();
        hashSet.add(new Person ("aaaa",1));
        hashSet.add(new Person("bbbb",2));
        hashSet.add(new  Person("cccc",3));
        hashSet.add(new Person("cccc",3));
        Iterator iterator =hashSet.iterator();
      while (iterator.hasNext()){
          Person  person = (Person)iterator.next();
          System.out.println(person.name+" "+person.num);
      }

        /***
         * 由于Person 默认是继承Object ,所以使用的是Object 的hashCode 方法和equals方法。
         *    public boolean equals(Object var1) {
         *         return this == var1;
         *     }
         *        Object   object ;
         *        object.hashCode()
         * cccc 3  由于是new 出来的所以虽然 内容一样,但是Object 的equals 不同对象 ,地址不同,
         * 输出结果
         * cccc 3
         * bbbb 2
         * cccc 3
         * aaaa 1
         */
    }

    public static void test2() {

        HashSet hashSet = new HashSet();

        hashSet.add(new Person2("aaaa", 1));

        hashSet.add(new Person2("bbbb", 2));
        hashSet.add(new Person2("cccc", 3));
        hashSet.add(new Person2("cccc", 3));

        //同一个对象存两次
        Person2  person=new Person2("dddd",5);
        hashSet.add(person);
        hashSet.add(person);
        Iterator iterator = hashSet.iterator();
        while (iterator.hasNext()) {
            Person2 person2 = (Person2) iterator.next();
            System.out.println(person2.name + " " + person2.age);
        }
        /***
         * aaaa1------ hashCode
         * bbbb2------ hashCode
         * cccc3------ hashCode
         * cccc3------ hashCode
         * cccc3------ equals     name.hashCode()+age*39;  与前一个相同 所以要判断 equals
         * dddd5------ hashCode
         * dddd5------ hashCode
         * bbbb 2
         * aaaa 1
         * cccc 3
         * dddd 5
         */
    }
}

 

LinkedHashSet

有序的,

HashSet  与LinkedHashSet

package day18;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
/**
 * Created by zengjx on 2019/5/24.
 */
public class LinkedListDemo {
public  static  void  main(String[]  args){
    test1();
}
    public  static  void test1(){

        LinkedHashSet linkedHashSet=  new LinkedHashSet();
        linkedHashSet.add("aaaa");
        linkedHashSet.add("bbbb");
        linkedHashSet.add("cccc");
        linkedHashSet.add("cccc");//重复不会被添加
        Iterator  it= linkedHashSet.iterator();
         //有序
        while(it.hasNext()){
            System.out.println(" -----"+it.next());
        }
        /**
         * 输出  有序
         * -----aaaa
          -----bbbb
         -----cccc
         */
       // HashSet不保证有序
        HashSet hashSet=  new HashSet();
        hashSet.add("aaaa");
        hashSet.add("bbbb");
        hashSet.add("cccc");
        Iterator  it1= hashSet.iterator();
        //有序
        while(it1.hasNext()){
            System.out.println(" ---2--"+it1.next());
        }
    }
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!