[基础数据结构|Java实现]一:HashSet

HashSet的基本概念:

  • 元素不能重复
  • 不能保证顺序

💓为了实现简单,规定只能存储String,不能为Null,并且区分大小写。

实现思路:

底层用一个数组做为,然后每个桶都绑定一个链表;添加的每个元素都先计算其hash值,并对数组的长度取模,然后得到桶的索引,再利用equal判断是否需要添加到链表中即可。

缺陷:

  • java中的hashSet链表的长度达到某个值时,会自动转换为红黑树存储(目前没有实现)。
  • 目前没有实现扩容,后续实现Redis里面的字典(或者说是map)时,会对扩容的部分进行实现。

在这里插入图片描述

具体实现要求:

  • 底层提供一个大小固定的容器 buf

  • 计算hashCode,并对hashCode取模,从而获取索引

  • 解决索引冲突(用链表存储索引相同的元素)

  • 扩容策略(暂时先不实现,后面实现Redis中的字典时,再用java实现Redis中字典的扩容策略)

  • 保存size

  • 遍历操作

  • 查询操作

  • 删除操作

  • 添加操作

Java实现代码:

package basic.hashset;

public class StringHashSet {

    private int capacity ;

    private int size;

    private Node [] buf;

    public StringHashSet(){
        this.capacity = 10;
        this.size = 0;
        this.buf = new Node[capacity];
    }

    public StringHashSet(int capacity){
        this.capacity = capacity;
        this.size = 0;
        this.buf = new Node[capacity];
    }


    private static class Node{
        String val;
        Node next;

        public Node(String var){
            this.val = var;
            this.next = null;
        }


    }

    public boolean add(String val){

        int index = val.hashCode()%this.capacity;
        Node node = new Node(val);
        if(buf[index] == null){
            buf[index] = node;
        }else {//使用链表存储
            if(isContain(buf[index],val))
                return false;
            addOnLast(buf[index], node);
        }
        size++;
        return true;
    }

    //遍历操作
    public void printAll(){
        System.out.println("========begin print==========");
        for(int i=0;i<buf.length;i++){
            System.out.println("index "+i+" : ");
            print(buf[i]);
        }
    }

    //打印链表
    private void print(Node node){
        while (node != null){
            System.out.print(node.val+"->");
            node = node.next;
        }
        System.out.println();
    }

    //判断值是否相同
    private boolean isContain(Node node,String val){
        while (node != null){
            if(node.val.equals(val))
                return true;
            else
                node = node.next;
        }
        return false;
    }
    //将node添加到root的尾部节点
    private void addOnLast(Node root, Node node){
        while (root.next != null){
            root = root.next;
        }
        root.next = node;
    }

    public boolean contains(String val){
        for(int i=0;i<buf.length;i++){
            if(isContain(buf[i],val))
                return true;
        }
        return false;
    }

    public void addAll(Iterable<String> list){
        list.forEach( val ->{
            add(val);
        });
    }

    public int size(){
        return this.size;
    }

    public boolean remove(String val){
        //如果不包含,则直接返回fasle
        if(!contains(val))
            return false;

        for(int i=0;i<buf.length;i++){
            if(buf[i] != null){
                Node node = removeNode(buf[i], val);
                if(node != null){
                    buf[i] = node;
                }
            }
        }
        size--;
        return true;
    }

    private Node removeNode(Node root,String val){
        Node begin = root;
        if(root.val.equals(val)){
            root = root.next;
            return root;
        }else {
            while (root.next != null){
                 Node pro = root;
                 root = root.next;
                 if(root.val.equals(val)){
                     if(root.next != null){
                         Node temp = root.next;
                         pro.next = temp;
                     }else {
                         pro.next = null;
                     }
                     return begin;
                 }
             }
        }
        return null;
    }


}

测试代码:

public static void main(String[] args) {

    StringHashSet stringHashSet = new StringHashSet(3);
    boolean add = stringHashSet.add("hello");
    System.out.println(add);
    stringHashSet.printAll();
    boolean add2 = stringHashSet.add("hello");
    System.out.println(add2);
    stringHashSet.printAll();
    boolean add3 = stringHashSet.add("fuck");
    System.out.println(add3);
    stringHashSet.printAll();

    //测试查找
    System.out.println(stringHashSet.contains("hello"));

    //测试批量插入
    List<String> list = new LinkedList<>();
    Collections.addAll(list,"a","b","a","b","c","d","e","ggg","abc");
    stringHashSet.addAll(list);

    stringHashSet.printAll();


    //测试容量
    int size = stringHashSet.size();
    System.out.println(size);
    //测试删除
    System.out.println(stringHashSet.remove("fuck"));
    stringHashSet.printAll();
    System.out.println(stringHashSet.size());
    System.out.println(stringHashSet.remove("xxx"));
    stringHashSet.printAll();
    System.out.println(stringHashSet.size());

}

测试结果:

true
========begin print==========
index 0 : 

index 1 : 
hello->
index 2 : 

false
========begin print==========
index 0 : 

index 1 : 
hello->
index 2 : 

true
========begin print==========
index 0 : 

index 1 : 
hello->
index 2 : 
fuck->
true
========begin print==========
index 0 : 
c->ggg->abc->
index 1 : 
hello->a->d->
index 2 : 
fuck->b->e->
9
true
========begin print==========
index 0 : 
c->ggg->abc->
index 1 : 
hello->a->d->
index 2 : 
b->e->
8
false
========begin print==========
index 0 : 
c->ggg->abc->
index 1 : 
hello->a->d->
index 2 : 
b->e->
8

Process finished with exit code 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值