泛型机制

泛型机制:

(1)概念

   jdk1.5版本开始使用的新特性,本质是进行"参数化类型",在类,接口,方法的定义上都可以使用,用来指定数据类型名的。

   (2)集合在定义时,可以用泛型机制来指定元素的类型,这样编译器在编译期间就可以进行检查元素类型是否匹配,避免了程序在运行时出现过多的错误 

   (3)集合框架中的所有类型(接口,抽象类,实现类)都是用了泛型机制   

   (4)泛型机制的参数只能传引用类型                

练习:自定义一个类型,练习泛型机制

定义一个类型MyContaionner:使用泛型机制,用于规定要存储的元素类型

package com.hyxy.se.day07;



import java.util.Arrays;



/*定义类型时使用泛型机制,泛型机制的本质是参数化类型

 * PS:与参数化对象/数据比较,与方法的形参比较*/

public class MyContainer<M> {

   private static final String M = null;

   Object[] values;

   public MyContainer(){

   values=new Object[16];     

   }

   /*定义方法时,使用泛型机制*/

   public void add(M m){

       for(int i=0;i<values.length;i++){

          if(values [i]==null){

              values [i]=m;

              break;

          }

       }

   }

   public M remove(Object obj){

          M m=null;

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

          if(values[i].equals(obj)){

              //存储要被移除的对象

              m=(M)values[i];//Object型强转成M类型

              System.arraycopy(values, i+1, values, i, size()-1-i);

              //values=Arrays.copyOf(values, values.length);

              values[size()-1]=null;

              break;

          }

       }

       return m;

   }

   public int size(){

       for(int i=0;i<values.length;i++){

          if(values [i]==null){

              return i;

          }

       }

       return values.length;

   }

  

   /**重写toString

    * 插入方法add(int index,M m)

    * M remove(int index)

    */

  

       public void add(int index,M m){

          //考虑扩容

          if((size()+1)>values.length){

              values=Arrays.copyOf(values, values.length+16);

          }

          System.arraycopy(values,index,values,index+1,size()-index);

          values[index]=m;

       }

  

    public M remove(int index) {  

        M m;

          if (index<0||index>size()) {

              throw new RuntimeException("下标越界");         

       }

      

       System.arraycopy(values, index+1, values, index, size()-index-1);

       values[size()-1]=null;     

       return m=(M)values;

    }

    public String toString(){

        String str="[";

        for(int i=0;i<size()-1;i++){

           str+=values[i]+",";

        }

        str+=values[size()-1]+"]";

        return str;

    }

}

第二部分

package com.hyxy.se.day07;



public class TestMyContainer {

   public static void main(String[] args) {

       MyContainer<String> my=new MyContainer<String>();

       System.out.println(my.size());

       //添加一个元素

       my.add("abc");

       System.out.println(my.size());

       my.add("hhhh");

       my.add("java");

       System.out.println(my.size());

       String e=my.remove("java");

       System.out.println(e);

       System.out.println(my.size());

       System.out.println(my);//com.hyxy.se.day07.MyContainer@15db9742  未重写

   }

}

 

List排序

Comparable接口:       

如何定义集合中元素之间的大小之分?我们需要在定义元素类型时实现Comparable接口,实现接口内的compareTo(E e)。实现此接口的类型的对象之间可以进行比较。

方法:int  compareTo(E e):

比较规则:

(1)this与e比较,this-e,按照升序排序

如果大于0,返回大于0的一个数

如果等于0, 返回0

如果小于0, 返回小于0的一个数

 (2)e-this,降序排序

工具类:Collections

提供了一个sort(Collection c)方法,对集合里的元素进行排序 

练习:定义一个类型Point,在集合List中存储五个Point对象按照到原点的距离长短进行降序排序。

   package com.hyxy.se.day07;

/*定义一个Point类型,在集合List中存储5个Point对象,按照到原点距离进行 降序排列*/

public class Point implements Comparable<Point>{

    private int x;

    private int y;

    public Point(int x,int y){

       this.x=x;

       this.y=y;

      

    }

   

    public void add(int x,int y){

      

    }

    public int getX() {

       return x;

    }

    public void setX(int x) {

       this.x = x;

    }

    public int getY() {

       return y;

    }

    public void setY(int y) {

       this.y = y;

    }

      

    @Override

    public int hashCode() {

       final int prime = 31;---定义一个素数局部变量进行初始化

       int result = 1; ---定义一个局部变量进行初始化

       result = prime * result + x;//定义一个素数prime 用新结果去乘以prime

       result = prime * result + y;

       return result;

    }



    @Override

    public boolean equals(Object obj) {

       if (this == obj)

           return true;

       if (obj == null)

           return false;

       if (getClass() != obj.getClass())

           return false;

       Point other = (Point) obj;

       if (x != other.x)

           return false;

       if (y != other.y)

           return false;

       return true;

    }



    @Override

    public String toString() {

       return "(" + x + "," + y + ")";

    }

    /*按照到原点距离的大小排序,降序排序*/

    public int compareTo(Point o){

       int dis1=x*x+y*y;

       int dis2=o.x*o.x+o.y*o.y;

       return (dis2-dis1);

    }

   

}

第二部分

package com.hyxy.se.day07;



import java.util.ArrayList;

import java.util.Collections;

import java.util.List;



public class TestPoint {

    public static void main(String[] args) {

       List<Point> list=new ArrayList<Point>();

       for(int i=0;i<5;i++){

           int x=(int)(Math.random()*10);

           int y=(int)(Math.random()*10);

           list.add(new Point(x,y));

       }

       System.out.println(list);

       Collections.sort(list);

       System.out.println(list);

    }

}

Comparator比较器接口:

如果元素类型已经实现了comparable接口,定义了默认的比较规则。之后,再想换其他比较规则时,不修改源码。可以利用比较器接口,来重新定义比较规则

方法

int compare(E o1,E o2);

比较规则

        升序: o1-o2

        降序: o2-o1

 

Set接口

特点1: 无序,存储的元素与添加顺序无关

特点2: 不可重复(使用元素的equals方法来判定是否重复)

特点3: 能存储null元素,只能存储一次。

set集合不能使用经典for循环但是可以用迭代器

Hash算法机制

Set集合在添加或查看元素时,当集合中的元素过多时,就是进行多次的比较,效率变低。

在设计元素类型时,提供hash算法,用于返回对象的一个int值。在内存中开辟很多小的区域,用于存储一定范围的返回值的对象。当我们想添加元素或查看元素,先计算此元素的返回值,然后去相应区域中查找遍历,

 --如果在这个区域没有找到对象,说明集合中可以添加这个对象。

 --如果有,然后查看两个对象的equals的返回值

 --如果为true,  不能添加 

 --如果为false, 可以添加,添加至对应的链表结构中(尽可能的避免发生)

重写HashCode方法

重写规则:尽可能的让所有的成员变量都参与运算,尽可能的避免出现hash值碰撞

注意:

重写的必要性:

 (1)如果重写了equals(), 有必要重写hashCode方法

 (2)如果equals()返回true, hashCode返回值有必要相同

 (3)如果equals()返回false,hashCode返回值不一定相同,如果返回值不同,可以提高检索的效率

反过来说:

 (1)hashCode值相同,equals方法可能不同

 (2)hashCode值不同,equals方法一定不同

Set接口派生的子类

  HashSet:通过实现hash算法的一种数据结构,无序,不重复。

  LinkedHashSet:通过实现hash算法的一种数据结构,但是通过链表来维持顺序。顺序与添加顺序一致。

  TreeSet:使用二叉树的一种数据结构,顺序与自然排序有关系。支持定制排序

猜你喜欢

转载自blog.csdn.net/qq_42721694/article/details/81915202