集合2

作者: 半年很快 | 来源:发表于2018-06-22 20:34 被阅读0次

    LinkedList集合:
    是List的子类,能继承List所有的方法,并具有自己的方法
    LInkedList linkedList = new LinkedList();
    jdk1.6之前方法:
    //addFirst()//始终在首位添加
    //addLast()//始终在末尾添加
    //getFirst()//获取的对象不存在会发生异常---NoSuchElementException
    //getLast()
    //removeFirst()//删除的对象不存在会发生异常---NoSuchElementException
    //removeLast()

    在jdk1.6后,增加、获取、删除做了以下更新:
    //offerFirst()//在第一个位置添加
    //offerLast()//在最后一个位置添加
    LinkedList linkedList2 = new LinkedList<>();
    linkedList2.offerFirst("java1");
    linkedList2.offerFirst("java2");
    linkedList2.offerLast("java3");

        //peekFirst()//获取的对象不存在会返回null
        //peekLast()
        System.out.println(linkedList2.peekFirst());
        
        //pollFirst()//删除的对象不存在会返回null
        //pollLast()
        System.out.println(linkedList2.pollFirst());
    

    jdk1.6之前和之后主要区别是:如果集合为空,之前返回的是异常,之后返回的是null

    List:接口,有序的,可重复的
    List集合在遍历的时候,因为List是可重复的,为了得到不可重复的元素,所以就用到了contains方法,contains工作原理:当添加元素的时候,会让当前对象里的元素与集合中已有的元素一一进行比较(contains方法中调用了equals方法),过程中只要有一次比较返回true,整个contains方法就返回true,只有所有比较都返回false,contains才会返回fasle
    Iterator iterator = list.iterator();
    while (iterator.hasNext()) {
    Object object = (Object) iterator.next();
    if(!list1.contains(object)){//看list1中的元素是否有object,如果已经有,那么list1.contains(object)返回true,!list1.contains(object)返回false,所以在赋值的时候就过滤掉了重复项
    list1.add(object);//将object中的元素添加到list1中
    }
    }

    (1)如果将两个引用用equals()方法比较,默认是比较他们的地址,所以为了比较指向的内容,我们在集合的时候需要重写equals()方法,实现我们自己想要的比较方式;
    (2)字符串类型用equals比较,不用重写,因为在String类中已经重写了equals方法,直接比较的就是字符串的内容

    //重写equals()方法
    系统中默认方法形式:boolean equals(Object object)
    所以在重写时方法形式一样,如下例:
    public boolean equals(Object obj){
    if(!(obj instanceof Person)){
    throw new ClassCastException
    }
    Person person = (Person)obj;
    return age==person.age&&name.equals(person.name);//引用类型需要重写equals方法,person是Person类的引用,如果不是基本数据类型和String类型的(内部已经重写了equals方法,不用我们写),则都需要重写equals方法
    }

    Set:无序的,不可重复的
    HashSet:底层是哈希表,线程不安全的
    TreeSet:底层是二叉树,线程不安全的

    HashSet实现不重复的过程:
    原理:是通过元素内部的hashCode()和equals()方法,实现的元素的去重,首先调用的是hashCode方法,比较两个哈希值,如果不同,就认为是两个对象,不再调用equals方法,如果hashCode相同,再去调用equals方法,如果返回true就认为是一个对象,返回false就认为是两个对象

    注意点:HashSet本身不能实现排序

    实例:使用HashCode实现对Person1类对象的保存并去重
    分析:因为去重需要用到hashCode方法和equals方法,故需要重写这两个方法,也是关键点

    重写hashCode
    hashCode在系统中形式:
    int hashCode();
    重写:
    public int hashCode(){
    return name.hashCode() + age*10000;
    }

    重写equals方法,如之前重写的

    注意:在LinkedList中的重写equals方法,HashSet重写的hashCode方法和equals方法,只要记住是这么用就行,里面的逻辑系统已经写好,暂时不用去了解

    TreeSet:
    底层是二叉树,线程不安全的,可以实现去重和排序
    注意:
    (1)使用TreeSet在存储字符串的时候,自动实现了去重顺便实现了排序,下面值介绍了排序的方法,TreeSet可以自动实现去重
    (2)在add方法中调用了元素(字符串)的compareTo(Object obj)方法
    (3)作为元素的字符串实现了compareTo接口,而在接口中有compareTo()方法,通过调用方法实现元素的比较,对字符串是按照字典顺序升序排列
    //在add方法中自动调用了compareTo方法,用来排序
    TreeSet set =new TreeSet<>();
    set.add("java1");
    set.add("java3");
    set.add("java4");
    set.add("java0");
    set.add("java0");

        System.out.println(set);
    

    这里打印结果直接去重并排序了

    如果数据类型不是String类型,是我们自己创建的类的类型,怎么排序并去重,要求是实现Comparable接口的compareTo方法,比较规则是:只要年龄和姓名规则相同,就认为是一个人?
    答:在自创类中实现Comparable,然后在类中重写compareTo方法
    在系统中compareTo形式为:int compareTo(Object o)
    实现compareTo方法:
    这个方法会返回int值,类型有三种:负数、0、正数
    负数:代表当前的对象小于后面的对象
    0:代表两个对象相等
    正数:代表前面的对象大于后面的对象

    重写为:
    public int compareTo(Object o){
    if(!(o instanceof Person)){
    throw new ClassCastException("类型异常");
    }
    Person person = (Person)o;
    //先按年龄比
    int num =age-person.age;
    //年龄相同,再按照姓名比(升序字典排序)
    return num==0?name.compareTo(person.name):num
    //字符串里面已经自动重写了compareTo方法}

    TreeSet:使用实现Comparator接口的比较器对对象进行排序

    总结:对于存放在TreeSet里面的元素可以同时存在两种排序方式:
    第一种:让元素直接实现Comparable接口--系统排序
    第二种:创建实现Comparator接口的比较器--人工排序
    系统的做法是让那个第二种的优先级高于第一种,方便人工排序的执行

    比较器的创建:
    public ComWIthLength implements Comparator{
    public int compare(Object o1,Object o2){
    if(!(o1 instanceof String)){
    throw new ClassCastException();
    }
    if()...
    }
    //向下转型
    String string1 = (String)o1;
    String string2 = (String)o2;
    //将字符串按照从短到长排序,如果长度相同再按照字典排序
    int num=string1.length()-string2.length();
    return num==0?string1.compareTo(string2):num;
    }

    泛型:
    通过<数据类型>接受一种数据类型,在编译的时候会使用这种数据类型检测集合中的元素,如果不是<>中规定的类型,就不允许添加到集合中(编译不通过)
    构成:数据类型后面的<类型>里面的定义的类型就是泛型

    泛型的作用:1.使用了泛型,不需要再强制类型转化、容错处理,简化代码
    2.将运行时候的问题提前到了编译阶段检查,提高了代码的安全性,提高了代码的编写效率

    泛型的使用场景:可以在类、方法、接口上使用
    例:
    //当给ArrayList使用泛型之后进行约束,里面的元素就只能是String类型
    ArrayList<String> list new ArrayList<String>();//后面的<>里面的类型可以不写

    相关文章

      网友评论

          本文标题:集合2

          本文链接:https://www.haomeiwen.com/subject/evfueftx.html