java-集合-set(不重复集合)知识分解——庖丁解牛版

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

     |
    | `static <E> [Set]( )<E>` | `[of]( )​(E e1, E e2)` | 
    返回一个包含两个元素的不可变集合。
     |
    | `static <E> [Set]( )<E>` | `[of]( )​(E e1, E e2, E e3)` | 
    返回一个包含三个元素的不可变集合。
     |
    | `static <E> [Set]( )<E>` | `[of]( )​(E e1, E e2, E e3, E e4)` | 
    返回一个包含四个元素的不可变集合。
     |
    | `static <E> [Set]( )<E>` | `[of]( )​(E e1, E e2, E e3, E e4, E e5)` | 
    返回一个包含五个元素的不可变集合。
     |
    | `static <E> [Set]( )<E>` | `[of]( )​(E e1, E e2, E e3, E e4, E e5, E e6)` | 
    返回一个包含六个元素的不可变集合。
     |
    | `static <E> [Set]( )<E>` | `[of]( )​(E e1, E e2, E e3, E e4, E e5, E e6, E e7)` | 
    返回一个包含七个元素的不可变集合。
     |
    | `static <E> [Set]( )<E>` | `[of]( )​(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8)` | 
    返回一个包含八个元素的不可变集合。
     |
    | `static <E> [Set]( )<E>` | `[of]( )​(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9)` | 
    返回一个包含九个元素的不可变集合。
     |
    | `static <E> [Set]( )<E>` | `[of]( )​(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)` | 
    返回一个包含十个元素的不可变集合。
     |
    | `boolean` | `[remove]( )​([Object]( ) o)` | 
    如果存在,则从该集合中删除指定的元素(可选操作)。
     |
    | `boolean` | `[removeAll]( )​([Collection]( )<?> c)` | 
    从此集合中删除指定集合中包含的所有元素(可选操作)。
     |
    | `boolean` | `[retainAll]( )​([Collection]( )<?> c)` | 
    仅保留该集合中包含在指定集合中的元素(可选操作)。
     |
    | `int` | `[size]( )​()` | 
    返回此集合中的元素数(其基数)。
     |
    | `default [Spliterator]( )<[E]( )>` | `[spliterator]( )​()` | 
    在此集合中的元素上创建一个 `Spliterator` 。
     |
    | `[Object]( )[]` | `[toArray]( )​()` | 
    返回一个包含此集合中所有元素的数组。
     |
    | `<T> T[]` | `[toArray]( )​(T[] a)` | 
    返回一个包含此集合中所有元素的数组; 返回的数组的运行时类型是指定数组的运行时类型。
     |

第二重境界:未尝见全牛也

============

HashSet


1、HashSet特点:

(1)底层数据结构是哈希表(查询速度快),使用HashCode哈希值

(2)对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序一致

(3)没有带索引的方法,所以不能使用普通for循环遍历

(4)由于是Set集合,所以是不包含重复元素的集合

2、HashSet集合添加一个元素的过程:

3、代码演示

package SetDemo;

import java.util.HashSet;

public class Set01 {

public static void main(String[] args) {

//导包创建对象HashSet

HashSet set=new HashSet();

//添加数据

set.add(“aaa”);

set.add(“bbb”);

set.add(“ccc”);

set.add(“ddd”);

//增强for循环遍历

for (String i:set){

System.out.println(i);

}

}

}

//代码输出结果

E:\develop\JDK\bin\java.exe "-javaagent:E:\IDEA\IntelliJ IDEA Community Edition

aaa

ccc

bbb

ddd

Process finished with exit code 0

4、注意事项(特殊之处,遍历无序的原因不是排序的无序,而是底层哈希值的存放地址的原因)

public static void main(String[] args) {

HashSet set=new HashSet();

set.add(“hello”);

set.add(“world”);

set.add(“java”);

//集合自带排序方式

System.out.println(set);

System.out.println(“--------”);

//迭代器方式

Iterator it = set.iterator();

while (it.hasNext()){

String s = it.next();

System.out.println(s);

}

System.out.println(“--------”);

//增强for循环

for (String s:set){

System.out.println(s);

}

}

//输出结果

[world, java, hello]


world

java

hello


world

java

hello

Process finished with exit code 0

上述代码是正常输出的结果,但是以下的代码的输出,请看:

public static void main(String[] args) {

HashSet set=new HashSet();

set.add(“6”);

set.add(“7”);

set.add(“8”);

set.add(“9”);

set.add(“10”);

//集合自带排序方式

System.out.println(set);

System.out.println(“--------”);

//迭代器方式

Iterator it = set.iterator();

while (it.hasNext()){

String s = it.next();

System.out.println(s);

}

System.out.println(“--------”);

//增强for循环

for (String s:set){

System.out.println(s);

}

}

//代码输出结果

[6, 7, 8, 9, 10]


6

7

8

9

10


6

7

8

9

10

Process finished with exit code 0

public static void main(String[] args) {

HashSet set=new HashSet();

set.add(“a”);

set.add(“b”);

set.add(“c”);

set.add(“d”);

set.add(“e”);

//集合自带排序方式

System.out.println(set);

System.out.println(“--------”);

//迭代器方式

Iterator it = set.iterator();

while (it.hasNext()){

String s = it.next();

System.out.println(s);

}

System.out.println(“--------”);

//增强for循环

for (String s:set){

System.out.println(s);

}

}

//代码输出结果

[a, b, c, d, e]


a

b

c

d

e


a

b

c

d

e

Process finished with exit code 0

上述两则代码结果,可以看到输出结果都是有序的,而HashSet特点有一,就是不保证迭代顺序。这不就是矛盾的一处地方吗?

原因:但并不是HashSet的自相矛盾,其原因就是底层实现的特点。哈希表实现,计算哈希值,通过哈希值代替索引的作用,查询存储的值。

而哈希值的计算,有一套自己的计算规则,当一串字符串计算哈希值时,哈希值的区别也许会很大,但如果是有规律的数字、字符进行计算哈希值时,其哈希值有会时有序的。

表现出来的结果就是在控制台输出有顺序有规律的单节字符时,输出也是有规律的。

5、LinkedHashSet集合概述和特点

(1)集合特点:

哈希表和链表实现的Set接口,具有可预测的迭代顺序。

由链表保证元素有序,也就是说元素的存储和取出顺序是一致的。

由哈希表保证元素唯一,也就是说没有重复的元素。

(2)代码案例

TreeSet


1、TreeSet集合特点

(1)元素有序,这里的顺序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体排序方式取决于构造方法

TreeSet​():根据其元素的自然排序进行排序

TreeSet​(Comparator<? super E> comparator) :根据指定的比较器进行排序

(2)没有带索引的方法,所以不能使用普通for循环遍历

(3)由于是Set集合,所以不包含重复元素的集合

2、注意事项

用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的

自然排序,就是让元素所属的类实现Comparable接口,重写compareTo​(T o)方法

重点:如何重写方法

重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写

重点:主要条件与次要条件

用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的

比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare​(T o1,T o2)方法

重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写

3、代码展示(比较器排序)

package SetDemo;

import java.util.Comparator;

import java.util.HashSet;

import java.util.Set;

import java.util.TreeSet;

public class Set003 {

public static void main(String[] args) {

Set set=new TreeSet(new Comparator() {

@Override

public int compare(News n1, News n2) {

int num=n1.getTitle().compareTo(n2.getTitle());

return num;

}

});

News news1=new News(“中国多地遭雾霾笼罩空气质量再成热议话题”);

News news2=new News(“民进党台北举行“火大游行””);

News news3=new News(“春节临近北京“卖房热””);

News news4=new News(“春节临近北京“卖房热””);

System.out.println(“新闻一与新闻二的比较:”+news1.equals(news2));

System.out.println(“新闻三与新闻四的比较:”+news3.equals(news4));

System.out.println(“--------”);

set.add(news1);

set.add(news2);

set.add(news3);

set.add(news4);

for (int i = 0; i < set.size(); i++) {

}

Set set1=new HashSet();

set1.addAll(set);

for (News n:set1){

System.out.println(n);

}

System.out.println(“--------”);

System.out.println(“集合中新闻的长度为:”+set1.size());

}

}

第三重境界:官知止而神欲行

=============

1、哈希值(hashCode)


概念:

是Jdk根据对象的地址/String/数字算出来一串数字(int),hashCode()是Object类的方法,所以说Java的对象都可以调用这个hashCode方法返回哈希值。

特点:

(1)如果自定义类没有重写hashCode方法,那么自定义类的对象生成的哈希值是根据对象的内存地址值生成的,所以说即便两个对象的属性一样,哈希值也不一样。

(2)诉求:如果两个对象属性一样,那么两个对象哈希值也要一样,所以在自定义的类中重写了      hashCode方法(不调用Object类hashCode),是根据对象的属性生成哈希值。

(3)两个对象哈希值一样,不代表两个对象的属性一样.两个对象的属性一样,则两个对象的哈希值肯定一样。

(4)数字的哈希值是它本身。

代码展示:

public static void main(String[] args) {

//创建学生类对象,实例化

Student s1 = new Student02(“盘古大神”, 100, 100, 100,300);

Student s2 = new Student02(“女娲娘娘”, 100, 95, 90,285);

Student s3 = new Student02(“天皇伏羲”, 98, 100, 90,288);

Student s4 = new Student02(“地皇神农”, 99, 95, 90,284);

Student s5 = new Student02(“人皇轩辕”, 95, 98, 80,273);

//输出哈希值

System.out.println(s1.hashCode());

System.out.println(s2.hashCode());

System.out.println(s3.hashCode());

System.out.println(s4.hashCode());

System.out.println(s5.hashCode());

}

//输出结果

356573597

1735600054

21685669

2133927002

1836019240

Process finished with exit code 0

2、哈希表


概念:

散列表Hash table,也叫哈希表),是根据(Key)而直接访问在内存存储位置的数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做散列函数,存放记录的数组称做散列表

最后

整理的这些资料希望对Java开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

image

image

其实面试这一块早在第一个说的25大面试专题就全都有的。以上提及的这些全部的面试+学习的各种笔记资料,我这差不多来回搞了三个多月,收集整理真的很不容易,其中还有很多自己的一些知识总结。正是因为很麻烦,所以对以上这些学习复习资料感兴趣
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!
.println(s2.hashCode());

System.out.println(s3.hashCode());

System.out.println(s4.hashCode());

System.out.println(s5.hashCode());

}

//输出结果

356573597

1735600054

21685669

2133927002

1836019240

Process finished with exit code 0

2、哈希表


概念:

散列表Hash table,也叫哈希表),是根据(Key)而直接访问在内存存储位置的数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做散列函数,存放记录的数组称做散列表

最后

整理的这些资料希望对Java开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

[外链图片转存中…(img-oxeJFJJ9-1714672342674)]

[外链图片转存中…(img-8NxBBDir-1714672342674)]

其实面试这一块早在第一个说的25大面试专题就全都有的。以上提及的这些全部的面试+学习的各种笔记资料,我这差不多来回搞了三个多月,收集整理真的很不容易,其中还有很多自己的一些知识总结。正是因为很麻烦,所以对以上这些学习复习资料感兴趣
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值