JAVA--框架②

1、 Hash表

图上所指的这个变化,是针对JDK1.8中的HashMap特别提出的

2、 Map

Map常用有HashMpa和TreeMap

put之前如果key为引入数据类型,我们需要同时改写equals和hashCode方法,否则可能会出现equals方法为true但是他依旧存储了2个key进去

  public class IDCard{
      private String idNumber;
      
      public IDCard(String idNumber){
          this.idNumber=idNumber;
      }
      
      public String getIdNumber(){
          return idNumber;
      }
      
      public void setIdNumber(String idNumber){
          this.idNumber=idNumber;
      }
      
      @Override
      public boolean equals(Object o){
          if(this==o)return true;
          if(o==null||getClass()!=o.getCalss()) return false;
          IDCard idCard=(IDCard)o;
          return Objects.equals(idNumber,idCard.idNumber);
      }
      //@Override
      //public int hashCode(){
      //  return Objects.hash(idNumber);
      //}
  }
  
  public static void main(String[] args){
      Map map=new Map();
      IDCard id1=new IDCard("3201021993");
      IDCard id2=new IDCard("3201021993");
      System.out.println(id1.hashCode());//1163157884
  
      System.out.println(id1.hashCode());//1956725890
      System.out.println(id2.equals(id1));//true
      map.put(id1,"123");
      map.put(id2,"123");
      System.out.println(map.size());
  }

2.1、 关于map的put方法

​ put方法:在进行put的时候,我们会先将key执行hashCode方法,返回一个hash码值,通过计算,会最终获得到他存在于我们数组中的具体数组下标位置。hash码值是通过Object类下的一个方法,hashCode()return的一个int数。也就是说如果我们想要确定这个元素应该插入散列表中数组的位置,我们就要重写他的hashCode方法。接下来,我们看当前数组位置是否有值,如果没有值则直接插入到对应的位置。

​ 举个例子:如果你的身份证号相同(equals方法比较相同)可是你的对象内存地址不同(Object的hashCode不同)那么你依旧有可能会插入到同一个map中,因为map在执行put调用equals之前会判断当前数组是否为空内容。

​ 确定了数组位置之后并发现当前是存在元素的,那么就会和元素进行equals方法进行比较,比较之后如果找到了相同的key(equals结果为true)那么我们会将这个元素的value进行修改。

​ 如果不存在true,那么会直接插入。察隅会比较如果当前是单独元素,那么就直接将link到元素后面形成列表,如果当前是一个元素列表,并且这个列表的长度已经到7,那么我们就会将这个元素插入到这个列表中,并且将这个列表进化成红黑树。(进化到红黑树的逻辑是JDK1.8新增的,之前的版本不存在)

2.1、 关于map的get方法

​ get方法,我们会根据传入的值(key)先通过kay的hashCode算法去获取的hash值,再通过计算得出具体对应存储的数据下标。

​ 比如说:我们要查字典,查“我”,我们有几种方法:逐页查询,或者,我们通过拼音确定wo在第160,那么我们从160页开始查询。 找到位置之后,我们取看这个数组下标位置的元素是否为空,如果为空,则直接返回找不到,如果有东西,那么我们逐个查询,如果是链表就正常循环查找,如果是红黑树,就会使用二分法查找比较。

​ 总结:所以说HashMap即有用ArrayList的查询效率快(它实现通过列表位置去寻找到对用的位置)又拥有LinkedList的快速增删。因为他实际增删和数组增删无关,他是通过列表熔断或者是向树中插入。

2.3、 HashMap原理总结

我们的HashMap如过存在使用一个引用数据类型作为key的话,我们需要同时改写equals和hashCode方法,这个方法我们可以不用首手写,我们可以直接使用IDEA代码生成工具,Alt+insert选择equals and hashCode

2.4、 遍历打印map信息

  public static void main(String[] args){
      Map<Integer,String> map=new HashMap<>;
      map.put(1,"123");
      map.put(4,"123");
      map.put(5,"123");
      map.put(6,"123");
      //通过map的keySet()方法,可以将map中的所有key返回成为一个set
      Set<Integer> keys = map.keySet();
      
      //通过迭代器遍历set
      Ierator<Integer> iterator =key.iterator();
      While(iterator.HashNext()){
          Integer key=interator.next();
          System.out.println("key="+key+",value="+map.get(key));
      }
      
      System.out.println("===========1===============");
      //方法1:通过增强for循环
      for(Integer key:keys){
          System.out.println("key="+key+",value="+map.get(key))
      }
      
      System.out.println("===========2===============");
      //方法2:通过Map.EntrySet
      Set<Map.Entry<Integer,String>> entries = map.entrySet();
      //迭代器
      Iterator<Map.Entry<Integer>,String>> entriesI=entries.iterator();
      While(entriesI.hashNext()){
          Map.Enty<Integer,String> entrie=entriesI.next();
          System.out.println("key="+entrie.getKey()+",value="+entrie.getValue()):
      }
      System.out.println("===========3===============");
      //增强循环
      for(Map.Entry<Integer,String> m:entries){
          System.out.println("Key="+m.getKey()+",Value="+m.getValue());
      }
  }

3、 泛型

泛型是用于约定代码,约定指定参数写指定类型的一种功能。

  
  //泛型在声明时声明,实例化的时候可以省略泛型内容,会根据你声明的来。
  List<Integer> List=new ArrayList<>();
  //此时,由于ArrayList的add方法时这样的:
  public boolean add(E e){
      ensureCapacityInternal(size+1); //Increments modCount!
      elementData[size++]=e;
      returrn true;
  }
  //并且ArrayList的类的声明是这样的
  public class ArrayList<E> extends AbstractList<E>
      implement List<E>,RandomAccess,Colneable,java.io.Serializable
  //所以我们声明的这个Integer为E——泛型类容,由于add方法形参为(E e)所以,只能传入Interger对象
  list.add(1);
  //不能执行添加Integer以外的数据类型
  //比如0.5是double或者Double对象所以不能插入这个集合中
  //list.add(0.5);

泛型声明

 
  public class pet<这是泛型标识符可以随便写 extends Animal>{
      public void paly(这是泛型标识符可以随便写 animal){
          System.out.println("你在和动物玩"+animal);
      }
      //方法泛型
      public <E extends Animal>void getPet(E e){
          System.out.println(e);
      }
  } 
  ​
  public class Dog extends Animal {
  }
  ​
  public class Cat extends Animal{
  }
  ​
  public class Car{    
  }
  ​
  public static void main(String[] args){
      Pet<Cat> catPet=new Pet<>();
      Cat cat=new Car();
      Dog god=new Dog();
      Car car=new Car();
      catPet.play(cat);
      //不能传递dog因为泛型约定是Cat
      //catPet.play(dog);
      Pet<Dog> dogPet=new Pet<>();
      dogPet.play(dog);
      //不能传递cat因为泛型约定是Dog
      //dogPet.play(cat);
      
      //由于Pet的泛型定义时我们要求泛型必须继承Animal
      //而Car类并未继承Animal所以Car无法作为泛型声明
      //Pet<Car> pet=new Pet<>();
      
      catPet.getPet(dog);
      catPet.getPet(cat);
      //此时这个不能写,因为方法泛型约定了,参数必须继承Animal
      //catPet.getPet(car);
  }
  
  <T extends Comparable<? super T>>
  //泛型中的extends垢面可以写类或者接口,写类就是要求继承这个类,写接口就是要求继承这个接口
  //泛型中写?代表某一个类,过着说这个类要求,比图上述泛型<?super T>就说明,我们的这个泛型T
  //必须是实现一个泛型为 T的父类或者说是T本身类的 Comparable接口
  //super关键字为超类,如<E super T>就是要求E这个类是T类的父类或者是T本身

4、 Collections.sort方法

sort方法在Collections工具类中存在两个重载方法,一个方法是要求

  
  public static <T extends Comparable<? super T>> void sort(List<T> List){
      List.sort(null);
  }

第一个方法,参数只要传递一个集合,要求这个集合中的泛型对象必须是实现了Comparable接口,这个接口的中文是“可比较的”,当你实现了“可比较的”接口你需要重写一个方法,叫做compareTo的方法,这个是我们的比较规则,比如::

  public class User implements Comparable<User>{
      private String name;
      private int 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;
      }
      
      public User(){    
      }
      
      @Override
      public String toString(){
          retuen "User{"+
                  "name='"+name+'\''+
                  ",age="+age+
                  '}';
      }
      
      //compareTo方法为重写比较大小的方法
      //会根据你的返回结果进行大小的比较
      //这个方法是返回一个int类型,不过他只会在一你这个数字和0的关系
      //如果等于0,说明这两个对象一样大
      //否则,大于0或者小于0,存在两个大小关系
      @Override
      public int compareTo(User o){
          //假如我们的规则是根据年龄排序,那么我们就可以写
          //if(this.age==o.age){
          //    return 0;
          //}else if(this.age>o.age){
          //    return 1;
          //}else{
          //    return -1;
          //}
          
          //由于该方法只在乎你是否比0大,座椅哦我们就可以直接写成
          //return this.age-o.age
          
          //如果我们修改规则,如果年龄相等,按照姓名来排序
          if(this.age!=o.age){
              return this.age-o.age;
          }else{
              return this.name.compareTo(o.name);
          }
      }
  }
 //测试方法
  public static void main(String[] args){
      Lsit<User> list = new ArrayList<>();
      list.add(new User("zhangsan1",18));
      list.add(new User("lise",17));
      list.add(new User("wangwu",20));
      list.add(new User("zhangsan2",18));
      for(User user:list){
          System.out.print(user);
      }
      Collections.sort(list);
      
      System.out.println();
      System.out.println("排序后:");
      for(User user:list){
          System.out.print(user);
      }
  }

如果想要使用第一个方法,那么我们正确的步骤是:

首先在我们List所储存的泛型类,将这个类实现接口Comparable

第二部,由于实现了这个接口,所以你需要去重写他的抽象方法compareTo(T t)方法

完成了这两步,你就可以直接使用我们的Collections.sort(list);这个方法了

另一个方法是:

  
  public static <T> void sort(List<T> List,Comparator<? super T> c){
      List.sort(c);
  }

第二个方法,需要传递两个参数,第一个参数是一个集合,这里不要求list的泛型实现了Comparable接口(可比较的),但是你需要给他一个比较规则,就是一个比较器。Comparator 这个“比较器”是让我们可以进行写规则的地方。

我们可以新写一个类,这个类是实现了比较器的类,比如:

  
  public class MyComparator implements Comparator{
      @Override
      public int compare(Object o1,Object o2){
          //这了写规则
          return ((User)o1).getAge()-((User)o2).getAge();
      }
  }
  
  //测试方法
  public static void main(String[] args){
      Lsit<User> list = new ArrayList<>();
      list.add(new User("zhangsan1",18));
      list.add(new User("lise",17));
      list.add(new User("wangwu",20));
      list.add(new User("zhangsan2",18));
      for(User user:list){
          System.out.print(user);
      }
      //新建的比较器,这个比较器是我们自己写的,他的规则是根据用户的年龄排序
      MyComparator myComparator = new MyComparator();
      //此时我们的User类就可以不用去实现Comparable(可比较的这个接口)
      Collections.sort(list,myComparator);
      
      System.out.println();
      System.out.println("排序后:");
      for(User user:list){
          System.out.print(user);
      }
  }

!!!!!当我不想为了一个简答的规则,去写一个新的类,而且这个新的类我又不用在别的地方,有什么简单的放啊么?👇

Lambda表达式 JDK1.8新特性

  
  public static void main(String[] args){
      Lsit<User> list = new ArrayList<>();
      list.add(new User("zhangsan1",18));
      list.add(new User("lise",17));
      list.add(new User("wangwu",20));
      list.add(new User("zhangsan2",18));
      for(User user:list){
          System.out.print(user);
      }
      //list的泛型没有任何约束
      Collections.sort(list,(a,b)->{
         //这里的规则,要看你来,这里的a,b你也可以以写成x,y都可以
         //接下来,这个a,b或者x,y就是你的集合中的泛型对象。
         //但是lambda表达式只推荐你在里面写非常简单的代码,
         //如果逻辑复杂,推荐你还是使用其他方法
         return a.getAge()-b.getAge(); 
      });
      //此时就搞定了,这个就是Lambda表达式,箭头函数
      
      System.out.println();
      System.out.println("排序后:");
      for(User user:list){
          System.out.print(user);
      }
  }
其他方法

  
  public static void main(String[] args){
      //创建集合
      List<String> list=new ArrayList<String>();
      //增加10个不同单词
      List.add("this");
      List.add("is");
      List.add("collection");
      List.add("test");
      List.add("and");
      List.add("we");
      List.add("can");
      List.add("learn");
      List.add("how");
      List.add("to");
      //打印输出集合中最大元素和最小元素
      String strMax=(String) Collections.max(list);
      String strMin=(String) Collections.min(list);
      System.out.println("最大值"+strMax);
      System.out.println("最小值"+strMin);
      //按升序打印输出集合中的所有元素
      Collections.sort(list);
      System.out.println("集合升序");
      for(int i=0;i<list.size();i++){
          System.out.println(list.get(i));
      }
      System.out.println(Collections.binarySearch(list,"this"));
      //按降序打印输出集合中的所有元素
      Collections.reverse(list);
      System.out.println("集合降序");
      for(int i=0;i<list.size();i++){
          System.out.println(list.get(i));
      }
  }

5、 List的常用方法

主要!!!start

  //添加元素
  boolean add(E e);//在集合的末尾处添加一个元素
  void add(int index,E e);//向坐标为index的位置添加元素
  ​
  //向集合的末尾处添加一个集合(可以是List,可以是Map,只要是Collection的实现都有可以)
  boolean addAll(Collection<? extends E> c); 
  boolean addAll (int index,Collection<? extends E> c);//向坐标为index的位置添加一组元素
  ​
  //从此列表中删除所有元素,无返回,调用即删除
  void clear();
  ​
  //是否包含元素
  boolean contains(Object o);//是否包含该元素
  boolean containsAll(collection<?> c);//是否包含所有元素
  ​
  //返回比较两个内容是否相同
  boolean equals(Object 0);
  ​
  //获取坐标位置的值,如果下标超过元素数量 异常:IndexOutOfBoundsException
  E get(int index);
  ​
  //返回此列表中指定元素的第一次出现索引,如果此列表不包含元素,则返回-1
  int indexOf(Object o);//正向查找
  int lastIndexOf(Object o);//反向查找
  ​
  //判断是否为空
  boolean isEmpty();
  ​
  //获取list的迭代器
  Iterator<E> iterator();
  ​
  //删除
  E remove(int index);
  boolean remove(Object o);
  boolean removeAll(collection<?> c);
  ​
  //仅保存集合内容
  boolean ratainAll(collection<?> c);
  ​
  //设置坐标元素成指定元素
  E set(int index,E element);
  ​
  //获取长度
  int size();
  ​
  //需要传递一个比较器,可以使用箭头函数
  default void sort(Comparator<? super E>c);
  ​
  //截取集合通过坐标位置和String一样[),左边包含,右边不包含
  List<E> subList(int fromIndex,int toIndex);
  ​
  //转数组
  Object[] toArray();
  <T> T[] toArray(T[] a);

主要!!!end

  public static void main(String[] args){
      List<Integer> list=new ArrayList<>();
      //添加元素,add()
      //add(E)
      list.add(123);
      list.add(9);
      list.add(5);
      list.add(8);
      list.add(1,1);
      List<Integer> list1=new ArrayList<>();
      //添加元素,add()
      //add(E)
      list1.add(124);
      list1.add(125);
      list.addAll(list1);
      //list.clear();
      for(Integer i:list){
          //System.out.println(i);
      }
      //System.out.println(list.contains(123));
      //System.out.println(list.containsAll(list1));
      //list1.add(168);
      //System.out.println(list.containsAll(list1));
      //list1.clear();
      //System.out.println(list.containsAll(list1));
  ​
      //System.out.println(list.equals(list));
      List<Integer> list2=new LinedLiset<>();
      //添加元素,add()
      //add(E)
      list2.addAll(list1);
      //System.out.println(list1==list2);
      //System.out.println(list1.equals(list2));
      
      //System.out.println(list2.get(1));
      
      for(Integer i:list){
          System.out.println(i);
      }
      System.out.println(------------------------);
      list=list.subList(2,3);
      
      for(Integer i:list){
          System.out.println(i);
      }
      System.out.println("-------------------------");
      Integer[] is=new Integer[10];
      is=list.toArray(is);
      for(Integer i:is){
          System.out.println(i);
      }
  }

集合求交集

  public static void main(String[] args){
      list<Integer> list1=new ArrayList<>();
      list<Integer> list2=new ArrayList<>();
      
      list1.add(1);
      list1.add(2);
      list1.add(3);
      list1.add(4);
  ​
      //定义交集,先拷贝一个需要寻找交集内容的集合    
      List <Integer> intersection=(ArrayList<Integer>)list1;   
      //执行retainAll可以获取二者交集到intersecton    
      intersection.retainAll(list2);
          
      for(int i:intersection){
          System.out.println(i);
      }
  }   

集合求并集

  
  public static void main(String[] args){
      list<Integer> list1=new ArrayList<>();
      list<Integer> list2=new ArrayList<>();
      
      list1.add(1);
      list1.add(2);
      list1.add(3);
      list1.add(4);
      
      //定义交集,先拷贝一个需要寻找交集内容的集合    
      List <Integer> intersection=(ArrayList<Integer>)((ArrayLsit<Integer>)list1).clone();   
      
      //执行retainAll可以获取两者交集到intersection
      intersection.retainAll(list);
      System.out.println("交集:");
      for(int i:intersection){
           System.out.println(i);
      }
      System.out.println("-------------------------");
      
  
  //forEach方法
  public static void main(String[] args){
      List<User> list=new ArrayList<>();
      list.add(new User("123",123));
      list.add(new User("124",124));
      list.add(new User("125",125));
      list.forEach(y->x.setAge(x.gatAge()+1));
      list.forEach(b->System.out.println(b));
  }

主要!!!strat

  
  List<E> list=Arrays.asList(E...e);//将动态封装成List集合
  ArrayList arr=...;
      ArryList();
      ArrayList(int capacity);
      ArrayList(Collection<R> list);
  ​
      //删除满足参数函数条件的元素
      //arr.removeIf(Predicator<E> filter);
      //删除姓名为zl的学员
      //list.removeIf((a)->a.getName().equals("zl"));
      //删除年龄小于20岁的学员
      //list.removeIf((a)->a.getAge()<20);
  ​
  //案例
  //public static void main(String[] args){
  //    List<User> list=new ArrayList<>();
  //    list.add(new User("123",123));
  //    list.add(new User("124",124));
  //    list.add(new User("125",125));
  //    list.removeIf(abc->abc.getAge()>123);
  //    list.forEach(x->System.out.println(x));
  //}
  ​
      //修剪数组长度为元素实际数量
      arr.trimToSize();
  ​
      //是否村子重复
      //如果是,有几个重复
  ​
  LinkedList<E> list=...
      LinkedList();
      LinkedList(Collection<E> list);
      
      LinkedList:链表
      lsit.addFirst(E e);//头部追加
      list.addLast(E e);//尾部追加
      Iterator<E> it=list.decendingIterator();//逆向迭代器
      E e=list.getFirst();//提取但不删除第一个节点元素
      E e=list.getLast();//提取但不删除最后一个节点元素
      E e=list.polFirst();//提取并删除第一个节点元素
      E e=list.pollLast();//提取并删除最后一个节点元素
      
      E e=list.removeFirstOccurrence(Object obj);//删除第一个匹配节点元素
      E e=list.removeLastOccurrence(Object obj);//删除最后一个匹配节点元素
      E e=list.removeFirst();//删除第一个节点元素,空报异常
      E e=list.removeLast();//删除最后一个节点元素,空报异常
 e=list.removeLastOccurrence(Object obj);//删除最后一个匹配节点元素
      E e=list.removeFirst();//删除第一个节点元素,空报异常
      E e=list.removeLast();//删除最后一个节点元素,空报异常

主要!!!end

6、 Map方法

HashMap<K,V> map =...
      HashMap()
      HashMap(int initalCapacity)
      HashMap(Map(K,V) map)
      
  V v=map.put(K key,V value);//添加键值对
  //如果K已存在,V覆盖原有值,并将其返回,不存在返回null
  map.putAll(Map<K,V> sub);//添加子Map
  V v=map.putIfAbsent(K key,V value);//不存在key添加,否则返回value
  ​
  Set<Map.Entry<K,V>> set=map.entrySet();//提取所有键值对
  Set<K> keys=map.keySet();//提取所有键
  Collection<V> values=map.values();//提取所有值
  V v=map.get(Object key);//根据键提取值
  V v=map.getOrDefault(Object key,V defaultValue);//根据键提取值,不存在返回默认值
  ​
  int size=map.size();//互殴去键值对的数量
  map.clear();//清空
  boolean empty=map.isEmpty();//是否为空
  ​
  boolean has=map.containKey(Object key);//是否存在键
  ​
  V v=map.remove(Object key);//根据key删除,存在返回键对应的值,否则返回null
  boolean yes=map.replace(Object key,Object value);//键值都匹配返回true,否则false
  ​
  //插入不会判断,这个方法是用于值存在才替换
  boolean yes=map.replace(Object key,Object value,Object newValue);
  //该方法等同于如下代码:
  //if((map.get(key)).equals(value)){
  //    map.put(key,newValue);
  //}
  //如  果键值都存在,则替换并返回true,否则返回false
  ​
  //如果键存在,则替换并返回原值,否则返回null
  V v=map。replace(Object key,Object value);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值