java集合详解|Hashset的增删改查实战,以及迭代器、泛型、equals和hashcode等集合优化工具

发布于:2023-01-19 ⋅ 阅读:(430) ⋅ 点赞:(0)

一、set定义

1、Set

是元素无序并且不可以重复的集合,被称为集。

2、hashset

HashSet是Set的一个重要实现类,称为哈希集
HashSet中的元素无序并且不可以重复
HashSet中只允许一个null元素【因为不可重复性】
具有良好的存取和查找性能

二、hashset的增加

1、增加

HashSet  cat=new HashSet();
cat.add(c);

先创建好hashset这个类的引用cat,
再通过add()方法将值存储到集合中

2、增加两个内容相同的对象

Cat c=new Cat("朵朵",2,"布偶");
Cat c2=new Cat("朵朵",2,"布偶");

打印一下结果,会发现有两条一模一样的数据。这似乎和hashset的不可重复性违背。
但其实并不是这样,这两条内容的引用地址不同,就会添加到一起。

在这里插入图片描述

3、剔除重复性的引用——equals和hashcode()组合

hashcode()

1、是为了减少寻找某数的步骤,提高查找的速度。如arraylist需要依次遍历数,才能找到正确的值。

2、而hashcode通过某种定义好的算法,将集合中的值按照某种方式计算出哈希码,根据哈希码分组,分别存储在若干个存储区域。

3、如果需要查找的内容和某个区域的哈希码相同,那么就在符合的区域中遍历。反之,则跳过这个集合。

equals

【有2种写法,只细讲第一种的代码】

   public boolean equals(Object o) {
        if (this == o) return true;

        if(o.getClass()==Cat.class){
            Cat cat=(Cat) o;
            return getAge() == cat.getAge() &&
                    Objects.equals(getName(), cat.getName()) &&
                    Objects.equals(getSpecies(), cat.getSpecies());
        }



        return false;
    }

1、this是当前类的对象,o是传进来的对象
if (this == o) return true;
即判断传入的类的名字是否相等。比如两个对象都是Cat。

2、第二个if中的判断条件是,如果传进来的对象o所对应的class是否是cat的对象的class
如果相等,那么再进一步比较类中的三个属性,name、age、species的值。

3、如果传入的数据hashcode值不相等,那么就绝对不会重复。【因为hashcode相当于已有的几种类型】

接着就会比较equals的值。如果是TRUE的话,那么就会hashset则不会将该条数据加入集合。如果是FALSE,则会加入。

   public boolean equals(Object o) {
        if (this == o) return true;

       if (!(o instanceof Cat)) return false;
        Cat cat = (Cat) o;
       
        return getAge() == cat.getAge() &&
                Objects.equals(getName(), cat.getName()) &&
                Objects.equals(getSpecies(), cat.getSpecies());
    }

三、删除

1、删除一条数据

cat.remove(c)

2、删除多条数据

则要先将满足条件的对象装入新的集合中

cat.remove(新的集合cat2);

同时要用到增强型for循环【在第四部分详细介绍】

HashSet <Cat> cat2=new HashSet <Cat> ();
for(Cat c7:cat){
    if(c7.getAge()<2){
        cat2.add(c7);
    }
}
cat.removeAll(cat2);

四、集合优化方式

1、泛型

防止强制类型转换时出错,直接在hashset集合创建的时候,就限制只能添加cat的实例对象。
操作步骤:在类名的后面和接口名的后面加上cat。

HashSet <Cat> cat2=new HashSet <Cat> ();

同理,如果迭代器要限制,也可以在创建时后面加上cat。

Iterator <Cat> it2=cat.iterator();

这样就能省去中的cat的强制转换。

    System.out.println(((Cat)(it2.next())).toString());
}

2、迭代器—打印集合内容

【由于set没有get元素的方法,需要借助迭代器打印】
集合在打印的过程中,

Iterator it2=cat.iterator();
  while(it2.hasNext()) {
    System.out.println(((Cat)(it2.next())).toString());
}

hasNext()是判断集合中是否还有下一个值,如果有,就为TRUE。
it2.next()是取出集合中的下一个值。

注意:
但如果打印的语句是System.out.println(((Cat)(it2.next())),取出的内容是

com.company.Cat@3079e610

这种地址需要在Cat类中增加tostring方法
将地址返回出类属性的字符串

@Override
public String toString() {
    return "{" +
            "姓名='" + name + '\'' +
            ", 年龄=" + age +
            ", 类型='" + species + '\'' +
            '}';
}

PS:每次要输出集合内容时,都要重新创建一个迭代器的引用对象。
因为上一个迭代器在前面执行过程中,已经将迭代器中的集合值遍历过一遍了,再次调用输出,很可能会空。

3、增强型for循环

    使用增强型for循环删除名叫“”小灰“的”猫的信息
for(Cat c6:cat){
    if(c6.getName()=="小灰"){
    //或者判断条件写作:"小灰".equals(c6.getName())
        System.out.println("找到小灰的信息"+c6.toString());
        cat.remove(c6);
    }
    //下面是错误且多余的语句
    else{
        System.out.println("没有小灰这只猫");
    }

增强型for循环的格式是

类名 对象名:要循环的集合或列表名

1、注意由于set的长度是动态变化的,如果删除了一个值后,再进行遍历,可能会报错。应该在if语句后加上break,满足条件后就结束循环。

2、在增强型for循环中判断时,不要出现ifelse语句,这样有很大可能出现在for循环满足FALSE和满足TRUE的情况。

ps、布尔值flag的运用

1)用于查找某个值是否存在
2)通常初始化为TRUE。
3)根据布尔值的类型,输出对应的提示语句

//寻找小黄的信息
Cat c5=null;
Iterator <Cat> it3=cat.iterator();
boolean flag=true;
while(it3.hasNext()){
    c5= it3.next();
    if(c5.getName()=="小黄"){

        break;
    }else{
        flag=true;
    }

}
if(flag){
    System.out.println("找到小黄的信息了!");
    System.out.println(c5.toString());
}else{
    System.out.println("找不到小黄的信息~");
}

温馨提示💓

如果在运用hashset时遇到问题,可以直接关注并私信我,发送报错问题,我看到后会第一时间回复~

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到