本节主要是为了搞懂
1.为什么重写equals方法和hashcode的作用
2.ListIterator的使用
3.Set的不允许重复性的背后
首先新建一个实体类
package utilbag;
public class User {
private String user_id;
private String user_name;
public User(){
}
public User(String user_id,String user_name){
this.user_id=user_id;
this.user_name=user_name;
}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
public String toString(){
return "[user_id"+user_id+",user_name="+user_name+"]";
}
//重写了equals方法
public boolean equals(Object obj){
if (this == obj) {
return true;
}
if(obj==null){
return false;
}
if(!(obj instanceof User)){
return false;
}
if(this.user_id==null || this.user_name==null){
return false;
}
User u=(User)obj;
return(this.user_id.equals(u.user_id) && this.user_name.equals(u.user_name));
}
//重写hansCode方法
public int hashCode(){
return this.user_id.hashCode()*this.user_name.hashCode();
}
/*String的hashCode()写法如下
public int hashCode()
{
int i = this.hash;
if (i == 0) {
int j = this.offset;
char[] arrayOfChar = this.value;
int k = this.count;
for (int l = 0; l < k; ++l) {
i = 31 * i + arrayOfChar[(j++)];
}
this.hash = i;
}
return i;
}
*/
}
//新建测试类
package utilbag;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;
public class TestUtil {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//List序列的用法
System.out.println("/***************测试List的用法*****************************/");
List<String> list=new ArrayList<String>();
list.add("100");
list.add("200");
list.add("300");
/***************Iterator单项向前遍历*****************************/
Iterator<String> itera=list.iterator();
while(itera.hasNext()){
System.out.println(itera.next());
}
/***************ListIterator双向遍历*****************************/
ListIterator<String> ite=list.listIterator(2);//从第3个开始遍历
/***************向后遍历*****************************/
while(ite.hasNext()){
System.out.println(ite.next());//指下一个元素
System.out.println(ite.nextIndex());//指下一个元素的下标
}
/***************向前遍历*****************************/
while(ite.hasPrevious()){
System.out.println(ite.previous());//指前一个元素
System.out.println(ite.previousIndex());//指上一元素的下标
}
//Set的用法
System.out.println("/***************测试Set的用法*****************************/");
Set<String> set=new HashSet<String>();
set.add("1");
set.add("2");
set.add("1");//重复的元素不会加到set集合中,加入的对象必须事先hashcode
set.add("3");
Iterator<String> it=set.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//打印出:3,2,1这3个元素
Set<User> su=new HashSet<User>();
User u1=new User("1","光光");
System.out.println(u1.hashCode());
su.add(u1);
User u2=new User("2","明明");
su.add(u2);
User u3=new User("3","天天");
su.add(u3);
User u4=new User("3","天天");
su.add(u4);
//注意不重写hashcode的方法则结果会是4个user,重写了hashcode方法,加到set中的结果是3条。//这个就是set容器不允许重复的实现方法
System.out.println("u3.hashCode()="+u3.hashCode());
System.out.println("u4.hashCode()="+u4.hashCode());
System.out.println("u3==u4结果为:"+(u3==u4));//不一样是因为他们的地址是不一样的
//在HashMap HashSet中,hashCode()是判断放进容器里的两个对象是否相等的依据。
//如果自己写容器,那就修改覆写改方法
System.out.println("u3.equals(u4)结果为:"+(u3.equals(u4)));
/**********怎么会都不相等呢,试试重写他们的equals和hashcode看看************/
Iterator<User> ituser=su.iterator();
while(ituser.hasNext()){
User uu=(User)ituser.next();
System.out.println(uu.hashCode());
System.out.println(uu);
}
String s="hello";
String s1=s;
String s2=s;
System.out.println("s1==s2:"+(s1==s2));
System.out.println("/***************测试Map的用法*****************************/");
Map<String, String> map=new HashMap<String, String>();
map.put("100", "100");
map.put("100", "200");
map.put("200", "300");
map.put("300", "400");
map.put("400", "500");
Iterator<String> imap=map.keySet().iterator();
while(imap.hasNext()){
String k=imap.next();
System.out.println(map.get(k));
//打印出来的值为400、300、500、200(无序)说明map不允许有重复的键(值可以重复)
}
map.clear();
map.put("100", "100");
map.put("500", "500");
map.put("200", null);
map.put("300", null);
map.put("400", null);
Iterator<String> iimap=map.keySet().iterator();
while(iimap.hasNext()){
String k1=iimap.next();
System.out.println(map.get(k1));
//System.out.println(iimap.get(k1));
//打印出来的值为null,null,null,100,500(无序)说明map不允许有重复的键(值可以重复,而且可以为null)
}
Iterator<Entry<String, String>> ie=map.entrySet().iterator();
while(ie.hasNext()){
Map.Entry<String, String> mp=ie.next();
System.out.println(mp.getKey()+":"+mp.getValue());
//打印出来
//300:null
//200:null
//400:null
//100:100
//500:500
}
map.clear();
map.put(null, null);
map.put(null, null);
map.put("100", "2");
map.put("100", null);
Iterator ie1=map.entrySet().iterator();
while(ie1.hasNext()){
Map.Entry<String, String> mpp=(Map.Entry<String, String>)ie1.next();
System.out.println(mpp.getKey()+":"+mpp.getValue());
//打印出来只有一个null:null,100:null因为它覆盖了前面的100:2
//键值不允许重复
}
}
}
总结:
1.在HashMap HashSet中,hashCode()是判断放进容器里的两个对象是否相等的依据。如果自己写容器,那就修改覆写改方法 。
2.判断2个对象相等是看2个对象的地址是否相等。
3.判断2个对象相等必须同时重写equals方法和hashcode方法。例如像set中添加2个user对象,缺少2个方法中的任何一个都不可以。
4.看java源码发现,
当new 一个set时,它是在构造函数中new一个map(它的实现是基于map的)
调用set的add方法时,传过去的值是调用的是map的put方法
put(set的值当作键,new object()当作值);
put时,它使用到了hashcode和equals方法
源码如下:
set中:
public HashSet()
{
this.map = new HashMap();
}
public boolean add(E paramE)
{
return (this.map.put(paramE, PRESENT) == null);
}
map中:
public V put(K paramK, V paramV)
{
if (paramK == null)
return putForNullKey(paramV);
int i = hash(paramK.hashCode());
int j = indexFor(i, this.table.length);
for (Entry localEntry = this.table[j]; localEntry != null; localEntry = localEntry.next)
{
Object localObject1;
if ((localEntry.hash == i) && ((((localObject1 = localEntry.key) == paramK) || (paramK.equals(localObject1))))) {
Object localObject2 = localEntry.value;
localEntry.value = paramV;
localEntry.recordAccess(this);
return localObject2;
}
}
this.modCount += 1;
addEntry(i, paramK, paramV, j);
return null;
}
现在我们知道了为什么set是不允许要加入的元素重复的了,而且要加入set的元素必须是重写了hashcode和equals,否则不能实现限制重复添加元素的功能(即set的本质,当然主要是对对象类型来说的)。
分享到:
相关推荐
Java 集合框架中 List、Set、Map 的用法和区别 Java 集合框架(Java Collections Framework)是 Java 语言中的一个重要组件,提供了一些基本的数据结构和算法来操作和存储数据。其中,List、Set、Map 是三个非常...
// java中对象容器主要有Set,List和Map三个接口类。 // 迭代器(Iterator)模式,又叫做游标(Cursor)模式。 // GOF给出的定义为:提供一种方法访问一个容器(container)对象中的各个元素, // 而又不需暴露该...
Collection, List, Set 和 Map 用法和区别 Collection 是 Java 中的一种对象...Collection、List、Set 和 Map 等集合类是 Java 中非常重要的一部分,需要深入了解其用法和区别,以便更好地使用集合类来实现业务逻辑。
在选择使用`List`、`Set`还是`Map`时,需要根据具体的应用场景和需求来决定。如果需要维护元素的顺序或允许重复元素,则可以选择`List`;如果需要确保集合中没有重复元素,则可以选择`Set`;而当需要存储键值对时,...
本文将深入探讨List和Set在使用`retainAll`方法时的效率差异,并通过`ListAndRetainAll.java`和`SetAndRetainAll.java`两个示例代码来具体分析。 首先,让我们了解`retainAll`方法的基本概念。`retainAll`是Java...
### 集合概述:set、List、Map #### 一、集合框架概述 ##### 1.1.1 容器简介 在Java编程中,集合框架是一个非常重要的概念,它提供了一种灵活的方式来存储、操作和管理不同类型的对象集合。集合框架的主要目标是...
在Java编程语言中,集合框架是处理对象组的重要工具,主要包括List、Set和Map三大接口。这些接口由Java Collection Framework提供,它是一个统一的架构,用于存储和操作各种类型的对象。接下来,我们将深入探讨这三...
1. **Collection**:这是所有单值容器的父接口,包括List和Set。 2. **List**:有序的容器,允许重复元素,支持索引访问。 3. **Set**:不允许有重复元素的容器,保持元素的唯一性。 4. **Map**:存储键值对的容器,...
在Java编程语言中,`set`、`list`和`map`是非常重要的数据结构,它们分别代表了不同的集合类型,各自有着独特的特性与用途。 - **List**:有序集合,可以包含重复元素。 - **Set**:不允许重复元素的集合,不保证...
根据给定文件的信息,我们可以详细地探讨一下Java中几种主要的集合容器——List、Set以及Map的区别,并且深入了解它们各自的特性和应用场景。 ### 一、List #### 1. ArrayList - **特点**:`ArrayList`是基于动态...
### Java集合Collection、List、Set、Map使用详解 #### 1. 集合框架概述 集合框架是Java编程语言中最基本且最重要的组成部分之一。它提供了处理数据集合的强大工具,这些工具不仅支持基本操作(如添加、删除和查找...
本文将详细解释Java集合的实现原理和其使用方法。 集合框架概述 Java集合框架是Java语言中的一种数据结构,用于存储和操作数据。集合框架提供了多种数据结构,例如Collection、List、Set、Map等,每种数据结构都有...
本文将深入探讨如何使用Java来操作Redis,包括设置和获取String、List和Map类型的数据,并且会介绍如何进行封装和单元测试。 首先,要与Redis进行交互,我们需要引入Jedis库,这是Java最常用的Redis客户端。在你的...
在Java编程语言中,集合框架是处理对象的重要工具,其中包括Set、List和Map三大接口。这些接口提供了多种数据结构和操作方法,使得开发者能够高效地组织和管理数据。 1. **Set接口**: Set接口表示一个不包含重复...
Java 集合类 List-Set-Map 的区别和联系 Java 集合类 List、Set 和 Map 是 Java 语言中最基本的集合类,它们之间存在着紧密的联系和区别。在本文中,我们将对 Java 集合类 List、Set 和 Map 的区别和联系进行详细的...
在 Java 集合框架中,`Map`、`List` 和 `Set` 是三种非常重要的数据结构,它们各自有着不同的特性和用途。 - **Map**:主要用于存储键值对(key-value pairs)。键必须是唯一的,而值可以重复。`Map` 不继承自 `...
在Java编程语言中,集合框架提供了多种数据结构来存储和操作数据,其中最常用的是`Set`、`Map`和`List`。这三种集合类型各自具有独特的特性和用途,理解它们之间的区别与联系对于有效地使用Java进行数据管理至关重要...
详细介绍了java中的list、map、set的存储方式及使用方法,涵盖了多个java大侠的见解,让读者充分了解list、map、set的区别和使用
在Java编程语言中,集合框架是处理对象组的重要工具,主要包括List、Set和Map三大类。这些接口由java.util包提供,为数据存储和操作提供了丰富的功能。下面将详细讲解如何遍历List、Set和Map这三种类型的集合。 1. ...