`
娜娜TX
  • 浏览: 8001 次
  • 性别: Icon_minigender_2
  • 来自: 湖南长沙
社区版块
存档分类
最新评论

集合的概念及应用和HashSet保证数据不重复的原理

阅读更多

集合的概念:集合类存放的都是对象的引用,不是对象本身,我们称集合中的对象就是指集合中对象的引用(reference),存放在Java.util包中。

集合类型主要有3种:set(集)、list(列表)和map(映射)。

集合的特点是:可以改变长度,但不保证迭代顺序和不存放重复的数据

在集合中如何判断两个数据相等?

在集合中判断一个数据是否相等要根据它的HashCode方法和equlas方法来判断内容是否相等,我们在判断一个数据是否相等的时候,首先它会调用自己的HashSet方法计算出一个Code值,然后通过这个code值来找到数据在集合中的位置,如果code值的位置上没有数据就将这个数据存放在集合中,如果有,就调用equals方法比较两个数据的大小,如果相等就返回true,否则返回false,如果返回的是true就说明集合中已经有一个数据和你要存放的数据相等了,那就不要再将这个数据存放进去,HashSet不能存放两个相同的数据,如果你一定要将这个数据存入集合就要重写HashCode方法equals方法,因为怕和集合中的数据产生重复,如果重复了你不重写这两个 方法是不能放进去的(ps:一定要HashCode方法和equals方法都相等才能说数据相等,二者缺一不可)

下面是一些代码的实现:

向集合中存储数据

 

/**
	 * 增加数据的方法
	 * 
	 * @param e
	 */
	public void add(E e) {
		Node<E> node = new Node<E>(e);// 创建一个新结点并指定数据
		// 如果head指向的数据为空说明是一个空链表
		if (head == null) {
			head = node;// 那么将head指向node
			last = node;// last也指向node,这时node即是头结点 也是尾结点
			num++;// 结点数增加
		} else {
			// 如果head不为空说明链表中有数据,调用isDuplicate方法,看要添加的数据和链表中的数据是否重复
			boolean bool = isDuplicate(node);
			if (!bool) {
				// 根据node的hashcode值找到下标
				int index = getIndex(node.code);
				// 调用insert方法,将数据插入在index位置
				insert(index, e);
				num++;// 结点数增加
			}
		}
	}

 向集合中添加数据的时候调用插入方法在这里面对数据进行比较

 

/**
	 * 定义一个私有的插入方法
	 * 
	 * @param index插入结点的下标
	 * @param e插入的内容
	 */
	private void insert(int index, E e) {
		Node<E> node = new Node<E>(e);// 创建新结点并指定数据
		// 插入的结点位置是头结点的位置
		if (index == 0) {
			node.next = head;// 将node的下一个结点指向head
			head.front = node;// head的上一个结点指向node
			head = node;// 将head指向 node,这时node中的数据处于第一个head的位置
		}
		// 其他位置
		else {
			// 创建一个新结点,调用getNode(index)方法找到我们要插入数据的结点的位置
			Node<E> n1 = getNode(index);
			Node<E> n2 = n1.front;// 再创建一个结点,将我们找到n1位置的上一个结点指向n2
			// 将node插在n2和n1的中间,n2->node->n1,所以
			n2.next = node;// n2的下一个结点指向node
			node.front = n2;// node的上一个结点 指向n2
			node.next = n1;// node的下一个结点指向n1
			n1.front = node;// n1的上一个结点指向node
			// 上面这一操作主要是在n2和n1的中间插入node结点,必须得改变他们的指向关系
		}
	}

 

 

获取数据的方法

 

 

/**
	 * 取出并移除一个数据
	 * 
	 * @return返回取出数据的内容
	 */
	public E get() {
		// 看头结点是否为空,不为空才继续下面的操作否则返回null
		if (head != null) {
			Node<E> n = head;// 定义一个新结点指向head
			head = head.next;// 将head指向它的下一个结点
			n.next = null;// 将新结点n的下一个结点指向null
			num--;
			return n.data;// 返回原来head的值
		}
		return null;
	}

 删除数据提供了两种不同的方法

 

①根据下标删除数据

 

/**
	 * 根据下标删除数据
	 * 
	 * @param index要删除数据的下标
	 */
	public void delete(int index) {
		Node<E> n = getNode(index);//创建一个新结点并根据下标获取需要删除的数据的位置
		//三者的位置n1->n->n2
		Node<E> n1 = n.front;//n1指向n的前一个结点
		Node<E> n2 = n.next;//n2指向n的下一个结点
		//下面将实现删除n结点
		n2.front = n1;
		n1.next = n2;
		n.front = null;
		n.next = null;
		num--;
	}

 

②根据内容删除数据

 

/**
	 * 根据内容删除数据的方法
	 * 
	 * @param e
	 */
	public void delete(E e) {
		Node<E> node = head;//创建新结点指向head
		int code = e.hashCode();//获得结点e的hashCode值
		while (node != null) {//node结点指向的数据不为null,进入循环
			//判断node的hashCode和内容是否等于e的hashCode和内容,相等就获取node的下标调用根据下标删除内容的方法
			if (node.data.equals(e) && node.code == code) {
				int m = getIndex(node.code);
				delete(m);
			}
			node = node.next;
		}
	}

 判断集合中是否有结点数据与要添加的数据相同的数据

 

 

/**
	 * 判断集合中是否有结点数据与要添加的数据相同的数据
	 * 
	 * @param node要添加的数据
	 * @return如果相同返回ture,没有相同的就返回false
	 */
	private boolean isDuplicate(Node<E> node) {
		Node<E> n = head;// 定义一个新结点指向head
		// 如果n指向的结点数据不为空就赶进入循环
		while (n != null) {
			// 判断n所指向 的数据和传入的数据的内容和code值 是否相等,相等返回true,否则n指向下一个结点
			if (n.data.equals(node.data) && n.code == node.code) {
				return true;
			}
			n = n.next;
		}
		return false;
	}

 根据结点的hashcode值计算出结点的位置

 

 

/**
	 * 根据结点的hashcode值计算出结点的位置
	 * 
	 * @param code
	 *            结点的hashcode值
	 * @return返回结点的位置
	 */
	private int getIndex(int code) {
		int t = -1;// 定义一个变量t给它赋值为一个不存在的值
		Node<E> node = head;// 定义一个新的结点指向head
		// 如果Node所指向结点的数据不为null,就进入循环
		while (node != null) {
			t++;// 这时变量t增加
			// 如果node的hashcode值大于等于我们要查找的数据的hashcode就退出循环,否则指向下一个结点
			if (node.code >= code) {
				break;
			}
			node = node.next;
		}
		return t;
	}

 根据下标确定结点

 

 

/**
	 * 根据下标确定结点
	 * 
	 * @param index查找结点的下标
	 * @return返回的结点的内容
	 */
	private Node<E> getNode(int index) {
		int t = -1;// 定义一个变量赋值为一个不存在的值
		// 判断我们在查找的下标是否在结点数范围内
		if (index >= 0 && index < num) {
			Node<E> node = head;// 创建新结点指向head
			// 如果node结点所指向的数据不为空就进入循环
			while (node != null) {
				// 这时t增加到0,从下标的最小值,如果前面定义的时候从0开始,这时再增加t就已经不再是下标的最小值,就和我们需要的结点对不上
				t++;
				// 如果t和Index相等就说明找到就退出程序,否则指向下一个结点继续循环
				if (t == index) {
					break;
				}
				node = node.next;
			}
			return node;
		} else {
			// 抛出异常
			throw new IndexOutOfBoundsException("下标超出边界!index:" + index + ",size:" + num);
		}
	}
}

 

1
2
分享到:
评论

相关推荐

    集合类HashSet

    在Java编程语言中,集合类是用于存储一组不重复元素的数据结构。HashSet是其中的一种,它属于集合框架的一部分,提供了一种基于哈希表实现的无序、不可重复的元素集合。本文将深入探讨HashSet类及其相关的知识点。 ...

    Java集合排序及java集合类详解.pdf

    - **集合**:用来存储不重复元素的容器,如List和Set。 - **映射**:用来存储键值对(key-value pair)的容器,如Map。 集合框架的设计旨在提高代码的可读性、可维护性和效率。通过使用这些容器,开发者可以更加专注...

    浅谈JAVA集合框架及其应用.zip

    例如,如果你需要存储不重复的元素并进行快速查找,那么`HashSet`可能是最佳选择;如果需要保持元素的插入顺序,`LinkedList`或`LinkedHashMap`将更合适;如果需要根据键的值进行排序,`TreeMap`则是理想选择。 在...

    java编程基础笔记(集合)

    4. Set接口的HashSet和TreeSet的实现原理及选择依据 5. Map接口的HashMap、TreeMap和Hashtable的特性及选择策略 6. 如何在实际编程中有效地利用集合框架解决问题 7. 集合的遍历方式,包括迭代器和增强for循环 8. ...

    第十六天有关集合的练习及源码

    在IT行业中,集合是编程语言中一个至关重要的概念,它是一种数据结构,用于存储一组不重复的元素。在本主题“第十六天有关集合的练习及源码”中,我们将探讨集合的相关知识点,并通过源码分析来加深理解。在软件开发...

    Java 集合与数据结构详解1

    这些算法对于理解排序原理很有帮助,但在实际应用中,Java集合框架中的Collections类提供了更高效的排序方法,如使用快速排序和归并排序。 HashMap的源码分析是一个深入的话题,它涉及到位运算、哈希函数、扩容策略...

    Java集合详解

    在集合框架中,“集合”的概念与数学中的集合概念类似,都指的是一组唯一项的组合,即集合中的元素不重复。集的基本属性包括集内仅包含每个项的一个实例,集可以是有限的也可以是无限的,还可以定义抽象概念等。 在...

    数据结构和Java集合框架 英文版 第三版

    通过本篇内容的学习,我们不仅了解了数据结构的基础知识和Java集合框架的核心概念,还探讨了如何结合JDK源码来深入理解这些知识点。掌握好这些内容对于提高编程技能、优化代码质量和提升软件工程能力具有重要意义。...

    day06-集合1

    其中,Set集合是一种不允许有重复元素的集合,它主要分为两大类:基于哈希表的HashSet和基于红黑树的TreeSet。本文将重点讨论基于哈希表的HashSet集合以及哈希值的概念。 1. **Set集合概述和特点** Set集合的主要...

    Java集合排序及java集合类详解(Collection、List、Map、Set)

    ### Java集合排序及java集合类详解(Collection、...以上是对Java集合框架中的`Collection`、`List`、`Set`和`Map`的详细介绍,涵盖了它们的基本概念、常用方法、实现原理等方面,希望对理解和使用Java集合有所帮助。

    java基础之集合面试题共4页.pdf.zip

    2. **HashSet和TreeSet**:HashSet基于HashMap实现,存储无序、不重复的元素,查找速度快。TreeSet由TreeMap支撑,保持元素排序,可以是自然排序或自定义比较器排序。 3. **HashMap和TreeMap**:HashMap提供快速的...

    集合 Collection

    ### Java 集合框架详解 ...通过深入理解和熟练应用集合框架,开发者可以显著提升代码质量和程序性能。无论是初学者还是经验丰富的开发者,都应该充分了解并掌握Java集合框架的相关知识,以更好地应对实际开发中的挑战。

    java 集合框架

    1. **灵活性**:集合框架支持多种数据结构,包括但不限于List(有序且允许重复)、Set(无序且不允许重复)、Map(键值对存储)等,满足不同场景下的数据存储需求。 2. **高效性**:内置的集合类通常经过优化,提供...

    Java 集合学习指南 - v1.1.pdf

    它们在实现上有着类似的机制,但HashSet专注于存储不重复的元素,而HashMap专注于存储键值对映射。 本学习指南适合已经具备Java语言入门水平的学习者。它旨在引导学习者通过阅读和分析JDK源码来深入理解集合类的...

    实用数据结构教程_Java语言描述

    数据结构是计算机科学中的核心概念,它涉及到如何在内存中有效地组织和管理数据,以便进行高效的操作。在Java编程中,理解数据结构至关重要,因为它们是构建复杂算法和应用程序的基础。"实用数据结构教程_Java语言...

    java集合框架全面进阶[归纳].pdf

    Java集合框架是Java编程语言中的核心部分,它提供了一种高效...通过学习Java集合框架,开发者可以熟练地处理各种数据结构,实现高效的代码,同时理解这些结构背后的数学原理,这对于编写高质量的Java应用程序至关重要。

    大公司最喜欢问的Java集合类面试题.zip

    在Java编程领域,集合类是面试中不可或缺的一部分,尤其对于大型公司来说,它们通常会深入探究候选人在集合类的理解和应用能力。Java集合框架是Java SE API中的核心部分,它提供了用于存储和操作对象的数据结构和...

Global site tag (gtag.js) - Google Analytics