A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 段孟钊 中级黑马   /  2019-5-7 14:53  /  995 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 小石姐姐 于 2019-5-9 18:31 编辑

个人笔记一、Set集合概述和特点
1.元素存取无序      
2.没有索引     
3.不能存储重复元素
二、哈希值概念
是JDK根据对象的地址或字符串或数字计算出来的一串int类型的数值
如何获取哈希值
Object类中有一个方法:hashCode()用于获取哈希值
三、HashSet集合概述和特点
1.底层是哈希表结构      
2.元素存取无序      
3.没有索引      
4.不能存储重复元素
四、HashSet集合保证元素唯一性源码分析
HashSet集合保证元素唯一性的原理
add("aa");方法----hashCode()计算"aa"的hash值
1.根据对象的哈希值计算存储位置         
         如果当前位置没有元素则直接存入 (方法中的生成数组的存储位置)            
​        如果当前位置有元素存在,则进入第二步     
2.当前元素的元素和已经存在的元素比较哈希值           
​        如果哈希值不同,则将当前元素进行存储 (以前的元素的链表的最后面)        
​        如果哈希值相同,则进入第三步     
3.通过equals()方法比较两个元素的内容 (和以前的元素的链表的每个元素内容进行比较)                  
​        如果内容不相同,则将当前元素进行存储(以前的元素的链表的最后面)      
​        如果内容相同,则不存储当前元素
五、常见数据结构之哈希表
hash表内存结构图.png
六、HashSet集合存储学生对象并遍历  
[Java] 纯文本查看 复制代码
package hashset;
  ​
  public class Student {
      private String name;
      private int age;
  ​
      public Student() {
      }
  ​
      public Student(String name, int age) {
          this.name = name;
          this.age = age;
      }
  ​
      public String getName() {
          return name;
      }
  ​
      public void setName(String name) {
          this.name = name;
      }
  ​
      public int getAge() {
          return age;
      }
  ​
      public void setAge(int age) {
          this.age = age;
      }
  ​
      @Override
      public String toString() {
          return "Student{" +
                  "name='" + name + '\'' +
                  ", age=" + age +
                  '}';
      }
      //为了实现Set集合的特点。不能有重复的元素,需要重写equals()和hashCode()方法,自动生成即可
      @Override
      public boolean equals(Object o) {
          if (this == o) return true;
          if (o == null || getClass() != o.getClass()) return false;
  ​
          Student student = (Student) o;
  ​
          if (age != student.age) return false;
          return name != null ? name.equals(student.name) : student.name == null;
      }
       //为了让java虚拟机先去比较两个对象的hash值,用这个hashCode()方法获取hash值
      //如果hash值相同,就去调用equals()方法,来比较两个对象的内容,如果不同,就存储
      //相同则不存储,如果hash值不同,就直接存储这个对象
      @Override
      public int hashCode() {
          int result = name != null ? name.hashCode() : 0;
          result = 31 * result + age;
          return result;
      }
  }
  ​
  ​
  ​
  package hashset;
  ​
  import java.util.HashSet;
  ​
  public class HashSetTest {
      public static void main(String[] args) {
          //创建HashSet对象
          HashSet<Student> hs = new HashSet<>();
          //创建学生对象
          Student s1 = new Student("张三",21);
          Student s2 = new Student("李四",22);
          Student s3 = new Student("王五",23);
          Student s4 = new Student("王五",23);
          //添加学生对象
          hs.add(s1);
          hs.add(s2);
          hs.add(s3);
          hs.add(s4);
          //增强for循环遍历集合
          for (Student s : hs){
              System.out.println(s);
          }
      }
  }

七、LinkedHashSet集合概述和特点
1.LinkedHashSet集合是HashSet集合的子类      
2.LinkedHashSet集合不能存储重复元素      
3.LinkedHashSet集合可以保证元素存取有序
总结特点:LinkedHashSet集合可以按照存储顺序来取出数据
  
  
[Java] 纯文本查看 复制代码
package linkedhashset;
  //LingkedHashSet集合可以按照存储顺序来取出数据
  import java.util.LinkedHashSet;
  ​
  public class LinkedHashSetTest {
      public static void main(String[] args) {
          //创建LinkedHashSet集合对象
          LinkedHashSet<String> lhs = new LinkedHashSet<String>();
          //添加元素
          lhs.add("aaa");
          lhs.add("bbb");
          lhs.add("ccc");
          //增强for循环输出
          for (String s : lhs){
              System.out.println(s);
          }
      }
  }

八、TreeSet集合概述和特点
1.元素有序。元素可以按照一定规则进行排序。具体要取决于构造方法              
​                TreeSet():根据元素的自然顺序进行排序               
​                TreeSet(Comparator c):根据指定的比较器进行排序
​                实现自然排序Comparable接口,来创建指定的自然排序        
2.TreeSet集合没有索引。只能通过迭代器、增强for循环进行遍历        
3.TreeSet集合不能存储重复元素
[Java] 纯文本查看 复制代码
 package treeset;
  /*
  特点:
      不能有重复元素
      默认构造方法,按照jdk指定的自然排序,1-10,a-z...这样的顺序排序
   */
  import java.util.TreeSet;
  ​
  public class TreeSetTest {
      public static void main(String[] args) {
          //创建TreeSet集合对象
          TreeSet<String> treeSet = new TreeSet<>();
          //添加元素
          treeSet.add("ccc");
          treeSet.add("ddd");
          treeSet.add("aaa");
          treeSet.add("bbb");
          treeSet.add("段");
          treeSet.add("孟");
          treeSet.add("钊");
          //增强for循环输出
          for (String s : treeSet){
              System.out.println(s);
          }
      }
  }

九、自然排序Comparable的使用  
  
[Java] 纯文本查看 复制代码
package comparable;
  ​
  import java.io.Serializable;
  ​
  public class Student implements Comparable<Student> {
      private String name;
      private int age;
  ​
      public Student() {
      }
  ​
      public Student(String name, int age) {
          this.name = name;
          this.age = age;
      }
  ​
      public String getName() {
          return name;
      }
  ​
      public void setName(String name) {
          this.name = name;
      }
  ​
      public int getAge() {
          return age;
      }
  ​
      public void setAge(int age) {
          this.age = age;
      }
  ​
      @Override
      public String toString() {
          return "Student{" +
                  "name='" + name + '\'' +
                  ", age=" + age +
                  '}';
      }
  ​
      @Override
      public int compareTo(Student s) {
          int num1 = this.age - s.age;
          //string类中也重写了compareTo()方法
          int num2 = num1 == 0 ? this.name.compareTo(s.name) : num1;
          return num2;
      }
  }
  ​
  ​
  package comparable;
  ​
  import java.util.TreeSet;
  ​
  public class ComparableTest {
      public static void main(String[] args) {
          //创建TreeSet集合对象:默认构造方法不能排序我们自己给定的自定义对象
          //这是需要使用第一种方式:自然排序Comparable接口
          /*
          1.实现自然排序Comparable接口:Student implements Comparable<Student>
          2.重写comprareTo()方法,返回值是int类型,返回值规则:
              为0:代表两个相比较的对象是相等的,根据Set集合特性不能有重复元素,他是不会添加进集合中的
              为正数1:代表后面添加进去的对象a比前面添加进去的对象b大,按照从小到大排序,a排在b的后面
              为负数-1:代表后面添加进去的对象a比前面添加进去的对象b小,按照从大到小排序,a排在b的前面
           */
          TreeSet<Student> ts = new TreeSet<>();
  ​
          //按照年龄大小排序,从小到大,次级按照姓名排序,从小到大
          Student s1 = new Student("张三",21);
          Student s2 = new Student("李四",22);
          Student s3 = new Student("王五",23);
          Student s4 = new Student("赵六",23);//为了更好的排序
          Student s5 = new Student("赵六",23);//为了显示Set集合的特点:不重复的元素
          //添加元素
          ts.add(s1);
          ts.add(s2);
          ts.add(s3);
          ts.add(s4);
          ts.add(s5);
          //增强for循环输出
          for (Student s : ts){
              System.out.println(s);
          }
      }
  }

  ​十、比较器排序Comparator的使用
技巧:Comparator集合也是接口,但是我们只使用一次,建议使用匿名内部类调用
  
  
[HTML] 纯文本查看 复制代码
package comparable;
  ​
  import java.io.Serializable;
  ​
  public class Student implements Comparable<Student> {
      private String name;
      private int age;
  ​
      public Student() {
      }
  ​
      public Student(String name, int age) {
          this.name = name;
          this.age = age;
      }
  ​
      public String getName() {
          return name;
      }
  ​
      public void setName(String name) {
          this.name = name;
      }
  ​
      public int getAge() {
          return age;
      }
  ​
      public void setAge(int age) {
          this.age = age;
      }
  ​
      @Override
      public String toString() {
          return "Student{" +
                  "name='" + name + '\'' +
                  ", age=" + age +
                  '}';
      }
  ​
      @Override
      public int compareTo(Student s) {
          int num1 = this.age - s.age;
          //string类中也重写了compareTo()方法
          int num2 = num1 == 0 ? this.name.compareTo(s.name) : num1;
          return num2;
      }
  }
  ​
  package comparable;
  ​
  import java.util.Comparator;
  import java.util.TreeSet;
  ​
  public class ComparatorTest {
      public static void main(String[] args) {
          TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
              @Override
              public int compare(Student s1, Student s2) {
                  //s1---this,s2---s
                  int num1 = s1.getAge() - s2.getAge();
                  //string类中也重写了compareTo()方法
                  int num2 = num1 == 0 ? s1.getName().compareTo(s2.getName()) : num1;
                  return num2;
              }
          });
          Student s1 = new Student("张三",21);
          Student s2 = new Student("李四",22);
          Student s3 = new Student("王五",23);
          Student s4 = new Student("赵六",23);//为了更好的排序
          Student s5 = new Student("赵六",23);//为了显示Set集合的特点:不重复的元素
          //添加元素
          ts.add(s1);
          ts.add(s2);
          ts.add(s3);
          ts.add(s4);
          ts.add(s5);
          //增强for循环输出
          for (Student s : ts){
              System.out.println(s);
          }
      }
  }

十一、成绩排序  
  
[Java] 纯文本查看 复制代码
package comparator;
  ​
  public class Student implements Comparable<Student> {
      private String name;
      private int chinese;
      private int math;
  ​
      public Student() {
      }
  ​
      public Student(String name, int chinese, int math) {
          this.name = name;
          this.chinese = chinese;
          this.math = math;
      }
  ​
      public String getName() {
          return name;
      }
  ​
      public void setName(String name) {
          this.name = name;
      }
  ​
      public int getChinese() {
          return chinese;
      }
  ​
      public void setChinese(int chinese) {
          this.chinese = chinese;
      }
  ​
      public int getMath() {
          return math;
      }
  ​
      public void setMath(int math) {
          this.math = math;
      }
  ​
      @Override
      public String toString() {
          return "Student{" +
                  "name='" + name + '\'' +
                  ", chinese=" + chinese +
                  ", math=" + math +
                  ", num=" + getSum() +
                  '}';
      }
      public int getSum(){
          return chinese+math;
      }
      @Override
      public int compareTo(Student s) {
          /*
          在compareTo()方法中,
          this:代表当前添加的对象,
          s:代表要进行比较的对象,
          返回值:s.getSum() - this.getSum()
          0---代表s.getSum()和this.getSum()相同,不会添加这个this.getSum()对象
          正数1---代表this.getSum()这个对象要排在s.getSum()这个对象的前面,按从大到小排序
          负数-1---代表this.getSum()这个对象要排在s.getSum()这个对象的后面,按从小到大排序
           */
          //System.out.println(this.name);
          //System.out.println(s.name);
          int num1 = s.getSum() - this.getSum();
          int num2 = num1 == 0 ? this.chinese - s.chinese : num1;
          int num3 = num2 == 0 ? this.name.compareTo(s.name) : num2;
          return num3;
      }
  }
  ​
  ​
  package comparator;
  /*
  //使用自然排序comparable接口,
  需要在需要排序的对象的自定义类中实现Comparable接口:implements Comparable<自定义类名>
  这里传的参数是你要进行比较的对象的自定义类
  并且要重写Comparable接口中的compareTo(自定义类名 引用名)方法,
  */
  import java.util.TreeSet;
  ​
  public class ComparableTest {
      public static void main(String[] args) {
          TreeSet<Student> ts = new TreeSet<>();
          Student s1 = new Student("张三",65,85);
          Student s2 = new Student("李四",70,85);
          Student s3 = new Student("王五",80,85);
          Student s4 = new Student("赵六",80,85);
          ts.add(s1);
          ts.add(s2);
          ts.add(s3);
          ts.add(s4);
          for (Student s : ts){
              System.out.println(s);
          }
      }
  }
  ​
  ​
  ​
  package comparator;
  //按照学生成绩,从高到低进行排序
  import java.util.Comparator;
  import java.util.TreeSet;
  ​
  public class ComparatorTest {
      public static void main(String[] args) {
          //使用比较器Comparator接口,只用一次,所以使用匿名内部类来实现Comparator接口
          //
          TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
              /*
              new Comparator<自定义类名>(){这里传的参数是你要进行比较的对象的自定义类
                  匿名内部类需要重写Comparator接口的方法---compare(自定义类名 引用名)
                  注意:返回值:0--代表和集合已经存在的元素进行相比较的元素相同,不会存储到集合
                  正数1:---代表和集合已经存在的元素进行相比较的元素a,比已经存在的元素b大,
                  a会排在b的后面,按照从小到大排序
                  负数-1---代表和集合已经存在的元素进行相比较的元素a,比已经存在的元素b小,
                  a会排在b的前面,按照从大到小排序
              }
  ​
              */
              @Override
              public int compare(Student s1, Student s2) {
                  int num1 = s2.getSum() - s1.getSum();
                  int num2 = num1 == 0 ? s1.getChinese() - s2.getChinese() : num1;
                  int num3 = num2 == 0 ? s1.getName().compareTo(s2.getName()) : num2;
                  return num3;
              }
          });
          Student s1 = new Student("张三",65,85);
          Student s2 = new Student("李四",70,85);
          Student s3 = new Student("王五",80,85);
          Student s4 = new Student("赵六",80,85);
          ts.add(s1);
          ts.add(s2);
          ts.add(s3);
          ts.add(s4);
          for (Student s : ts){
              System.out.println(s);
          }
      }
  }
  ​

  ​十二、不重复的随机数  
[Java] 纯文本查看 复制代码
 package random;
  ​
  import java.util.HashSet;
  import java.util.Random;
  import java.util.Set;
  import java.util.TreeSet;
  ​
  /*
  1.创建一个HashSet和TreeSet集合对象,泛型为Integer类型
       2.创建Random对象,用于生成随机数
       3.使用while循环判断集合长度是否不等于10
           如果长度不为10,则生成随机数保存到集合中
        4.使用增强for循环遍历集合
  ​
   */
  public class SetTest {
      public static void main(String[] args) {
          //创建一个HashSet对象,泛型为Integer类型
          //Set<Integer> s = new HashSet<Integer>();//生成无序
          Set<Integer> s = new TreeSet<Integer>();//生成有序
          //创建Random对象,用于生成随机数
          Random r =new Random();
          //使用while循环判断集合长度是否不等于10
          while(s.size() <= 10){
              //添加随机数,生成1-20的随机数
              int i = r.nextInt(20) + 1;
              s.add(i);
          }
          //使用增强for循环遍历集合
          for (Integer i : s){
              System.out.println(i);
          }
      }
  }

十三、泛型概述和好处什么是泛型(参数化类型)
泛型指的是广泛的数据类型,就是将原来具体的类型参数化,在使用的时候再传入具体的类型!
泛型的好处  (在编译期类型检查,不用类型转换)
将运行时期的错误提前到了编译期间     
省去了类型转换的麻烦
十四、泛型类  
  泛型类的定义(在自定义类名后面加<E e>,E,T,Y泛指所有类型)
      
[Java] 纯文本查看 复制代码
public class Generic<T> {
          private T t;
          public T getT() {
           return t;
          }
          public void setT(T t) {
              this.t = t;
       }
        }

  泛型类的使用
         
[Java] 纯文本查看 复制代码
Generic<String> g1 = new Generic<String>();
          g1.setT("林青霞");
          System.out.println(g1.getT());
  ​
          Generic<Integer> g2 = new Generic<Integer>();
          g2.setT(30);
          System.out.println(g2.getT());

  ​十五、泛型方法  
  泛型方法的定义(在修饰符后面加<E e>,E,T,Y泛指所有类型)
        
[Java] 纯文本查看 复制代码
public class Generic {
             public <T> void show(T t) {
                  System.out.println(t);
             }
          }

  泛型方法的使用
        
[Java] 纯文本查看 复制代码
 Generic g = new Generic();
          g.show("林青霞");
          g.show(30);
          g.show(true);
          g.show(12.34);

  ​十六、泛型接口  
  泛型接口的定义(在自定义类名后面加<E e>,E,T,Y泛指所有类型)
      
[Java] 纯文本查看 复制代码
 public interface Generic<T> {
            void show(T t);
         }
         public class GenericImpl<T> implements Generic<T> {
              @Override
              public void show(T t) {
                  System.out.println(t);
              }
         }

  泛型接口的使用
         
[Java] 纯文本查看 复制代码
Generic<String> g1 = new GenericImpl<String>();
          g1.show("林青霞");
  ​
          Generic<Integer> g2 = new GenericImpl<Integer>();
          g2.show(30);

  ​十七、类型通配符<?>
List<?>:表示元素类型未知的List,它的元素可以匹配任何的类型     
这种带通配符的List仅表示它是各种泛型List的父类,并不能把元素添加到其中类型通配符向上限定
<? extends 类型>
List<? extends Number>:它表示的类型是Number或者其子类型类型通配符向下限定
<? super 类型>
List<? super Number>:它表示的类型是Number或者其父类型
十八、可变参数什么是可变参数
可变参数又称为参数个数可变,用于方法的形式参数使用。
可变参数的注意事项
可变参数其实是一个数组      
如果一个方法有多个参数,而且包含可变参数。可变参数要放在最后
  
  
[Java] 纯文本查看 复制代码
public static void main(String[] args) {
          System.out.println(show(10,20));
          System.out.println(show(10,20,30));
          System.out.println(show(10,20,30,40));
  ​
  ​
      }
      /*public static void show(int a,int b){
          System.out.println(a+", "+b);
      }
      public static void show(int a){
          System.out.println(a+);
      }
      public static void show(int a,int b,int c){
          System.out.println(a+", "+b+", "+c );
      }*/
      /*public static int show(int... a){
          int sum = 0;
          for (int i : a){
              sum+=i;
          }
          return sum;
      }*/
      public static int show(int b, int...a){
          int sum = 0;
          for (int i : a){
              sum+=i;
          }
          return sum;
      }

  ​十九、可变参数的使用  
  JDK中提供的类使用可变参数的方法
        
[Java] 纯文本查看 复制代码
Arrays工具类中有一个静态方法:
          public static <T> List<T> asList•(T... a):返回由指定数组支持的固定大小的列表
  ​
        List接口中有一个静态方法:
          public static <E> List<E> of•(E... elements):返回包含任意数量元素的不可变列表
  ​
        Set接口中有一个静态方法:
          public static <E> Set<E> of•(E... elements) :返回一个包含任意数量元素的不可变集合
          //public static <T> List<T> asList•(T... a):返回由指定数组支持的固定大小的列表
          /*List<Integer> list = Arrays.asList(10,20,30);
          //list.add(40);//UnsupportedOperationException,不能添加元素
          //list.remove(20);//UnsupportedOperationException,不能删除元素
          list.set(1,40);//可以修改元素
          System.out.println(list);*/
          //public static <E> List<E> of•(E... elements):返回包含任意数量元素的不可变列表
          /*List<Integer> list = List.of(10,20,30);
          //list.add(40);//UnsupportedOperationException,不能添加元素
          //list.remove(20);//UnsupportedOperationException,不能删除元素
          //list.set(1,40);//不能修改元素
          System.out.println(list);*/
          //public static <E> Set<E> of•(E... elements) :返回一个包含任意数量元素的不可变         集合
          Set<Integer> set = Set.of(10,20,30);
          //set.add(40);//UnsupportedOperationException,不能添加元素
          //set.remove(20);//UnsupportedOperationException,不能删除元素
          //set.set(1,40);//Set集合里面没有带索引的方法,例如:set()
          System.out.println(set);      

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马