您的位置 首页 java

Java 17 Set 接口知识点

Java 17 Set 接口知识点

思维导图

对于 Set 集合, 它是一个不可包含重复元素的集合。对于添加方法实现了限制重复元素的条件。对于 Set 接口有三个通用的实现, 分别是:

  • HashSet:将元素存储在 哈希表 中,是性能最佳的实现。但是它只保证不重复元素, 但是不保证元素的顺序。
  • TreeSet:将元素存储在 红黑树 中,根据元素的值对其元素进行排序。
  • LinkedHashSet:它是作为哈希表实现的, 其中的实现规则是包含了一个 链表 ,它根据元素插入到集合中的顺序对其元素进行排序。

它的用途包含不限于, 对于包含相同元素的元素集合, 可以消除对应的所有重复项。

Set 接口

接口的定义:

 public interface Set<E>  extends  Collection<E>   

通过查看 Set 的 第一手资料 API。地址: java /util/Set.html

可以知道和 Set 接口相关的知识点包含:Collection、HashSet、TreeSet、 Abstract Set、SortedSet。

根据上两篇内容知道, 有抽象类的时候, 已经是因为接口中有些通用的方法可以中间抽出来一层, 不需要所有的都又最下层实现类进行实现。 Collection 详解, 可以参考上面针对 Collection 讲解的知识点。

AbstractSet

接下来, 我们来看看 AbstractSet 抽象类。

抽象类 的定义:

 public abstract class AbstractSet<E>
    extends AbstractCollection<E>
    implements Set<E>  

此抽象类, 主要是提供了 Set <E> 接口的实现,在最大程度上减少了实现此接口所需要的工作量。

这里需要注意, 对于 AbstractSet 抽象类并没有重写类中的任何实现, 只是添加了 AbstractCollection 抽象类的 equals、 hashCode 、removeAll 的实现。

方法的含义:

HashSet

现在说说 HashSet 类, 实现了 Set 接口, 并且继承 AbstractSet 抽象类。

类的定义:

 public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable  

此类的实现是有哈希表支持的接口。 但是内部的实现是使用 HashMap 实现的。该实现不保证迭代的顺序, 也就是说随着使用变化, 顺序不会保持不变。

并且该集合不是同步的, 如果 多线程 访问的情况下, 使用的时候就需要注意需要同步该哈希集合。 否则会出现数据不一致的情况。

可以使用如下代码进行同步使用:

 Set sHashSet = Collections. synchronized Set([HashSet集合]);  

该类的API 文档如下:

使用案例, 字符串 去重:

再看一个例子。

我们按照顺序插入到 HashSet 集合中的数据, 在读取的时候顺序并不会按照插入的顺序进行读取。 所以想要读取顺序和写入的顺序一致怎么办呢?

LinkedHashSet

这个类是基于哈希表和链表基于 Set 实现的。 并且类继承自 HashSet 类。

 public class LinkedHashSet<E>
    extends HashSet<E>
    implements Set<E>, Cloneable, java.io.Serializable   

该集合同样不是同步的。 异步使用可以使用封装类 Collections。

 Set s = Collections.synchronizedSet([LinkedHashSet集合]);  

API 文档如下:

重新按照 HashSet 的代码改造如下:

 import java.util.LinkedHashSet;
import java.util.Set;

public class LinkedHashSetTest {
    public  static   void  main(String[] args) {
        Set<String> set = new LinkedHashSet<>();
        for (int i = 10; i < 30; i++) {
            set.add(String.valueOf(i));
            System.out.print(" " + i);
        }
        System.out.println();

        for (String str : set) {
            System.out.print(" " +  str);
        }
        System.out.println();
    }
    
}  

该方法可以用于网站的菜单动态展示中, 接口返回按照指定顺序返回菜单数据中。 当然也可以指定用户权限。 不同的应用之间可能存在重复的权限, 对于权限来说有没有必要重复, 所以可以按照这种格式去重就得到了唯一的权限值。 处理一次, 后续都能减少遍历次数。

TreeSet

对于 TreeSet 类实现了 NavigableSet 接口, 并且基于 TreeMap 实现。该集合提供两种排序方式, 默认的情况下按照自然排序, 另外一种方式就是重写 Comparator 进行排序。

定义格式:

 public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable  

基础代码演示:

上面的代码正常允许, 并且保证了其顺序, 这个时候, 如果传入的数据是个对象。 例如下面的代码:

上面的代码虽然可以正常编译, 但是无法运行。错误信息如下:

这个错误的原因是因为并没有给 MenuInfo 的类重写对应的比较方法。 所以无法转换成对应的比较接口。

修改方式也很简单, 只需要 MenuInfo 实现 Comparable 接口就好了。

 class MenuInfo implements Comparable<MenuInfo>{
     private  String id;
    private String name;
    public MenuInfo(String id, String name){
        this.id = id;
        this.name = name;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "MenuInfo [id=" + id + ", name=" + name + "]";
    }
    @Override
    public int compareTo(MenuInfo o) {
        return 0;
    }
}  

compareTo (Object o) 方法通常有三个返回值: -1、0、1。

分别代表的含义是:

  • 1 代表着插入新的元素永远比上一个元素大, 这样读取的时候就是正序的排序了。
  • 0 代表着数据相等。 相等的元素集合只会保留一个。 所以集合都等于 0 的情况下该集合只有一条数据了。
  • -1 代表着插入的新元素永远比上一个元素小, 这样读取的时候就是倒序的排序了。

演示一下等于 0 的情况。

当等于 1 时,和插入顺序一致。

当等于 -1 式。 插入的顺序是倒序。

以上只是强制的根据插入数据走, 真实的情况是要和当前数据业务匹配的。

compareTo 代码可以修改如下:

 public int compareTo(MenuInfo o) {
    if(this.id.equals(o.id)){return 0;}
    int i = Integer.parseInt(this.id) <  Integer.parseInt(o.id) ? 1 : -1 ;
    return i;
}  

compareTo 也可以用于两个相同类型数据的比较。 比较规则如下:

  • 如果指定的数与方法参数相等返回 0。
  • 如果指定的数小于方法参数返回 -1。
  • 如果指定的数大于方法参数返回 1。
 int a = 10; 
x.compareTo(3); // 结果为 1
x.compareTo(10);// 结果为 0
x.compareTo(18);// 结果为 -1   

最终演示代码如下:

多多理解 compareTo 的概念。 这个在排序的方法中使用很广。

Set 接口和相关的实现, 小案例演示就到这了。 有什么问题, 随时评论区见。

当你纠结学习哪一个 编程语言 好的时候, 其实不防先把其中一个学精通,到达这领域的专家级别,在别的编程语言的学习的时候,就会变得更容易。因为很多知识点都是相同的, 本人是在这方面是走了很多弯路。各种语言的语法记住的挺多。 但是这只是流于表面的。要多学习“ 内核 ”的东西。 一个编程语言学习的是其内核, 除非你一致想做一个高级新手。 加油吧!

点赞,关注, 收藏。 码字不易。 感谢!

文章来源:智云一二三科技

文章标题:Java 17 Set 接口知识点

文章地址:https://www.zhihuclub.com/174778.shtml

关于作者: 智云科技

热门文章

网站地图