Day17---昨天周六休息一天

虽然昨天周六休息了了,但早上还是去了图书馆学习了下,只不过当时效率不太高,产出不多。今天专注学习时间大于5个小时。学习效率还是蛮高的,把Set接口学了以及复习了一部分之前的知识。还学了一部分的Map接口,开了个头,接下来的一周,可能学习时间不太够,但我还是会寄出来些时间,确保每天专注学习时间大于3小时,加油OVO。

Day17

新发现一个快捷键,双击Shift ,就可以查找所有了。

Set接口

 

HashSet和LinkedHashSet

package com.sorrymaker.CollectionTest;

import org.junit.Test;

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

/**
* 1.set接口的框架
* /---Collection接口
*   /--Set接口:存储无序的,不可重复的数据   ---> 高中讲的“集合”
*       /--HashSet:作为Set接口的主要实现类,线程不安全,可以存储null值
*           /--LinkedHashSet:作为HashSet的子类;遍历其内部数据时,可以按照添加的顺序遍历、
*                             对于频繁的的遍历操作,LinkedHashSet效率高于HashSet
*       /--TreeSet:可以按照添加对象的指定属性,进行排序。
*
* 1.Set接口没有额外定义的方法,都是Collection的方法。
* 2.要求:向Set中添加的数据,其所在类一定给要重写hashCode()和equals()
*   要求:重写的hashCode()和equals()尽可能保持一致性。
*/

public class SetTest {
   /*
   一、Set:无序的,不可重复的。
   HashSet为例
   1.无序性:不等于随机性,存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的Hash值决定的。

   2.不可重复性:保证添加的元素按照equals()判断时,不能返回true,即:相同的元素只能添加一个。
   二、添加元素的过程:以HashSet为例:
       向HashSet中添加元素a,首先调用元素a所在的hashCode()方法,计算元素a的哈希值,
       此时哈希值接着通过某种计算在HashSet底层数组中的存放位置(即为索引位置),判断
       数组此位置是否已经有元素;
           如果此位置上没有其他元素,则元素a添加成功 ----->情况1
           如果此位置上有其他元素b(或以链表形式存在的多个元素),则比较元素a与元素b的hash值:
               如果hash值不同,则元素a添加成功 ------>情况2
               如果hash值相同,进而需要调用元素a所在类的equals()方法:
                       equals()返回True,元素a添加失败。
                       equals()返回false,则元素a添加成功 ----->情况2
        HashSet底层:数组+链表的结构。
    */
   @Test
   public void test1(){
       //LinkedHashSet作为HashSet的子类,在添加数据的同时,每个数据还维护了两个引用,记录了此数据前一个和后一个数据
       //对于频繁的的遍历操作,LinkedHashSet效率高于HashSet
       Set set =new LinkedHashSet();
       set.add(456);
       set.add(123);
       set.add("AA");
       set.add("cc");
       set.add(123);//Set不可重复性,所以不会输出两个一样的对象。
       set.add(new Person("tom",20));
       set.add(new Person("ton",20));//地址值不一样,所以都能输出

       Iterator iterator =set.iterator();
       while (iterator.hasNext()){
           System.out.println(iterator.next());
      }
  }
}

 

TreeSet

package com.sorrymaker.CollectionTest;

import org.junit.Test;

import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

public class TreeSetTest {
   /*
   1.向TreeSet中添加的数据,要求是相同类的对象。
   2.两种排序方式:自然排序(实现Comparable接口)和定制排序。

   3.自然排序中,比较两个对象是否相同的标准为:compareTo()返回0,不再是equals();
   4.在定制排序中,比较两个对象是否相同的标准为:compare()返回0,不再是equals();
    */
   @Test
   public void test1(){
       TreeSet set = new TreeSet();
       //失败,不能添加不同类的对象
//       set.add(123);
//       set.add(456);
//       set.add(new Person("小明",21));
//       set.add(456);

       //举例一:可以排序,按照从小到大。
//       set.add(123);
//       set.add(456);
//       set.add(789);
//       set.add(-2);

       //举例二:自定义的排序
       set.add(new User("AA",21));
       set.add(new User("CC",22));
       set.add(new User("QS",23));
       set.add(new User("LJS",19));
       set.add(new User("LOL",2));
       set.add(new User("LOL",12));

       Iterator iterator =set.iterator();
       while(iterator.hasNext()){
           System.out.println(iterator.next());
      }
  }
   @Test
   public void test2(){
       Comparator com =new Comparator() {
           //按照年龄从小到大排序。
           @Override
           public int compare(Object o1, Object o2) {
               if(o1 instanceof User && o2 instanceof User){
                   User u1 =(User) o1;
                   User u2 =(User) o2;
                   return Integer.compare(u1.getAge(),u2.getAge());
              }else {
                   throw new RuntimeException("输入的数据类型不匹配");
              }
          }
      };
       TreeSet set =new TreeSet(com);//有参数,就按照定制的排序了。
       set.add(new User("AA",21));
       set.add(new User("CC",22));
       set.add(new User("QS",23));
       set.add(new User("LJS",19));
       set.add(new User("LOL",2));
       set.add(new User("QQ",2));
       set.add(new User("LOL",12));

       Iterator iterator =set.iterator();
       while(iterator.hasNext()){
           System.out.println(iterator.next());
      }
  }
}

 

今日五题:

  1. 集合Collection 中存储的如果是自定义的对象,需要自定义类重写那个方法?为什么?

    重写equals()方法。 contains()/remove()/retainsAll()

    List:equals()方法

    Set(HashSet和LinkedHashSet为例):重写equals()和hashCode()。

    (TreeSet为例):Comparable:compareTo(Object obj)

    Comparator:compare(Object o1,Object o2)(相同的元素不输出)


  2. ArrayList,LinkedList,Vector 三者的相同点不同点:

    List Map Set

    相同点:

    ArrayList :作为List接口的主要实现类。线程不安全,效率高。开发中经常用。扩容的时候是1.5倍,底层是Object[] elementData存储,查找效率高,插入效率低,O*n

    LinkedList:效率高。底层存储是以双向链表存储,查找效率低O的n次方,插入效率高。

    Vector:古老的,效率低,扩容的是2倍。底层使用Object[] elementData存储,线程安全。


  3. List的接口的常用方法有那些(增。删。改。查。插入。长度。遍历)

    1. add(Object obj)

    2. remove(int index)/remove(Object obj)

    3. set(int index,Object obj)

    4. get(int index)

    5. add(int index , Object obj)

    6. size()-----返回的是元素的个数。

    7. 使用迭代器

      iterator;foreach;普通的for循环。


  1. 如何使用Iterator ,foreach,遍历list,举例说明:

public void test2(){
   ArrayList list = new ArrayList();
   list.add(123);
   list.add(456);
   list.add("Aa");
   //方式一,使用迭代器Iterator遍历
   Iterator iterator =list.iterator();
   while(iterator.hasNext()){
       System.out.println(iterator.next());
  }
   //方式二:增强for循环
   for(Object obj:list){
       System.out.println(obj);
  }
   //方式三:普通for循环
   for (int i =0;i<list.size();i++){
       System.out.println(list.get(i));
  }
}

  1. Set的存储数据的特点是说明?常见的实现类有什么?说明以下特点。

    特点:Set:无序的,不可重复的。

    常见的实现类:HashSet

    LinkedHashSet

    TreeSet

 

今日代码

自然排序和定制排序

EmplyeeTest

package com.sorrymaker.TreeSetTest;

import org.junit.Test;

import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

public class EmployeeTest {
   //2.按生日日期的先后顺序排序
   @Test
   public void test2() {
       TreeSet set = new TreeSet(new Comparator() {
           @Override
           public int compare(Object o1, Object o2) {
               if (o1 instanceof Employee && o2 instanceof Employee) {
                   Employee e1 = (Employee) o1;
                   Employee e2 = (Employee) o2;

                   MyDate b1 = e1.getBirthday();
                   MyDate b2 = e2.getBirthday();
                   //方式一:
//                   //比较年
//                   int minusYear = b1.getYear() - b2.getYear();
//                   if (minusYear != 0) {
//                       return minusYear;
//                   }
//                   //比较月
//                   int minusMonth = b1.getMonth() - b2.getMonth();
//                   if (minusMonth != 0) {
//                       return minusMonth;
//                   }
//                   //比较日
//                   return b1.getDay()- b2.getDay();
//               }
                   //方式二:
                   return b1.compareTo(b2);
              }
               throw new RuntimeException("数据不一致,");
          }
      });
       Employee e1 = new Employee("lianghuisen", 21, new MyDate(2000, 07, 25));
       Employee e2 = new Employee("xiaofeizhu", 21, new MyDate(2000, 05, 25));
       Employee e3 = new Employee("naocan", 19, new MyDate(2002, 02, 23));
       Employee e4 = new Employee("ruozhi", 20, new MyDate(2001, 05, 23));
       Employee e5 = new Employee("choushabi", 22, new MyDate(1999, 05, 23));
       set.add(e1);
       set.add(e2);
       set.add(e3);
       set.add(e4);
       set.add(e5);

       Iterator iterator = set.iterator();
       while (iterator.hasNext()) {
           System.out.println(iterator.next());

      }
  }
   //1.自然排序
   @Test
   public void test1(){
       TreeSet set =new TreeSet();
       Employee e1 =new Employee("lianghuisen",21, new MyDate(2000,07,25));
       Employee e2 =new Employee("xiaofeizhu",21, new MyDate(2000,05,25));
       Employee e3 =new Employee("naocan",19, new MyDate(2002,02,23));
       Employee e4 =new Employee("ruozhi",20, new MyDate(2001,05,23));
       Employee e5 =new Employee("choushabi",22, new MyDate(1999,05,23));
       set.add(e1);
       set.add(e2);
       set.add(e3);
       set.add(e4);
       set.add(e5);

       Iterator iterator = set.iterator();
       while (iterator.hasNext()){
           System.out.println(iterator.next());
      }
  }
}

MyDate

package com.sorrymaker.TreeSetTest;

public class MyDate implements Comparable {
   private int year;
   private int month;
   private int day;

   public MyDate() {
  }

   public MyDate(int year, int month, int day) {
       this.year = year;
       this.month = month;
       this.day = day;
  }

   public int getYear() {
       return year;
  }

   public void setYear(int year) {
       this.year = year;
  }

   public int getMonth() {
       return month;
  }

   public void setMonth(int month) {
       this.month = month;
  }

   public int getDay() {
       return day;
  }

   public void setDay(int day) {
       this.day = day;
  }

   @Override
   public String toString() {
       return "MyDate{" +
               "year=" + year +
               ", month=" + month +
               ", day=" + day +
               '}';
  }

   @Override
   public int compareTo(Object o) {
       MyDate d = (MyDate) o;
       //比较年
       int minusYear = this.getYear() - d.getYear();
       if (minusYear != 0) {
           return minusYear;
      }
       //比较月
       int minusMonth = this.getMonth() - d.getMonth();
       if (minusMonth != 0) {
           return minusMonth;
      }
       //比较日
       return this.getDay() - d.getDay();
  }
}

Employee

package com.sorrymaker.TreeSetTest;

public class Employee implements Comparable {
   private String name;
   private int age;
   private MyDate birthday;

   public Employee() {
  }

   public Employee(String name, int age, MyDate birthday) {
       this.name = name;
       this.age = age;
       this.birthday = birthday;
  }

   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;
  }

   public MyDate getBirthday() {
       return birthday;
  }

   public void setBirthday(MyDate birthday) {
       this.birthday = birthday;
  }

   @Override
   public String toString() {
       return "Employee{" +
               "name='" + name + '\'' +
               ", age=" + age +
               ", birthday=" + birthday +
               '}';
  }


   @Override
   public int compareTo(Object o) {
       if(o instanceof Employee){
           Employee e =(Employee) o;
           return this.name.compareTo(e.name);//按从小到大排序
      }else {
        throw new RuntimeException("数据错误");
      }
  }
}

 

课后两道小题

1.在List内去除重复数字值,要求尽量简单。

2.哈希值,在从写了hashCode()和equals()方法的前提下。

package com.sorrymaker.CollectionTest;

import org.junit.Test;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

public class dayTest {
   //在List内去除重复数字值,要求尽量简单。
   public static List duplicateList(List list){
       HashSet set =new HashSet();
       set.addAll(list);
       return new ArrayList(set);
  }
   @Test
   public void test(){
       List list =new ArrayList();
       list.add(new Integer(1));
       list.add(new Integer(1));
       list.add(new Integer(2));
       list.add(new Integer(2));
       list.add(new Integer(5));
       List list1 = duplicateList(list);
       for(Object integer:list1){
           System.out.println(integer);
      }
  }
   @Test
   public void test1(){
       //因为有person类了,所以我建个Atm类
       HashSet set =new HashSet();
       Atm atm1 =new Atm("小红",21);
       Atm atm2 =new Atm("lv",11);
       set.add(atm1);
       set.add(atm2);
       System.out.println(set);//[Atm{name='小红', age=21}, Atm{name='lv', age=11}]
       atm1.name ="panda";
       
       //hashCode的值改变了,按照原本的hashCode值找不到,所以没删除。
       set.remove(atm1);//按照哈希值删除,又因为已经改变了,所以没删除到。
       System.out.println(set);//[Atm{name='lv', age=11}, Atm{name='panda', age=21}]
       
       set.add(new Atm("panda",21));
       //这个是拿原本的"小红","11"的hash值算,发现没有,所以就可以添加这个元素。
       
       System.out.println(set);//[Atm{name='lv', age=11}, Atm{name='panda', age=21}, Atm{name='panda', age=21}]
       
       set.add(new Atm("小红",21));
       //虽然hash值一样,但是equals不一样,这里equals的是panda,所以不一样,就还是可以存储进去。
       
       System.out.println(set);//[Atm{name='lv', age=11}, Atm{name='panda', age=21}, Atm{name='panda', age=21}, Atm{name='小红', age=21}]
  }
}

 

Day17 Map接口

 

 

Map接口继承树

Day17---昨天周六休息一天

 

 

package com.sorrymaker.Map;

import org.junit.Test;

import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

/**
* 一、Map的实现类的结构:
* /----Map:双列数据,存储key-value键值对的数据   -类似于y =f(x)
*     /---HashMap:作为Map的主要实现类;线程不安全的,效率高。允许存储null的key和value
*             /---LinkedHashMap:保证在遍历map元素时,可以按照添加的顺序实现遍历。
*                         原因:在原有的HashMap底层结构的基础上,添加了一对指针,指向了前一个和后一个元素。
*                         对于频繁的遍历操作,此类执行效率高于HashMap。
*     /---TreeMap:保证按照添加的key-value对进行排序,实现排序遍历。按照key来自然排序和定制排序。
*                 底层使用红黑树。
*     /---Hashtable:作为古老的实现类;线程安全,效率低。不允许存储null的key和value。
*             /---Properties:常用来处理配置文件,key和value都是String类型。
*
*
*             HaspMap的底层:数组加链表(jdk7之前)
*                           数组加链表加红黑树 (jdk8)
*
* 面试题:
* 1.HashMap的底层实现原理:
* 2.HashMap 和Hashtable的异同。
* 3.CurrentHashMap 与Hashtable的异同。
*
* 二、Map的理解
*     Map中的key:无序的,不可重复的,使用Set存储所有的Key。--->key所在的类要重写equals()和hashCode()(以hashMap为例)。
*     Map中的value:无序的,可重复的,使用Collection 存储了所有的value--->value所在的类要重写equals()
*     一个键值对:key—value构成了一个Entry对象。
*     Map中的entry:无序的,不可重复的,使用所有Set存储所有entry。
*
* @author 喜
*/
public class MapTest {

   @Test
   public void test(){
       Map map =new HashMap();
       map =new Hashtable();
       map.put(null,null);
  }
}

 

上一篇:2021-02-06 大数据课程笔记 day17


下一篇:Day17,方法的定义和调用