关注

Java学习之集合1

集合:

为什么需要集合,存储数据用数组不就行了吗?

对于对象数据据进行排序 ?
以及对重复数据进行去重 ?
以及存储对应的 Key Value 数据?

集合作为应该容器,内部提供了一些类,可以为存储在内的大批量数据提供对应的对象方法

哪些类是集合类?对应方法如何使用?

集合中的类:

1. Collection顶级父接口

        /*
            TODO 查看顶级父接口 Collection 的方法
                1.add
                    用于添加一个Object子类的元素,其中对于基本数据类型并不是 Object子类 但是可以添加(添加后会对其装箱)
                2.toArray
                3.remove
                4.clear

			补:
                <>:表示泛型,用于限制当前集合存储数据的类型,暂时可以不用给定
                对于数据相关的类,一般先做增删改查,之后再看其特殊方法
                对于Collection并没有提供针对单个元素的获取以及修改方法?
                    对于不同的子实现类,其特性不一样  比如 List 和 Set 来说  List有序,Set是无序
                        那么Set不能通过其下标去取数据,Collection 仅仅是一个接口,具体实现要看其子实现对象
         */

        // 由于Collection为接口无法实例化对象,
        // 而ArrayList为实现该接口的实体类。由于Java中的多态思想:父类的引用指向子类实例。
        // 因此,可以这样来实例化对象,用其调用方法。
        Collection collection = new ArrayList();
        collection.add("1");
        collection.add(1);
        collection.add(true);
        int i = 2;
        
        // add()方法会对基本数据类型进行自动装箱 包装成 Integer
        collection.add(i);  
        System.out.println(collection);

        /*
            collection 提供的iterator()方法可以获取其数据
         */
        collection.iterator();
//        toArray() 将数据转换成一个数组,因此转换后可以对其进行数组的操作
        System.out.println(collection.toArray()[0]);
        for (Object o : collection) {
            System.out.println(o);
        }

        /*
            删除数据
         */
        collection.remove(true);
        System.out.println(collection);
        collection.clear();
        System.out.println(collection);

2.迭代器

/*
    TODO 通过Collection获取其迭代器
             迭代器是用于遍历数据的一种容器  迭代器维护了一个指针,其指针一开始位置在集合之前
         其提供的方法:
            hasNext:查看当前位置是否存在数据
            next: 获取下一个位置的数据  将当前指针移动下一个,然后返回当前指针指向的数据
 */
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class DemoIterator {
    public static void main(String[] args) {
    /* TODO
            collection.iterator() 方法的调用
            对于ArrayList中iterator方法返回了一个Itr对象
                new Itr();
            // Itr类为ArrayList的成员内部类 并且是属于私有的 private 私有的只能在当前 ArrayList类中使用
            //  所以可以 new一个对象  并且实现了 Iterator 接口
            private class Itr implements Iterator<E> {
                // cursor 游标; 指针
                int cursor;       // index of next element to return
                int lastRet = -1; // index of last element returned; -1 if no such
                int expectedModCount = modCount;
                public boolean hasNext() {
                    return cursor != size;
                }
                @SuppressWarnings("unchecked")
                public E next() {
                    checkForComodification();  //
                    int i = cursor;
                    if (i >= size)
                        throw new NoSuchElementException();
                    // Object数组
                    Object[] elementData = ArrayList.this.elementData;
                    if (i >= elementData.length)
                        throw new ConcurrentModificationException();
                        // 对游标进行移动1位
                    cursor = i + 1;
                    // 获取当前i的下标数据
                    return (E) elementData[lastRet = i];
                }
            }
         */
        Collection collection = new ArrayList();
        Iterator iterator = collection.iterator(); // iterator => Collection 是抽象的

        int i = 1;
        Integer integer = i;
        //integer1指向创建的对象的地址
        Integer integer1 = new Integer(i);
        // TODO 
        //      Integer valueOf(int i):返回一个表示指定的 int 值的 Integer 实例。
        //      Integer valueOf(String s):返回保存指定的 String 的值的 Integer 对象。
        //      Integer valueOf(String s, int radix):
        //      返回一个 Integer 对象,该对象中保存了用第二个参数提供的基数进行解析时从指定的 String 中提取的值。
        Integer integer2 = Integer.valueOf(i);
        System.out.println(integer == integer1); // false
        System.out.println(integer == integer2); // true



    }
}

3. Collection实现实例

import java.util.ArrayList;
import java.util.Collection;

public class StudentCollection {
    public static void main(String[] args) {
        Collection arrayList = new ArrayList();
        arrayList.add(new Student("陆玉龙", 18, "bigdata30"));
        arrayList.add(new Student("汪雨", 19, "bigdata30"));
        arrayList.add(new Teacher("杨德广", 28, "bigdata30"));

        for (Object o : arrayList) {
            // com.shujia.day08.Student cannot be cast to com.shujia.day08.Teacher
            // 测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型,是则返回True。
            if (o instanceof Teacher) {
                //若不对集合添加泛型,默认传入的对象是Object类型对象,o为Object类型对象,要将其进行强制类型转换
                Teacher o1 = (Teacher) o;
                System.out.println(o1);// Student{name='陆玉龙', age=18, clazz='bigdata30'}
                o1.teach();
            } else if (o instanceof Student) {
                Student o1 = (Student) o;
                System.out.println(o1);
                o1.learn();
            }else {
                System.out.println(o);
            }
        }

        /*
            对于上述的调用过程,有时会出现类型转换问题,那么如何解决?
                1.获取对象对其进行判断是否为某个类的对象或子类对象 如果是那么进行强制类型转换 再进行调用
                2.由于Java是强类型语言,对于一个集合一般情况下,都只存储一种类型的数据
                        为了对其进行限制,提供了泛型方式
         */
        // class ArrayList<E> => 其中<E> 表示泛型类型,给定的类型需要继承Object 引用类型
        //    E 表示当前集合中存储的所有元素的类型 为 E
        Collection<Student> students = new ArrayList<>();
        students.add(new Student("汪雨", 19, "bigdata30"));
        students.add(new Student("许康杰", 29, "bigdata30"));
        //TODO 报错:泛型确定了集合中数据的类型 students.add(new Teacher("许康杰", 29, "bigdata30"));
        System.out.println(students);
        // 对于取到的每个元素的类型就可以确定
        for (Student student : students) {
            System.out.println(student);
            student.learn();
        }

//        Collection<int> ints = new ArrayList<>();
        Collection<Integer> ints = new ArrayList<>(); // 对于基本数据类型需要使用其包装类

        // 对于泛型E 满足多态 => 父类引用指向子类对象
        Collection<Person> peoples = new ArrayList<>();
        peoples.add(new Student("汪雨", 19, "bigdata30"));
        System.out.println(peoples);
//        for (Person people : peoples) {
//
//        }



    }
}

class Teacher {
    String name;
    int age;
    String clazz;

    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 String getClazz() {
        return clazz;
    }

    public void setClazz(String clazz) {
        this.clazz = clazz;
    }

    public Teacher(String name, int age, String clazz) {
        this.name = name;
        this.age = age;
        this.clazz = clazz;
    }

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

    public void teach() {
        System.out.println(name + "老师" + "正在教授大数据..");
    }
}

class Person{

}

class Student extends Person{
    String name;
    int age;
    String clazz;

    public Student(String name, int age, String clazz) {
        this.name = name;
        this.age = age;
        this.clazz = clazz;
    }

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

    public void learn() {
        System.out.println(name+"同学正在学习Java");
    }
}

4.继承自Collection接口的List接口

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class DemoList {
    public static void main(String[] args) {
        /*
            TODO List 接口的用法
                 有序集合(也称为序列 )。 用户可以精确控制列表中每个元素的插入位置。
                        用户可以通过整数索引(列表中的位置)访问元素,并搜索列表中的元素。
                 通过下标的方式来维护存储的数据位置
         */
        List<Integer> integers = new ArrayList<>();
        // 对于集合Collection不能指定获取单个元素,但是由于List接口其特性已经确定,所以可以获取
        integers.add(3);
        integers.add(5);
        integers.add(6);
        integers.add(2);
        integers.add(1);
        integers.add(7);
        integers.add(8);
        integers.add(4);
        integers.add(9);

        System.out.println(integers.get(0)); // 1
//        System.out.println(integers[1]); // 1 => []获取数据只能通过数组
        System.out.println(integers.indexOf(4)); // 获取元素所在的下标位置
        integers.remove(1);
        System.out.println(integers);

        // set要求传入下标和元素
        integers.set(1,5);
        System.out.println(integers);


        // 遍历数据
        //方法一
        for (Integer integer : integers) {
            System.out.println("elem:"+integer);
        }
        
        //方法二
        for (int i = 0; i < integers.size(); i++) {
            System.out.println("index elem:"+integers.get(i));
        }

        /*
            TODO List集合迭代器:
                 hasPrevious:查看指针上一个有没有数据
                 previous:将指针进行上移,并获取其中的数据
                 hasNext:查看当前位置是否存在数据
                 next: 获取下一个位置的数据  将当前指针移动下一个,然后返回当前指针指向的数据
         */
        ListIterator<Integer> integerListIterator = integers.listIterator();
        while (integerListIterator.hasNext()){
            System.out.println(integerListIterator.next());
        }

        while (integerListIterator.hasPrevious()){
            System.out.println(integerListIterator.previous());
        }



    }
}

5. List中Remove方法

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class ListRemove {
    public static void main(String[] args) {
        /*
            对于自定义类使用List中的方法
         */
        List<Stu> stus = new ArrayList<>();
        Stu stu = new Stu("陆玉龙", 18, "bigdata30");
        stus.add(stu);
        stus.add(new Stu("徐玉娟",18,"bigdata30"));

        /*
            TODO remove的源码:
            public boolean remove(Object o) {
                // 对象等于null
                if (o == null) {
                    for (int index = 0; index < size; index++)
                        if (elementData[index] == null) {
                            fastRemove(index);
                            return true;
                        }
                } else {
                    // 不为null
                    for (int index = 0; index < size; index++)
                        // 遍历 elementData中所有的数据 并使用equals方法对其进行比较
                        //TODO 由于当前Stu没有重写equals方法,所以使用的是Object中继承的 默认使用 == 判断
                        if (o.equals(elementData[index])) {
                            fastRemove(index);
                            return true;
                        }
                }
                return false;
            }
         */

        //TODO 由于重写了equals()方法,导致进行remove(stu)时判断前两个添加的元素都符合条件,
        //     因此将它们都给删除了
        stus.remove(stu);
        stus.remove(new Stu("徐玉娟",18,"bigdata30"));
        System.out.println(stus);

    }
}
class Stu{
    String name;
    int age;
    String clazz;

    public Stu(String name, int age, String clazz) {
        this.name = name;
        this.age = age;
        this.clazz = clazz;
    }

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

    // TODO: 重写继承自Object类中的equals()方法,
    //     因为Object类中的equals()方法比较的是两个元素的存储地址,不满足我们现在实际的需要
    //     重写后通过比较两个对象的属性值来判断它们是否相同
    @Override
    public boolean equals(Object o) {
        //返回 true 或 false
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Stu stu = (Stu) o;
        return age == stu.age && Objects.equals(name, stu.name) && Objects.equals(clazz, stu.clazz);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, clazz);
    }
}

6. List中Sort方法与Arrays中Sort方法的使用

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

public class ListSort {
    public static void main(String[] args) {
        /*
            TODO 排序操作:
                1. List中的排序,可以使用 List对象的sort方法
                            需要传入一个  Comparator 实例对象 要实现其 compare 方法  第一个值减去第二个值就是升序 否则就是降序
                        或者对于基本数据类型包装类 传入 null 即可
                2.Arrays对自定义类数组的排序
                Arrays类位于 java.util 包中,主要包含了操作数组的各种方法。
                        需要对自定义类实现 Comparable 接口,并实现其 compareTo方法
                            当前对象减去传入的对象 就是升序 反之降序
         */
        List<Integer> integers = new ArrayList<>();
        integers.add(3);
        integers.add(5);
        integers.add(6);
        integers.add(2);
        integers.add(1);
        integers.add(7);
        integers.add(8);
        integers.add(4);
        integers.add(9);

        /*
            sort方法需要传入 Comparator<? super E> c 参数
                排序需要给定规则,规则是由 Comparator 的实现对象决定的
                而 interface Comparator<T>  为一个接口  => 不能构建具体的对象
                    方式1:可以创建一个类 实现该接口,并创建实现类对象传给 sort
                    方式2:匿名内部类实现
                    方式3:对于基本类型数据的包装类,做排序时,可以直接传入null值
         */

//      方式1:可以创建一个类 实现该接口,并创建实现类对象传给 sort
        integers.sort(new IntSort());

        //方式2:匿名内部类实现
        integers.sort(new Comparator<Integer>() {
            @Override
            public int compare(Integer thisObj, Integer otherObj) {
                return -(thisObj - otherObj);
            }
        });

//      方式3:对于基本类型数据的包装类,做排序时,可以直接传入null值
        integers.sort(null);

        System.out.println(integers);


        String[] allStr = new String[3];
        allStr[0] = "10";
        allStr[1] = "8";
        allStr[2] = "1";

        Arrays.sort(allStr);
        // Arrays.sort() 底层代码默认是按照字典顺序比较
        System.out.println(Arrays.toString(allStr));


       //区别与 Tea tees1 = new Tea(); 写法,以数组形式呈现
        Tea[] teas = new Tea[3];
        teas[0] =  new Tea("张三",19,3);
        teas[1] =  new Tea("李四",19,4);
        teas[2] =  new Tea("王五",21,4);
        /*
            java.lang.ClassCastException: com.shujia.day08.Tea cannot be cast to java.lang.Comparable
            类型转换错误 => 给定的是自定义对象, Arrays并不知道具体的排序方式
            现在底层代码是将 每个Tea对象强制类型 转换成 Comparable 对象 并调用其 compareTo 方法 ,默认使用字典排序
                现在 interface Comparable 是一个接口 实现其 compareTo
         */
        Arrays.sort(teas);
        System.out.println(Arrays.toString(teas));

    }
}

// TODO Comparator<T> 其中T表示要比较的数据类型
//  Comparator<T> 与 Comparable<T> 的区别???
class IntSort implements Comparator<Integer>{

    //不符合实现情况中的判断逻辑,因此对compare()方法进行重写
    @Override
    public int compare(Integer thisObj, Integer otherObj) {
        /*
            thisObj - otherObj 是自然升序的方式进行排序
         */
        return -(thisObj - otherObj); //是自然降序的方式进行排序
    }
}

class Tea implements Comparable<Tea>{
    String name;
    int age;
    int year;

    public Tea(String name, int age, int year) {
        this.name = name;
        this.age = age;
        this.year = year;
    }

    //不符合实现情况中的判断逻辑,compareTo()方法进行重写
    @Override
    public int compareTo(Tea other) {
        /*
            定义两个对象的比较逻辑:
                 1.先比较工作年限 年限相同再比较年龄
         */
        // 年限相减结果为 0 表示相同
        int compareRes = this.year - other.year == 0 ? this.age - other.age : this.year - other.year;
        return - compareRes;
    }

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

转载自CSDN-专业IT技术社区

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/m0_58050808/article/details/138474912

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--