我们知道list存储的是有序不唯一的元素。

set存储的是无序唯一的元素。

那么下面看一个例子吧:

package CollectionPart;

import java.util.HashSet;
import java.util.Set; public class HashSet1 {
public static void main(String[] args) {
Set mySet = new HashSet();
mySet.add("df");
mySet.add("df");
System.out.println(mySet.size());
for (Object object : mySet) {
System.out.println(object);
}
}
}

运行结果:

1
df

这就充分说明了,set集合里面存储的元素是唯一的。

那么如下代码将会反映一个问题:

package CollectionPart;

import java.util.HashSet;
import java.util.Set; public class HashSet1 {
public static void main(String[] args) {
Set mySet = new HashSet();
mySet.add("df");
mySet.add("df"); Employee_1 e1 = new Employee_1("1","lifei",23,"2013-02-09");
Employee_1 e2 = new Employee_1("1","lifei",23,"2013-02-09"); mySet.add(e1);
mySet.add(e2); System.out.println(mySet.size());
for (Object object : mySet) {
System.out.println(object);
}
}
}

运行结果:

3
df
Employee_1 [employeeId=1, employeeName=lifei, employeeAge=23, employeeHireDate=2013-02-09]
Employee_1 [employeeId=1, employeeName=lifei, employeeAge=23, employeeHireDate=2013-02-09]

我们存储的元素明明一模一样,但是结果好像不如人意,不是说好set里面存储的都是不同的元素么,e1 跟e2明显是 同一个对象。

这就需要考量set集合在判定元素是否相等的时候,是通过什么进行判别的。

鼠标移到这个 add方法上面就会有提示:

Adds the specified element to this set if it is not already present. More formally, adds the specified element e to this set if this set contains no element e2 such that (e==null ? e2==null : e.equals(e2)). If this set already contains the element, the call leaves the set unchanged and returns false.

这个说明还是有必要读一下的:添加特定元素给set集合,如果不存在这样一个元素的时候。通常情况下,为当前set集合添加元素e时,如果这个set集合没有已经存在一个e2的话,【通过equals函数来比较】如果已经存在此元素的话,那么add方法的调用并不会修改set集合,并且会返回false。

//有两个点要试:1、null的值可以存储几个,从说明上感觉是1个。2、第二次添加已经存在的元素的时候,会报添加失败,而不是第二次的值覆盖第一次的值。这个是纯想象的,因为覆盖就有添加了一次,这感觉上会产生更多的操作。不如不允许添加来的效率高。

package CollectionPart;

import java.util.HashSet;
import java.util.Set; public class HashSet1 {
public static void main(String[] args) {
Set mySet = new HashSet();
mySet.add("df");
boolean add = mySet.add("df"); System.out.println("是否添加成功:"+add);
Employee_1 e1 = new Employee_1("1","lifei",23,"2013-02-09");
Employee_1 e2 = new Employee_1("1","lifei",23,"2013-02-09"); mySet.add(e1);
mySet.add(e2); System.out.println(mySet.size());
for (Object object : mySet) {
System.out.println(object);
}
mySet.add(null);
boolean add2 = mySet.add(null);
System.out.println("是否添加成功:"+add2+",此时set集合中的元素个数:"+mySet.size());
}
}

运行结果:

是否添加成功:false
3
df
Employee_1 [employeeId=1, employeeName=lifei, employeeAge=23, employeeHireDate=2013-02-09]
Employee_1 [employeeId=1, employeeName=lifei, employeeAge=23, employeeHireDate=2013-02-09]
是否添加成功:false,此时set集合中的元素个数:4

接下来就要处理,这个 equals的问题了,就可以回去考究这个 set集合中对于元素的equals的方法的比较了,毕竟,e1 跟e2 是一个人。要想办法,把它们区分开。查看默认的 Employee中的equals方法

我们所写的员工类里面并没有一个 equals方法,说明这是 继承来的:所以敲出equals 坐等联想然后得到这样一个函数:

@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
return super.equals(obj);
}

鼠标放在 equals上面得到这样一个说明:

Indicates whether some other object is "equal to" this one.

The equals method implements an equivalence relation on non-null object references:

  • It is reflexive: for any non-null reference value x, x.equals(x) should return true.
  • It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
  • It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
  • It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
  • For any non-null reference value x, x.equals(null) should return false.

The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true).

Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.

简单翻译一下:欢迎斧正,

判断其他的对象是否与当前对象相等。

反射性?reflexive?:对于任何值,x.equals(s) 应该返回true.

对称性:对于非空值x,y,如果x.equals(y)返回true时,当且仅当y.equals(x)也返回true.

传递性:对于非空值x,y和z,如果 x.equals(y)返回true,y.equals(z)返回true,那么x.equals(z)应该也返回true.

一致性?:不论怎么调用,结果都应该是一致的,要么true,要么false,当参与比较的两个非空值,x,y,在这种不断地比较过程中始终未被修改的时候。

对于非空值 x,x.equals(null) 的返回值应该是false.

equals方法用来描述object类中两个对象是否相等的关系,如果非空值x,y的返回结果是true的话,那么x,y执行的是相同的实体。

注:通常情况下也要重写hashCode方法,只要equals方法被重写。为了hashCode方法保持总体联系,为了标明相同的对象具有相同的hash码。

所以,这才是 Set集合要注意的地方,只要使用Set集合的话,就要记得重写equals 方法和 hashCode方法。【好在这两个方法都可以自动生成。】

在ssh里面,如果用到多对多的情况的时候,要记得重写这两个方法。

不过重点好像还是没有解释清楚。就是 e1 究竟为什么不等于e2.

我们通过快捷键ctrl+鼠标左键,找到他的实现方法:

public boolean equals(Object obj) {
return (this == obj);
}

发现。他们在底层调用的就是这样的语句,那么问题来了,这比较的是什么,this指代的是什么?我们通常在校验是否空指针的时候总会,输出一下,当前对象。那么这个比较就是返回的当前这个 对象的地址值,如果 这个 值不相等的话,就认为两者不相等。好了,那么现在我们认为 id相同并且,姓名相同的话,这两个元素就是一个实体,事实上,最好把所有属性都包含进去,但是 可以利用后期系统的某些存在唯一性约束的属性,作为两个实体是否相等的标识。

Set集合要说明的就是这一个一定要重写 equals() 方法和 hashCode()方法,别的没有了。

习题:打印员工姓名及性别,利用迭代器遍历

员工的字段有 工号 姓名 年龄 入职时间。

由于改写了 员工类的 不妨新写一个 实体类。

//写的时候 复制的,所以 就输出 姓名和年龄吧

package CollectionPart;

/**
* 为了Set的联系,比Employee_1多重写了两个方法
*
*/
public class Employee_2 { private String employeeId;
private String employeeName;
private int employeeAge;
private String employeeHireDate;
/*
这里就存储成String 类型,在 数据库里面设置成 date格式。
然后 利用Date today = new Date();
SimpleDateFormat fm = new SimpleDateFormat("YYYY-MM-dd");
来做
*/
public String getEmployeeId() {
return employeeId;
}
public void setEmployeeId(String employeeId) {
this.employeeId = employeeId;
}
public String getEmployeeName() {
return employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
public int getEmployeeAge() {
return employeeAge;
}
public void setEmployeeAge(int employeeAge) {
this.employeeAge = employeeAge;
}
public String getEmployeeHireDate() {
return employeeHireDate;
}
public void setEmployeeHireDate(String employeeHireDate) {
this.employeeHireDate = employeeHireDate;
}
@Override
public String toString() {
return "Employee_1 [employeeId=" + employeeId + ", employeeName=" + employeeName + ", employeeAge="
+ employeeAge + ", employeeHireDate=" + employeeHireDate + "]";
}
public Employee_2(String employeeId, String employeeName, int employeeAge, String employeeHireDate) {
super();
this.employeeId = employeeId;
this.employeeName = employeeName;
this.employeeAge = employeeAge;
this.employeeHireDate = employeeHireDate;
}
public Employee_2() {
super();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + employeeAge;
result = prime * result + ((employeeHireDate == null) ? 0 : employeeHireDate.hashCode());
result = prime * result + ((employeeId == null) ? 0 : employeeId.hashCode());
result = prime * result + ((employeeName == null) ? 0 : employeeName.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;
Employee_2 other = (Employee_2) obj;
if (employeeAge != other.employeeAge)
return false;
if (employeeHireDate == null) {
if (other.employeeHireDate != null)
return false;
} else if (!employeeHireDate.equals(other.employeeHireDate))
return false;
if (employeeId == null) {
if (other.employeeId != null)
return false;
} else if (!employeeId.equals(other.employeeId))
return false;
if (employeeName == null) {
if (other.employeeName != null)
return false;
} else if (!employeeName.equals(other.employeeName))
return false;
return true;
}
}
package CollectionPart;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set; public class HashSetPractise_1 {
public static void main(String[] args) {
Employee_2 e1= new Employee_2("dept1_001", "lifei", 23, "2016-02-05");
Employee_2 e2= new Employee_2("dept1_001", "lifei", 23, "2016-02-05");
Employee_2 e3= new Employee_2("dept1_002", "life2", 24, "2016-03-05");
Employee_2 e4= new Employee_2("dept3_001", "life3", 28, "2015-03-05");
Set<Employee_2> mySet = new HashSet<Employee_2>();
mySet.add(e1);
mySet.add(e2);
mySet.add(e3);
mySet.add(e4);
Iterator<Employee_2> iterator = mySet.iterator();
System.out.println("员工人数为:"+mySet.size());
while (iterator.hasNext()) {
Employee_2 employee_2 = iterator.next();
System.out.println("当前员工: "+employee_2.getEmployeeName()+" ,年龄为:"+employee_2.getEmployeeAge());
}
}
}

运行结果:

员工人数为:3
当前员工: life3 ,年龄为:28
当前员工: lifei ,年龄为:23
当前员工: life2 ,年龄为:24

发现一个事儿,就是 确实是无序的。

集合练习——Set部分的更多相关文章

  1. java基础集合经典训练题

    第一题:要求产生10个随机的字符串,每一个字符串互相不重复,每一个字符串中组成的字符(a-zA-Z0-9)也不相同,每个字符串长度为10; 分析:*1.看到这个题目,或许你脑海中会想到很多方法,比如判 ...

  2. .Net多线程编程—并发集合

    并发集合 1 为什么使用并发集合? 原因主要有以下几点: System.Collections和System.Collections.Generic名称空间中所提供的经典列表.集合和数组都不是线程安全 ...

  3. 一起学 Java(三) 集合框架、数据结构、泛型

    一.Java 集合框架 集合框架是一个用来代表和操纵集合的统一架构.所有的集合框架都包含如下内容: 接口:是代表集合的抽象数据类型.接口允许集合独立操纵其代表的细节.在面向对象的语言,接口通常形成一个 ...

  4. 编写高质量代码:改善Java程序的151个建议(第5章:数组和集合___建议75~78)

    建议75:集合中的元素必须做到compareTo和equals同步 实现了Comparable接口的元素就可以排序,compareTo方法是Comparable接口要求必须实现的,它与equals方法 ...

  5. java基础_集合List与Set接口

    List接口继承了Collection的方法  当然也有自己特有的方法向指定位置添加元素   add(索引,添加的元素); 移除指定索引的元素   remove(索引) 修改指定索引的元素   set ...

  6. Java基础Collection集合

    1.Collection是所有集合的父类,在JDK1.5之后又加入了Iterable超级类(可以不用了解) 2.学习集合从Collection开始,所有集合都继承了他的方法 集合结构如图:

  7. 轻量级“集合”迭代器-Generator

    Generator是PHP 5.5加入的新语言特性.但是,它似乎并没有被很多PHP开发者广泛采用.因此,在我们了解PHP 7对Generator的改进之前,我们先通过一个简单却显而易见的例子来了解下G ...

  8. Asp.net MVC 传递数据 从前台到后台,包括单个对象,多个对象,集合

    今天为大家分享下 Asp.net MVC 将数据从前台传递到后台的几种方式. 环境:VS2013,MVC5.0框架 1.基本数据类型 我们常见有传递 int, string, bool, double ...

  9. 这些.NET开源项目你知道吗?.NET平台开源文档与报表处理组件集合(三)

    在前2篇文章这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧 和这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧!(第二辑)中,大伙热情高涨.再次拿出自己的私货,在.NET平台 ...

  10. python 数据类型 --- 集合

    1. 注意列表和集合的区别 set 列表表现形式: list_1 = [1,3,4];  集合表现形式:set_1= set() list_1 = [1,2,3,4,23,4,2] print(lis ...

随机推荐

  1. Android开发之PackageManager类

    PackageManger,可以获取到手机上所有的App,并可以获取到每个App中清单文件的所有内容. 设置应用程序版本号在应用程序的manifest文件中定义应用程序版本信息.2个必须同时定义的属性 ...

  2. 2016年中国500强利润率最高的公司,中国500强最赚钱的40家公司,ROE最高的公司

    2016年中国500强利润率最高的公司     排名 公司名称 利润率 62 阿里巴巴集团控股有限公司 73.09% 87 百度股份有限公司 50.71% 195 国信证券股份有限公司 47.87% ...

  3. 在SQL2005实现维护计划-备份数据库

    一.備份數據庫維護計劃方案 [注]: 1.先啟動SQL Server Agent服務 2..交易記錄備份 (只限於完整和大量記錄復原模式). 3.下面中”清除備份trn文件” & “清除備份日 ...

  4. 函数的重载与 泛型(generic)有什么不同?

    函数重载指   重载函数,形参(类型)不同,实现的功能一样. 泛型算法指2个方面:这些算法可作用于各种不同的容器类型,而这些容器类型又可以容纳多种不同类型的元素.

  5. 数据结构:二级指针与Stack的数组实现

    [简介] Stack,栈结构,即传统的LIFO,后进先出,常用的实现方法有数组法和链表法两种.如果看过我上一篇文章<数据结构:二级指针与不含表头的单链表>,一定会看到其中的关键在于,利用v ...

  6. CodeForcesGym 100753B Bounty Hunter II 二分图最小路径覆盖

    关键在建图 题解:http://www.cnblogs.com/crackpotisback/p/4856159.html 学习:http://www.cnblogs.com/jackiesteed/ ...

  7. Fatjar成功安装记录

    1.FatJar安装方式 (1)在线安装 具体网址http://kurucz-grafika.de/fatjar (2)离线安装 将fatjar的jar放到plugins文件夹中,重启 2. 安装失败 ...

  8. wuzhicms查找:当前页面使用的哪个文件

    要查看这个地址的模版.http://www.wuzhicms.com/item-34-2-1.html 首先,我们的这个地址需要是动态的.而不是生成的静态地址. 打开文件: /www/configs/ ...

  9. vijosP1413 Valentine’s Present

    vijosP1413 Valentine’s Present 链接:https://vijos.org/p/1413 [思路] 组合公式. 由题目知:每个箱子中的蛋糕要么与箱子颜色相同,要么指向一个蛋 ...

  10. 定时备份为Sharepoint做网站备份,并删除指定日期的备份

    一.创建bat文件 @echo cd \ c: cd "Program Files\Common Files\Microsoft Shared\web server extensions\1 ...