Java进阶 -- Set集合和泛型

HashSet和TreeSet集合

  • Set单列集合接口特征:
  1. 无序:存和取的顺序不一定一致。
  2. 不可以存储重复元素
  3. 没有索引,不能使用fori遍历,只能使用增强for循环遍历。
    hash值的作用:默认前情况下用来表示对象在内存中的地址,一般情况下不同的对象hash值是不一样的,所以我们常说地址值不一样。除非重写了hashCode()方法hash值才可能一。
  • HashSet集合

    1. 特点:
      底层使用哈希表结构(数组中存放链表)。
      Set集合中元素唯一的条件.
  • LinkedHasSet集合
    底层原理:哈希表+链表
    链表保证集合元素有序,是指元素的存取有序
    哈希表保证集合元素唯一

  • TreeSet集合
    特点:元素有序,不是指元素在存取过程中有序,是指元素在存入集合中,会进行排序,有一定的顺序。
    排序的条件:条件二选一
    1、TreeSet集合中的元素实现Comparable自然排序的接口,定义排序规则。
    2、元素不需要实现Comparable接口,但是在创建TreeSet集合对象的时候传递一个Comparator比较器对象

  • Comparable和Comparator区别?
    Comparable自然排序的接口,需要元素对象去实现这个接口。
    Comparator比较器接口,给TreeSet对象使用。

集合类型特点
共同点无序、不能存储重复着、没有索引。
HashSet底层是哈希表结构。元素唯一的条件:元素要重写hashCode()方法和equals()方法。
LinkedHashSet底层是链表+哈希表结构 。元素有序:存和取的顺序一致。元素唯一的条件:元素要重写hashCode()方法和equals()方法。
TreeSet元素默认自然排序

泛型

概念:将固定的数据类型参数化,也叫做参数化类型。
好处:
1、将运行期的异常提前到了编译器,保证存储的数据的正确性。
2、避免了强制类型转换。

  • 泛型的分类:
    泛型类:
    第一步:在类名后面定义泛型,那么这个类的任何地方都可以使用泛型。
public class GenericClass<T> {
         //data只能保存String类型的数据
          //private String data;
          /*
              需求:需要data能保存任意类型的数据
           */
          private T data;

          public T getData() {
              return data;
          }

          public void setData(T data) {
              this.data = data;
          }
      }

第二步:在创建对象的时候确定泛型

public static void main(String[] args) {
     //创建GenericClass对象,并确定泛型
      GenericClass<String> gc1 = new GenericClass<>();
      gc1.setData("java");
      System.out.println(gc1.getData());

      //存储Student类型
      GenericClass<Student> gc2 = new GenericClass<>();
      gc2.setData(new Student("真皮沙发", 22));
      System.out.println(gc2.getData());
  }
  • 泛型接口:
    第一步:在接口名后面定义泛型,接口中的任何地方都可以使用泛型
 public interface GenericInterface<T>{
      //在抽象方法中使用泛型
         public T method(T t);
     }

第二步:为接口定义实现类,和泛型类的定义一样

 public class GenericInterfaceImpl<T> implements GenericInterface<T>{
    public T method(T t){

       }
   }

第三步:创建实现类对象的时候确定泛型
GenericInterface<String> gif=new GenericInterfaceImpl<String>();

  • 泛型方法:
    第一步:在方法的的修饰符后面定义泛型,在方法的任意位置(返回值、参数列表,方法体中)都可以使用泛型。
 public class GenericMethod {
    //定义一个泛型方法
        public static <E> E show(E e){
            //判断e是否是String类型
            if(e instanceof String){
                String s= (String) e;
                s="hello "+s;
                return (E) s;
            }
            return e;
        }
    }

第二步:在调用方法的时候通过传递的参数值确定泛型的类型

 public static void main(String[] args) {
      //创建对象
       GenericMethod gm=new GenericMethod();
       //调用show方法
       String s = gm.show("java");
       System.out.println(s);

       Student stu = gm.show(new Student("zhangsan", 20));
       System.out.println(stu);
   }
  • 通配符泛型:<?>表示泛型的父类,一般应用在方法参数列表中
 public class GenericTest {
         public static void main(String[] args) {
             //创建集合对象
             List<Number> list1=new ArrayList<Number>();
             //调用method方法
             method(list1);

             //创建集合对象
             /*List<Integer> list2=new ArrayList<Integer>();
             //调用method方法
             method(list2);*/


             //创建集合对象
             List<Object> list3=new ArrayList<Object>();
             //调用method方法
             method(list3);
         }
/*
        Number和Integer是子父类关系,但是装有Number的list集合和装有Integer的list集合不是子父类关系

        List<? extends Number>:定义通配符?的上限,最大类型只能是Number类型,所以传递List<Object>报错
        List<? super Number>:定义通配符?的下限,最小类型只能是Number类型,所以传递List<Integer>报错
     */
    /*public static void method(List<? extends Number> list){
        System.out.println(list);
    }*/
    public static void method(List<? super Number> list){
        System.out.println(list);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值