1.Set集合

1.1 Set集合概述和特点

Set集合的特点

  元素存取无序

  没有索引、只能通过迭代器或增强for循环遍历

  不能存储重复元素

1.2 哈希值

哈希值简介

  是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值

如何获取哈希值

  Object类中的public int hashCode():返回对象的哈希码值

哈希值的特点

  同一个对象多次调用hashCode()方法返回的哈希值是相同的

  默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同

1.3 HashSet集合概述和特点

HashSet集合的特点

  底层数据结构是哈希表

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

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

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

1.4 HashSet集合保证元素唯一性源码分析

HashSet集合保证元素唯一性的原理

  1.根据对象的哈希值计算存储位置

    如果当前位置没有元素则直接存入

    如果当前位置有元素存在,则进入第二步

  2.当前元素的元素和已经存在的元素比较哈希值

    如果哈希值不同,则将当前元素进行存储

    如果哈希值相同,则进入第三步

  3.通过equals()方法比较两个元素的内容

    如果内容不相同,则将当前元素进行存储

    如果内容相同,则不存储当前元素

1.5 哈希表

哈希表的本质实质上就是数组加链表

1.6 LinkedHashSet集合概述和特点

LinkedHashSet集合特点

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

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

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

2.Set集合排序

2.1 TreeSet集合概述和特点

TreeSet集合概述

  元素有序,可以按照一定的规则进行排序,具体排序方式取决于构造方法

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

    TreeSet(Comparator comparator) :根据指定的比较器进行排序

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

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

2.2 自然排序Comparable的使用

案例需求

  存储学生对象并遍历,创建TreeSet集合使用无参构造方法

  要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序

实现步骤

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

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

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

学生类

  1. 1 public class Student implements Comparable<Student> {
  2. 2 private String name;
  3. 3 private int age;
  4. 4
  5. 5 public Student() {
  6. 6 }
  7. 7
  8. 8 public Student(String name, int age) {
  9. 9 this.name = name;
  10. 10 this.age = age;
  11. 11 }
  12. 12
  13. 13 public String getName() {
  14. 14 return name;
  15. 15 }
  16. 16
  17. 17 public void setName(String name) {
  18. 18 this.name = name;
  19. 19 }
  20. 20
  21. 21 public int getAge() {
  22. 22 return age;
  23. 23 }
  24. 24
  25. 25 public void setAge(int age) {
  26. 26 this.age = age;
  27. 27 }
  28. 28
  29. 29 @Override
  30. 30 public boolean equals(Object o) {
  31. 31 if (this == o) return true;
  32. 32 if (o == null || getClass() != o.getClass()) return false;
  33. 33
  34. 34 Student student = (Student) o;
  35. 35
  36. 36 if (age != student.age) return false;
  37. 37 return name != null ? name.equals(student.name) : student.name == null;
  38. 38 }
  39. 39
  40. 40 @Override
  41. 41 public int hashCode() {
  42. 42 int result = name != null ? name.hashCode() : 0;
  43. 43 result = 31 * result + age;
  44. 44 return result;
  45. 45 }
  46. 46
  47. 47 @Override
  48. 48 public String toString() {
  49. 49 return "Student{" +
  50. 50 "name='" + name + '\'' +
  51. 51 ", age=" + age +
  52. 52 '}';
  53. 53 }
  54. 54
  55. 55
  56. 56 @Override
  57. 57 public int compareTo(Student o) {
  58. 58 int num = o.age - this.age;
  59. 59 int num2 = num == 0?o.name.compareTo(this.name):num;
  60. 60 return num2;
  61. 61 }
  62. 62 }

测试类

  1. 1 import java.util.TreeSet;
  2. 2
  3. 3 public class test {
  4. 4 public static void main(String[] args) {
  5. 5 TreeSet<Student> stu = new TreeSet<>();
  6. 6 Student s1 = new Student("tony",21);
  7. 7 Student s2 = new Student("xiaohong",21);
  8. 8 Student s3 = new Student("wangdachui",800);
  9. 9
  10. 10 stu.add(s1);
  11. 11 stu.add(s2);
  12. 12 stu.add(s3);
  13. 13
  14. 14 for (Student s : stu){
  15. 15 System.out.println(s);
  16. 16 }
  17. 17 }
  18. 18 }

2.3 比较器排序Comparator的使用

案例需求

  存储学生对象并遍历,创建TreeSet集合使用带参构造方法

  要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序

实现步骤

  用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的 比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T o2)方法

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

学生类

  1. 1 public class Student {
  2. 2 private String name;
  3. 3 private int age;
  4. 4
  5. 5 public Student() {
  6. 6 }
  7. 7
  8. 8 public Student(String name, int age) {
  9. 9 this.name = name;
  10. 10 this.age = age;
  11. 11 }
  12. 12
  13. 13 public String getName() {
  14. 14 return name;
  15. 15 }
  16. 16
  17. 17 public void setName(String name) {
  18. 18 this.name = name;
  19. 19 }
  20. 20
  21. 21 public int getAge() {
  22. 22 return age;
  23. 23 }
  24. 24
  25. 25 public void setAge(int age) {
  26. 26 this.age = age;
  27. 27 }
  28. 28
  29. 29 @Override
  30. 30 public boolean equals(Object o) {
  31. 31 if (this == o) return true;
  32. 32 if (o == null || getClass() != o.getClass()) return false;
  33. 33
  34. 34 Student student = (Student) o;
  35. 35
  36. 36 if (age != student.age) return false;
  37. 37 return name != null ? name.equals(student.name) : student.name == null;
  38. 38 }
  39. 39
  40. 40 @Override
  41. 41 public int hashCode() {
  42. 42 int result = name != null ? name.hashCode() : 0;
  43. 43 result = 31 * result + age;
  44. 44 return result;
  45. 45 }
  46. 46
  47. 47 @Override
  48. 48 public String toString() {
  49. 49 return "Student{" +
  50. 50 "name='" + name + '\'' +
  51. 51 ", age=" + age +
  52. 52 '}';
  53. 53 }
  54. 54
  55. 55 }

测试类

  1. 1 import java.util.Comparator;
  2. 2 import java.util.TreeSet;
  3. 3
  4. 4 public class test {
  5. 5 public static void main(String[] args) {
  6. 6 TreeSet<Student> stu = new TreeSet<>(new Comparator<Student>() {
  7. 7 @Override
  8. 8 public int compare(Student o1, Student o2) {
  9. 9 int num = o1.getAge() - o2.getAge();
  10. 10 int num2 = num == 0?o1.getName().compareTo(o2.getName()):num;
  11. 11 return num2;
  12. 12 }
  13. 13 });
  14. 14 Student s1 = new Student("tony",21);
  15. 15 Student s2 = new Student("xiaohong",21);
  16. 16 Student s3 = new Student("wangdachui",800);
  17. 17
  18. 18 stu.add(s1);
  19. 19 stu.add(s2);
  20. 20 stu.add(s3);
  21. 21
  22. 22 for (Student s : stu){
  23. 23 System.out.println(s);
  24. 24 }
  25. 25 }
  26. 26 }

3.泛型

3.1 泛型概述和好处

泛型概述

  是JDK5中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型

  它的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。一提到参数,最熟悉的就是定义方 法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具 体的类型参数化,然后在使用/调用时传入具体的类型。这种参数类型可以用在类、方法和接口中,分别被称为泛型类、泛型方法、泛型接口。

泛型定义格式

  <类型>:指定一种类型的格式。这里的类型可以看成是形参

  <类型1,类型2…>:指定多种类型的格式,多种类型之间用逗号隔开。

  这里的类型可以看成是形参 将来具体调用时候给定的类型可以看成是实参,并且实参的类型只能是引用数据类型。

泛型的好处

  把运行时期的问题提前到了编译期间

  避免了强制类型转换

3.2 泛型类

格式:

  1. 1 修饰符 class 类名<类型> { }

实例:

  1. 1 public class Ger<T> {
  2. 2 private T t ;
  3. 3
  4. 4 public T getT() {
  5. 5 return t;
  6. 6 }
  7. 7
  8. 8 public void setT(T t) {
  9. 9 this.t = t;
  10. 10 }
  11. 11 }

测试类

  1. 1 public class test {
  2. 2 public static void main(String[] args) {
  3. 3 Ger<String> str = new Ger<>();
  4. 4 str.setT("hello");
  5. 5 System.out.println(str.getT());
  6. 6
  7. 7 Ger<Integer> Intr = new Ger<>();
  8. 8 Intr.setT(100);
  9. 9 System.out.println(Intr.getT());
  10. 10
  11. 11 Ger<Boolean> br = new Ger<>();
  12. 12 br.setT(true);
  13. 13 System.out.println(br.getT());
  14. 14 }
  15. 15 }

3.3 泛型方法

定义格式

  1. 1 修饰符 <类型> 返回值类型 方法名(类型 变量名) { }

带有泛型方法的类

  1. 1 public class Ber {
  2. 2 public <T> void show(T t){
  3. 3 System.out.println(t);
  4. 4 }
  5. 5 }

测试类

  1. 1 public class test {
  2. 2 public static void main(String[] args) {
  3. 3 Ber br = new Ber();
  4. 4 br.show("hello");
  5. 5 br.show(100);
  6. 6 br.show(true);
  7. 7 }
  8. 8 }

3.4 泛型接口

定义格式

  1. 1 修饰符 interface 接口名<类型> { }

接口

  1. 1 public interface Cer<T> {
  2. 2 public abstract void show(T t);
  3. 3 }

实现类

  1. 1 public class CerA<T> implements Cer<T>{
  2. 2
  3. 3 @Override
  4. 4 public void show(T t) {
  5. 5 System.out.println(t);
  6. 6 }
  7. 7 }

测试类

  1. 1 public class test {
  2. 2 public static void main(String[] args) {
  3. 3 CerA<String> str = new CerA<>();
  4. 4 str.show("Hello");
  5. 5 }
  6. 6 }

3.5 类型通配符

类型通配符的作用

  为了表示各种泛型List的父类,可以使用类型通配符

类型通配符的分类

  类型通配符:<?>

    List<?>:表示元素类型未知的List,它的元素可以匹配任何的类型

    这种带通配符的List仅表示它是各种泛型List的父类,并不能把元素添加到其中

  类型通配符上限:<? extends 类型>

    List<? extends Number>:它表示的类型是Number或者其子类型

  类型通配符下限:<? super 类型>

    List<? super Number>:它表示的类型是Number或者其父类型

4.可变参数

4.1可变参数

可变参数介绍

  可变参数又称参数个数可变,用作方法的形参出现,那么方法参数个数就是可变的了

可变参数定义格式

  1. 1 修饰符 返回值类型 方法名(数据类型… 变量名) { }

可变参数的注意事项

  这里的变量其实是一个数组

  如果一个方法有多个参数,包含可变参数,可变参数要放在最后

  1. 1 public class kb {
  2. 2 public static void main(String[] args) {
  3. 3 sum(10,20);
  4. 4 sum(10,20,30);
  5. 5 sum(10,20,30,40);
  6. 6 }
  7. 7
  8. 8 public static void sum(int... x){
  9. 9 int a = 0;
  10. 10
  11. 11 for (int i : x){
  12. 12 a += i;
  13. 13 }
  14. 14
  15. 15 System.out.println(a);
  16. 16 }
  17. 17 }

4.2 可变参数的使用

Arrays工具类中有一个静态方法:

  public static List asList(T... a):返回由指定数组支持的固定大小的列表

  返回的集合不能做增删操作,可以做修改操作

List接口中有一个静态方法:

  public static List of(E... elements):返回包含任意数量元素的不可变列表

  返回的集合不能做增删改操作

Set接口中有一个静态方法:

  public static Set of(E... elements) :返回一个包含任意数量元素的不可变集合

  在给元素的时候,不能给重复的元素

  返回的集合不能做增删操作,没有修改的方法

JavaSE15-集合·其二的更多相关文章

  1. java基础集合经典训练题

    第一题:要求产生10个随机的字符串,每一个字符串互相不重复,每一个字符串中组成的字符(a-zA-Z0-9)也不相同,每个字符串长度为10; 分析:*1.看到这个题目,或许你脑海中会想到很多方法,比如判 ...

  2. .Net多线程编程—并发集合

    并发集合 1 为什么使用并发集合? 原因主要有以下几点: System.Collections和System.Collections.Generic名称空间中所提供的经典列表.集合和数组都不是线程安全 ...

  3. 一起学 Java(三) 集合框架、数据结构、泛型

    一.Java 集合框架 集合框架是一个用来代表和操纵集合的统一架构.所有的集合框架都包含如下内容: 接口:是代表集合的抽象数据类型.接口允许集合独立操纵其代表的细节.在面向对象的语言,接口通常形成一个 ...

  4. 编写高质量代码:改善Java程序的151个建议(第5章:数组和集合___建议75~78)

    建议75:集合中的元素必须做到compareTo和equals同步 实现了Comparable接口的元素就可以排序,compareTo方法是Comparable接口要求必须实现的,它与equals方法 ...

  5. java基础_集合List与Set接口

    List接口继承了Collection的方法  当然也有自己特有的方法向指定位置添加元素   add(索引,添加的元素); 移除指定索引的元素   remove(索引) 修改指定索引的元素   set ...

  6. Java基础Collection集合

    1.Collection是所有集合的父类,在JDK1.5之后又加入了Iterable超级类(可以不用了解) 2.学习集合从Collection开始,所有集合都继承了他的方法 集合结构如图:

  7. 轻量级“集合”迭代器-Generator

    Generator是PHP 5.5加入的新语言特性.但是,它似乎并没有被很多PHP开发者广泛采用.因此,在我们了解PHP 7对Generator的改进之前,我们先通过一个简单却显而易见的例子来了解下G ...

  8. Asp.net MVC 传递数据 从前台到后台,包括单个对象,多个对象,集合

    今天为大家分享下 Asp.net MVC 将数据从前台传递到后台的几种方式. 环境:VS2013,MVC5.0框架 1.基本数据类型 我们常见有传递 int, string, bool, double ...

  9. 这些.NET开源项目你知道吗?.NET平台开源文档与报表处理组件集合(三)

    在前2篇文章这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧 和这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧!(第二辑)中,大伙热情高涨.再次拿出自己的私货,在.NET平台 ...

  10. python 数据类型 --- 集合

    1. 注意列表和集合的区别 set 列表表现形式: list_1 = [1,3,4];  集合表现形式:set_1= set() list_1 = [1,2,3,4,23,4,2] print(lis ...

随机推荐

  1. MySQL索引背后的数据结构及原理

    摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...

  2. 面试官:连Spring AOP都说不明白,自己走还是我送你?

    前言 因为假期原因,有一段时间没给大家更新了!和大家说个事吧,放假的时候一位粉丝和我说了下自己的被虐经历,在假期前他去某互联网公司面试,结果直接被人家面试官Spring AOP三连问给问的一脸懵逼!其 ...

  3. 学习netty遇到的关于 LineBasedFrameDecoder 的问题

    最近在看<Netty权威指南>这本书,关于TCP粘包/拆包,书中使用的是 LineBasedFrameDecoder 来解决的,但是我在实践的过程中出现了问题,上代码吧. 这个是 serv ...

  4. 对于this和当前线程的一些理解

    在学习这个InheritableThreadLocal类的时候,我对于有个地方一直没有理解,我发现了盲点. 1 private void init(ThreadGroup g, Runnable ta ...

  5. 【R语言入门】R语言中的变量与基本数据类型

    说明 在前一篇中,我们介绍了 R 语言和 R Studio 的安装,并简单的介绍了一个示例,接下来让我们由浅入深的学习 R 语言的相关知识. 本篇将主要介绍 R 语言的基本操作.变量和几种基本数据类型 ...

  6. 干货分享:盘点那些最常用的Linux命令,需熟记!

  7. sentinel整合dubbo

    <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-dubbo-a ...

  8. gulp常用配置

    由于项目中经常会使用到gulp,而每次配置大概都差不多,所以将配置记录一下 项目结构 ├─dist │ ├─assets │ ├─css │ ├─images │ └─js ├─node_module ...

  9. rest-framework 分页器

    一 简单分页(查看第n页,每页显示n条) from rest_framework.pagination import PageNumberPagination # 一 基本使用:url=url=htt ...

  10. 【NOIP2015模拟11.5】JZOJ8月5日提高组T2 Lucas的数列

    [NOIP2015模拟11.5]JZOJ8月5日提高组T2 Lucas的数列 题目 PS:\(n*n*T*T<=10^{18}\)而不是\(10^1*8\) 题解 题意: 给出\(n\)个元素的 ...