首页 > 其他分享 >集合框架(二)

集合框架(二)

时间:2023-11-19 12:45:39浏览次数:51  
标签:set name 框架 HashSet age 集合 new public

Set集合

Set集合是一个无序不重复的接口,里面有两个实现类HashSet和TreeSet

HashSet类

 创建HashSet的语法:

①HashSet 名称=new HashSet();
②HashSet set1=new HashSet(初始化容量数);
③HashSet set2=new HashSet(初始化容量数 ,负载因子);
负载因子:当数量到达容量的多少时进行扩容,默认75%。

举个例子:

 1 public class Test2 {
 2     public static void main(String[] args) {
 3         //创建一个无参的HashSet对象,
 4         HashSet set=new HashSet();
 5         //初始化容器的大小,初始化容量为12
 6         HashSet set1=new HashSet(12);
 7         //初始化容器的大小,并附上负载因子
 8         HashSet set2=new HashSet(12,0.7f);
 9         // (这个例子中)负载因子的概念是:当容量超过70%,进行扩容操作
10     }
11 }

添加操作

语法:

boolean  add(E e):将指定元素添加到此集合(如果尚未存在) 

举个例子:

1 public class Test2 {
2     public static void main(String[] args) {
3         //创建一个无参的HashSet对象,
4         HashSet set=new HashSet();
5         //添加一个尚未存在的元素时返回true,否则返回false
6         set.add(12);
7     }
8 }

删除操作

语法:

boolean  remove(Object o):删除指定的元素 

举个例子:

1 public class Test2 {
2     public static void main(String[] args) {
3         //创建一个无参的HashSet对象,
4         HashSet set=new HashSet();
5         //删除一个指定的元素
6         set.remove(12);
7     }
8 }

遍历操作

HashSet是一个无序不重复的结构,所以没有索引值,只能通过迭代器和增强for循环来实现遍历

①迭代器

 1 public class Test2 {
 2     public static void main(String[] args) {
 3         HashSet set = new HashSet();//生成一个HashSet集合
 4         Iterator iterator = set.iterator();//获取迭代器的对象
 5         while (iterator.hasNext()) {//判断迭代器是否存在下一个元素
 6             //存在下一个元素
 7             //获取指定元素并将指针往下移动
 8             Object object = iterator.next();
 9             System.out.println(object);
10         }
11     }
12 }

②通过foreach遍历

1 public class Test2 {
2     public static void main(String[] args) {
3         HashSet set=new HashSet();//生成一个HashSet集合
4         for(Object object:set){
5             //遍历集合内容
6             System.out.println(object);
7         }
8     }
9 }

HashSet底层结构

Set是一个无序不重复的集合,而HashSet作为Set的子实现类,它是如何实现无序不重复的呢?

①底层使用哈希表实现无序

HashSet底层采用哈希表存储数据,哈希表是一种对于增删改查数据性能都比较好的结构,HashSet在存储数据的时候,会根据数组长度和哈希值计算出要存储的位置,从而实现无序结构。

②使用hashcode方法和equals方法实现不重复

HashSet通过hashcode方法计算哈希值,如果两者哈希值都相等,则使用equals方法来判断两者时候是同一个类型。

自定义类对象添加HashSet

 1 public class Test2 {
 2     public static void main(String[] args) {
 3         HashSet<Person> set = new HashSet<>();//生成一个HashSet集合
 4         /*
 5         * TODO HashSet底层原理:
 6         * 将自定义类添加到HashSet中时,会判断hashcode方法计算的哈希值是否相同
 7         *如果哈希值不相等,则表示两者不是同一个对象,添加成功
 8         * 如果哈希值相等,则比较equals方法,如果equals方法不相等,说明不是同一个对象 ----这种情况为哈希冲突
 9         * 如果equals方法相等,则表示两者是同一个对象
10         */
11         //添加对象
12         set.add(new Person("张三",18));
13         set.add(new Person("张三",18));
14         set.add(new Person("李四",14));
15         set.add(new Person("王五",19));
16         set.add(new Person("老牛",14));
17         //遍历对象
18         for (Person person:set) {
19             System.out.println(person);
20         }
21 
22     }
23 }
24 class Person{
25     private  String name;
26     private  int age;
27 
28 
29     public Person() {
30     }
31 
32     public Person(String name, int age) {
33         this.name = name;
34         this.age = age;
35     }
36     public String getName() {
37         return name;
38     }
39     public void setName(String name) {
40         this.name = name;
41     }
42 
43     public int getAge() {
44         return age;
45     }
46     public void setAge(int age) {
47         this.age = age;
48     }
49 
50     public String toString() {
51         return "Person{name = " + name + ", age = " + age + "}";
52     }
53 }

效果展示:

 这里发现,对于自定义类中,我想表达的是属性如姓名和年龄两者相等,则是同一个对象才对呀?那为什么会出现两个{张三,18}呢?

那是因为自定义类它使用的hashcode方法是Object类中的hashcode方法,而Object类中的hashcode方法是通过比较两者之间地址值,如果地址值相同表示同一个对象,所以如果我们想表示属性值相同表示同一个对象,需要重写hashcode方法

重写hashcode语法

@Override
public int hashCode() {
    return Objects.hash(需要比较的属性名,.......,需要比较的属性名);
}

效果展示:

 发现为什么重写了hashCode仍然结果一样呢?

那是因为当我们只重写hashCode方法时,HashSet底层会认为{张三,18}这个对象求出的哈希值是相等的,它会比较equals方法,而如果我们没有重写equals方法会直接使用Object类的equals 方法,而Object类的equals方法比较的是两者地址值,如果地址值相等,才代表是同一个对象。

重写equals语法

@Override
public boolean equals(Object obj) {
   //比较两者地址值,如果相等返回true
   if(obj == this){
       return  true;
   }
    //如果两者是不同类型的返回false
   if(!(obj instanceof 自定义类)){
        return false;
   }
    //两者是相同类型
    自定义类    对象 = (自定义类) obj;
    //如果两者属性相同,则表示同一个对象
    if(比较对象的属性如果相等){
       return true;
    }
      return false;
}

效果展示:

 发现每个对象是不重复的,这样才能满足我们自己的需求。而String类它也是通过重写hashCode和equals方法来判断是否为同一对象.

 TreeSet类

TreeSet底层使用的是二叉树,而TreeSet中元素要求具有排序规则,其它判断元素是否重复与HashSet一样都需要重写hashCode方法和equals方法

创建TreeSet语法:

TreeSet  名称  =new   TreeSet(); //调用无参构造器

举个例子:

public class TreeSetTest {
    public static void main(String[] args) {
        //调用无参构造器
        TreeSet set=new TreeSet();
    }
}

TreeSet存储的内容是可比较的,那如果是自定义类如何实现对象之间的可比较呢?

Java中提供两种方法来实现

比较的结果返回值:

如果返回0表示两个元素一致。
如果返回大于0,表示添加得元素比容器中得元素大。
如果返回小于0,表示添加得元素比容器中得元素小。

方法一:实现Comparable接口重写里面的方法

语法:

class 类名 implements Comparable<类名>{
    
   // 重写CompareTo方法
    @Override
    public int compareTo(类名 o) {
 
        //代码内容
}

举个例子:

 1 public class TreeSetTest {
 2     public static void main(String[] args) {
 3         //调用无参构造器
 4         TreeSet set=new TreeSet();
 5         //添加元素
 6         set.add(new People("张三",20));
 7         set.add(new People("老王",18));
 8         set.add(new People("老牛",30));
 9         set.add(new People("李四",10));
10         //遍历元素
11         for (Object o:set) {
12             People people=(People) o; 
13             System.out.println(people);
14         }
15     }
16 }
17 class People implements Comparable{
18     private String name;
19     private int age;
20 
21     @Override
22     public int compareTo(People o) {
23         24         //按照年龄进行从小到大排序(根据对象o与本类对象进行比较)
25         return this.age-o.age;
26     }
27 
28     public People() {
29     }
30 
31     public People(String name, int age) {
32         this.name = name;
33         this.age = age;
34     }
35     public String getName() {
36         return name;
37     }
38     public void setName(String name) {
39         this.name = name;
40     }
41     public int getAge() {
42         return age;
43     }
44     public void setAge(int age) {
45         this.age = age;
46     }
47     public String toString() {
48         return "People{name = " + name + ", age = " + age + "}";
49     }
50 }

 效果展示:

方法二:通过自定义排序方式,通过实现Comparator接口从而调用TreeSet的有参构造方法

语法:

class  类名  implements Compatator<类名>{

      //重写接口方法
      @Override
      public   int  compare(类名  o1,类名   o2){
            //代码内容
      }
}

举个例子:

 1 public class TreeSetTest {
 2     public static void main(String[] args) {
 3         //调用有参构造方法,传入一个实现Comparator接口的类对象
 4         TreeSet<People> set=new TreeSet<>(new People());
 5         //添加元素
 6         set.add(new People("张三",20));
 7         set.add(new People("老王",18));
 8         set.add(new People("老牛",30));
 9         set.add(new People("李四",10));
10         //遍历元素
11         for (People people:set){
12             System.out.println(people);
13         }
14     }
15 }
16 class People implements Comparator<People> {
17     private String name;
18     private int age;
19 
20     @Override
21     public int compare(People o1, People o2) {
22         //按照年龄从小到大排序
23         return o1.age-o2.age;
24     }
25 
26     public People() {
27     }
28 
29     public People(String name, int age) {
30         this.name = name;
31         this.age = age;
32     }
33     public String getName() {
34         return name;
35     }
36     public void setName(String name) {
37         this.name = name;
38     }
39     public int getAge() {
40         return age;
41     }
42     public void setAge(int age) {
43         this.age = age;
44     }
45     public String toString() {
46         return "People{name = " + name + ", age = " + age + "}";
47     }
48 }

效果展示:

发现有时候这个实现Comparator接口的类只是使用一次就会丢弃,那如果每次都直接生成一个类只使用一次就会导致资源的浪费。

所以这里可以使用匿名实现类的方法来解决这个问题

语法:

Comparator<类名> comparator=new Comparator<类名>() {
            @Override
            public int compare(类名 o1, 类名 o2) {
                //代码内容
            }
};

举个例子:

 1 public class TreeSetTest {
 2     public static void main(String[] args) {
 3         //生成匿名接口类对象
 4         Comparator<String> comparator=new Comparator<String>() {
 5             @Override
 6             public int compare(String o1, String o2) {
 7                 return o1.length()-o2.length();
 8             }
 9         };
10         //调用有参构造器,传入自定义排序规则对象
11         TreeSet<String> set=new TreeSet<>(comparator);
12     }
13 }

这种方法也适用于一些已经实现Comparable接口的类,当自己不想用这种排序规则时,便可以使用自定义排序.

 

标签:set,name,框架,HashSet,age,集合,new,public
From: https://www.cnblogs.com/gzyhrc/p/17838051.html

相关文章

  • Java中的Set集合之TreeSet
    TreeSet:TreeSet是一个有序集合,它扩展了AbstractSet类并实现了NavigableSet接口。以下是此实现最重要方面的快速摘要:它存储唯一的元素它不保留元素的插入顺序它按升序对元素进行排序它不是线程安全的在该实现中,对象根据其自然顺序以升序排序和存储。该TreeSet中使用的是一......
  • 史上功能最全的Java权限认证框架!
    大家好,我是Java陈序员。权限认证是我们日常开发绕不过的话题,这是因为我们的应用程序需要防护,防止被窜入和攻击。在Java后端开发中,实现权限认证有很多种方案可以选择,一个拦截器、过滤器也许就可以轻松搞定。当然,现在也有很多成熟的框架,供我们选择。轻量的Shiro,Spring家族的......
  • jdk8 Stream流中将集合转成map,重复key处理,统计最大值,获取某个属性集合等10种最常用方
    jdk8Stream流中将集合转成map,重复key处理,统计最大值,获取某个属性集合等10种最常用方法......
  • linux环境安装可操作图库语言Gremlin的图框架HugeGraph
    原创/朱季谦 若你还没接触过图数据库,可能看到这个概念时,会比较蒙蔽。图是什么?图数据库又是什么?首先,在数据结构中,图是一种由顶点(vertex)集合及顶点间关系集合组成的一种非线性数据结构。而图数据库,则是以图这种具有点边结构来增、删、改、查之类操作的NoSQL数据库,它特别擅长处理大数......
  • java集合
    java集合2023.11.5集合可以动态的保存任意多个对象提供一系列的操作对象方法使用集合添加,删除新元素,简洁集合的框架体系图Iterator对象称为迭代器,主要用于遍历Collection集合中的元素所有实现了Collection接口的的集合类都有一个iterator()方法,用以返回......
  • SpringMVC框架第一天
    目录SpringMVC的基本概念三层架构和MVC三层架构MVC模型MVC概述SpringMVC是什么SpringMVC在三层架构的位置SpringMVC的优势SpringMVC的入门SpringMVC的入门案例入门案例中的组件DispatcherServlet:前端控制器HandlerMapping:处理器映射器Handler:处理器HandlAdapter:处理器适配器ViewR......
  • 集合
    集合类型Python中的集合与数学中集合的概念一致Python中的集合是一个无序的不重复元素序列集合中只能存储不可变数据类型在Pythont中集合使用{定义与列表、字典一样,都是Pythont中的可变数据类型 集合的创建方式1.使用{}花括号直接创建集合语法结构如下:s={element1,element2......
  • AJAX手写JQuery框架封装AJAX请求和常见方法实现项目功能省市联动查询效果------AJAX
    建立一个SQL表CREATETABLEt_stu(idBIGINTAUTO_INCREMENTPRIMARYKEY,usernameVARCHAR(255),ageINT,addressVARCHAR(255));INSERTINTOt_stu(id,username,age,address)VALUES(NULL,"zhangsan",15,"广州")INSERTINTOt_stu(id,username,age,address)......
  • 表现层框架设计
    表现层框架设计是指在软件系统中,将用户界面(UI)和用户交互逻辑与后端业务逻辑分离,使用特定的框架来组织和管理表现层的功能和结构。下面是表现层框架设计的一般步骤和常用技术:确定需求和功能:首先,明确系统的需求和功能,确定用户界面需要展示的内容和交互逻辑。这包括界面元素、用户操作......
  • Java集合类API详解​(上)单列集合Set类
    Java集合类API详解单列集合一次添加一个数据的集合。它们的根接口是Collection,具体体系如图:List系列集合的特点:添加的元素是有序、可重复、有索引的。也即存和取的顺序是一致的;包含的元素是可以有重复的;包含的元素是有索引的,可以通过索引对元素进行操作。Set系列集合的特点:添加的元......