集合:
为什么需要集合,存储数据用数组不就行了吗?
对于对象数据据进行排序 ?
以及对重复数据进行去重 ?
以及存储对应的 Key Value 数据?
集合作为应该容器,内部提供了一些类,可以为存储在内的大批量数据提供对应的对象方法
哪些类是集合类?对应方法如何使用?
集合中的类:
1. Collection顶级父接口
/*TODO 查看顶级父接口 Collection 的方法1.add用于添加一个Object子类的元素,其中对于基本数据类型并不是 Object子类 但是可以添加(添加后会对其装箱)2.toArray3.remove4.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()方法会对基本数据类型进行自动装箱 包装成 Integercollection.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) {/* TODOcollection.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 returnint lastRet = -1; // index of last element returned; -1 if no suchint 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); // falseSystem.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 表示当前集合中存储的所有元素的类型 为 ECollection<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;}@Overridepublic 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;}@Overridepublic 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) {// 对象等于nullif (o == null) {for (int index = 0; index < size; index++)if (elementData[index] == null) {fastRemove(index);return true;}} else {// 不为nullfor (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;}@Overridepublic String toString() {return "Stu{" +"name='" + name + '\'' +", age=" + age +", clazz='" + clazz + '\'' +'}';}// TODO: 重写继承自Object类中的equals()方法,// 因为Object类中的equals()方法比较的是两个元素的存储地址,不满足我们现在实际的需要// 重写后通过比较两个对象的属性值来判断它们是否相同@Overridepublic boolean equals(Object o) {//返回 true 或 falseif (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);}@Overridepublic 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:可以创建一个类 实现该接口,并创建实现类对象传给 sortintegers.sort(new IntSort());//方式2:匿名内部类实现integers.sort(new Comparator<Integer>() {@Overridepublic 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()方法进行重写@Overridepublic 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()方法进行重写@Overridepublic int compareTo(Tea other) {/*定义两个对象的比较逻辑:1.先比较工作年限 年限相同再比较年龄*/// 年限相减结果为 0 表示相同int compareRes = this.year - other.year == 0 ? this.age - other.age : this.year - other.year;return - compareRes;}@Overridepublic String toString() {return "Tea{" +"name='" + name + '\'' +", age=" + age +", year=" + year +'}';}
}