`
schy_hqh
  • 浏览: 542315 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

(集合)java中的哈希表,HashSet,TreeSet

 
阅读更多

 

 

哈希表是一种数据结构,能够快速定位已存储的数据的地址:

 

1.通过hashCode()计算哈希码,通过该哈希码定位到内存地址。hash码的计算通常基于对象的某些特有属性进行计算;

 

2.如果地址不同,则直接存入;

 

3.如果地址相同,则调用该对象的equals()比较内容;如果内容相同,则丢弃,不同,则顺延一个空间,存入。

 

HashSet  HashMap 都是基于hash表的数据结构进行实现的。

 

 

 

HashSet确保对象唯一,通过hashCode()与equals()来完成

 

hashCode() 计算不同对象的哈希码

equals() 当地址相同时,判断对象是否相同,如果相同,则丢弃,如果不同,就顺延存入。这样便确保了对象的唯一性

 

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


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


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

	/**
	 * Person对象的哈希值计算方法
	 */
	@Override
	public int hashCode() {
		return name.hashCode()+age*31;
	}

	/**
	 * 比较Person对象是否相同的规则
	 */
	@Override
	public boolean equals(Object obj) {
		Person p = (Person)obj;
		return this.name.equals(p.getName()) && this.age == p.getAge();
	}
	
	
	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;
	}

	
}

 

	public static void main(String[] args) {
		
		Set<Person> set = new HashSet<Person>();
		set.add(new Person("zs1",10));
		set.add(new Person("zs2",20));
		set.add(new Person("zs3",30));
		set.add(new Person("zs1",10));//hachCode()结果相同,equals()结果为true,该对象被丢弃
		
		Iterator<Person> iter = set.iterator();
		while(iter.hasNext()) {
			Person p = iter.next();
			System.out.println(p.getName()+"--"+p.getAge());
		}
	}

 

 

TreeSet确保对象唯一,并且按指定规则排序,通过compare()或compareTo()实现

 

TreeSet中比较器,返回int值,如果为0,表示相同,则不存,确保唯一。

TreeSet的实现,不依赖hashCode()和equals()。

 

如,String字符串类实现了Comparable接口,复写了compareTo()

 

public int compareTo(String anotherString) {
        int len1 = value.length;
        int len2 = anotherString.value.length;
        int lim = Math.min(len1, len2);
        char v1[] = value;
        char v2[] = anotherString.value;

        int k = 0;
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                return c1 - c2; //比较字符的自然顺序
            }
            k++;
        }
        return len1 - len2;
    }

 

 

1. 自定义比较器,实现Comparator接口;在存入TreeSet集合的时候指定比较器。

让集合具备比较功能,而且将覆盖元素自身的比较规则!

应用场景:

a.覆盖对象本身具备的比较规则,如String类默认按自然顺序排序,将其覆盖为按长度排序

b.为其它类(非自己创建的类)指定比较规则,将比较功能传入集合中,让集合具备比较功能

 

 

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

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

	
}
 

 

 

 

import java.util.Comparator;


public class PersonComparator implements Comparator<Person> {
	/**
	 * 姓名不同
	 * 	存入,并按姓名排序
	 * 姓名相同,比较年龄
	 * 	年龄不同,则首先按姓名,再按年龄排序
	 * 	年龄也相同,则为同一个对象,不存!
	 */
	@Override
	public int compare(Person o1, Person o2) {
		//1.按姓名比较
		int comp = o1.getName().compareTo(o2.getName());
		//2.姓名相同,则继续按年龄比较,如果年龄相同,则表示同一个对象,不存!
		return comp==0?(o1.getAge()-o2.getAge()):comp;
	}

}
 
	public static void main(String[] args) {
		Set<Person> set = new TreeSet<Person>(new PersonComparator());//传入比较器
		set.add(new Person("zs1",10));
		set.add(new Person("zs2",20));
		set.add(new Person("zs2",15));//姓名相同的情况下,则年龄作为次要排序条件
		set.add(new Person("zs1",10));//哈希值相同,equals()结果为true,该对象被丢弃
		
		Iterator<Person> iter = set.iterator();
		while(iter.hasNext()) {
			Person p = iter.next();
			System.out.println(p.getName()+"--"+p.getAge());
		}
	}
 

 

结果:

 

zs1--10
zs2--15
zs2--20
 

 

 

 

2. 实现Comparable接口

 

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

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

	/**
	 * 排序规则:
	 * 	首先按姓名排
	 * 	姓名相同,再按年龄排
	 * 	年龄也相同,则为同一个对象,不存!
	 */
	@Override
	public int compareTo(Person o) {
		int temp = this.name.compareTo(o.getName());
		return temp==0 ? (this.age-o.getAge()) : temp;
	}

	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;
	}

	
}
 
public static void main(String[] args) {
		Set<Person> set = new TreeSet<Person>();
		set.add(new Person("zs1",10));
		set.add(new Person("zs2",20));
		set.add(new Person("zs2",15));//姓名相同的情况下,再按年龄排序
		set.add(new Person("zs1",10));//哈希值相同,equals()结果为true,该对象被丢弃
		
		Iterator<Person> iter = set.iterator();
		while(iter.hasNext()) {
			Person p = iter.next();
			System.out.println(p.getName()+"--"+p.getAge());
		}
	}
 结果:

 

zs1--10
zs2--15
zs2--20
 
分享到:
评论

相关推荐

    Java集合框架Set接口.pdf

    HashSet是基于哈希表实现的Set集合,它不保证集合中元素的顺序。由于哈希表的实现机制,HashSet的添加、删除和查找操作都具有很好的性能,时间复杂度为O(1)。 LinkedHashSet是基于链表和哈希表实现的Set集合,它保证...

    【后端】java基础(4.2)java中级基础之集合——List

    HashSet的底层结构是哈希表,主要用于快速查找,存入HashSet的对象必须定义HashCode。不能保证保存次序 TreeSet底层为树状结构,可以保证保存次序 LinkedHashSet具有HashSet的速度,且底层使用链表维护元素的次序。 ...

    ypjh001#-#04.Set集合1

    1.HashSet集合介绍 2.HashSet集合存储数据的结构(哈希表) 3.HashSet存储自定义类型元素 5.TreeSet集合 1.特点 2.演示 1

    Java超详细!Java实现数据结构PPT课件

    哈希表(HashTable) 树形数据结构 二叉树(BinaryTree)、二叉搜索树(BinarySearchTree、BST) 平衡二叉搜索树(BalancedBinarySearchTree、BBST) AVL树(AVLTree)、红黑树(RebBlackTree) B树(B-Tree) 集合...

    关于Set集合

    --| class HashSet 底层是哈希表存储数据 --| class TreeSet 底层存储数据是一个二叉树 1.2 HashSet 1.2.1 底层结构 package com.qfedu.b_set; import java.util.HashSet; public class Demo2 { public static ...

    【Java】基础25:List、Set以及哈希表

    昨天学习了几种简单数据结构,为何要了解数据结构?一方面的原因是因为集合的底层就是与其...HashSet的底层数据结构:哈希表。 前天学习了Collection集合,其继承体系图如下: 原创文章 25获赞 4访问量 617 关注

    集合比较

    (负载因子=表中元素的数量/哈希表的总大小)如果容量减少,性能会更好。 b。 在第1部分中,我们使用平衡树(AVL TREE)来实现一个集合,它只需要O(logn)时间即可完成诸如搜索,插入或删除之类的功能。 但是在...

    Java容器

    HashSet:基于哈希表实现,支持快速查找,但是不支持有序,就是插入的数据遍历出来是无序的。 LinkedHashSet:具有HashSet查找效率,同时前后链维持数据的插入顺序。 TreeSet:基于红黑树实现,支持有序性操作。 ...

    Java容器.xmind

    底层哈希表,基于hashCode的equals的比较方式,线程不安全,存取速度快。 SortedSet 标记: interface TreeSet 标记: class 实现comparable接口,元素是以二叉树的形式存放的。线程不安全 CopyOnWriteArraySet 标记:...

    leetcode算法题主函数如何写-Algorithm-DataStructure:算法-数据结构

    无序集合HashSet,无序映射HashMap,底层基于哈希表实现。 数组Array Array.java: 基于Java中最基础的数组,自定义二次封装实现了一个动态数组: 1.自定义一个数组类Array,使用泛型,让数组类支持存储任意元素。 ...

    Java开发技术大全 电子版

    11.4.5哈希表(Hashtable)简介371 11.5本章小结371 第12章类型包装器、自动装箱和元数据(注释)372 12.1类型包装器372 12.1.1字符类型包装器372 12.1.2布尔类型包装器373 12.1.3数字类型包装器373 12.2自动...

    达内 coreJava 习题答案

    其中a为1至9之中的一个数,项数也要可以指定。 import java.util.Scanner; class Multinomial{ public static void main(String[] args){ int a; //定义输入的 a int howMany; //定义最后的一项有多少个数字 ...

    扩展矩阵leetcode-imooc_algorithm_graph:慕课网《玩转算法系列--图论精讲》笔记及Golang代码实现

    HashSet(哈希表) 或者 TreeSet(红黑树)(2-7 13:35) 由于 Golang 中没有内置的 TreeSet 红黑树,这里就使用 map (哈希表)了 :/ 可以使用深度优先遍历 验证图是否联通、是否有环 二分图检测 寻找图中的桥 寻找...

Global site tag (gtag.js) - Google Analytics