希望各位能够留下你们美丽的赞和评论谢谢,或者有好的资源帮帮小编提升实力一起努力,奥里给!! 拒绝垃圾视频:超级好的视频,建议从头开始看:https://www.bilibili.com/video/BV16K4y1x7Gi?p=42
概念:对象的容器,定义了对多个对象进行操作的常用方法。可实现数组的功能。
(1)数组长度固定,集合长度不固定 (2)数组可以存储基本类型和引用类型,集合只能引用类型。
3.1 Collection体系及结构 3.2 Collection父接口 特点:代表一组任意类型的对象,无序、无下标、不能重复。
方法功能boolean add(E e)添加一个对象boolean addAll(Collection<? extends E> c)将指定集合中的所有元素添加到此集合void clear()从此集合中删除所有元素boolean contains(Object o)如果此集合包含指定的元素,则返回 trueboolean containsAll(Collection<?> c)如果此集合包含指定 集合中的所有元素,则返回trueboolean equals(Object o)比较此集合是否与指定集合相等int hashCode()返回此集合的哈希码值boolean isEmpty()集合为空返回 trueIterator iterator()返回此集合中的元素的迭代器default Stream parallelStream()返回可能并行的 Stream与此集合作为其来源boolean remove(Object o)从该集合中删除指定元素的单个实例boolean removeAll(Collection<?> c)删除集合中所有包含此集合的元素default boolean removeIf(Predicate<? super E> filter)删除满足给定谓词的此集合的所有元素boolean retainAll(Collection<?> c)仅保留此集合中包含在指定集合中的元素int size()返回此集合中的元素数default Spliterator spliterator()创建一个Spliterator在这个集合中的元素default Stream stream()返回以此集合作为源的顺序 StreamObject[] toArray()返回数组形式 T[] toArray(T[] a)返回包含此集合中所有元素的数组; 返回的数组的运行时类型是指定数组的运行时类型3.3 小试牛刀(增删改查)
重点:迭代器中不能用collection的方式进行remove否则会报错,但是可以用迭代器的remove。
package cn.itcast.study; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; /** * collection接口的使用 * (1)添加 * (2)删除 * (3)遍历 * (4)判断 * @author 11218 * */ public class CollectionDemo1 { public static void main(String[] args) { //创建集合 Collection collection = new ArrayList(); // * (1)添加 collection.add("苹果"); collection.add("111"); collection.add("香蕉"); System.out.println("元素个数:"+collection.size()); System.out.println(collection); // * (2)删除 // collection.remove("111"); // System.out.println("删除之后:"+collection); // * (3)遍历(重点) //1.使用增强for System.out.println("==============="); for(Object object:collection) { System.out.println(object); } //2.迭代器 //hasNext();有没有下一个元素 //next();获取下一个元素 //remove();删除当前元素 System.out.println("==============="); Iterator it = collection.iterator(); while(it.hasNext()) { String object = (String) it.next(); System.out.println(object); //不能在迭代的时候用collection.remove()的方法 } // * (4)判断 System.out.println("==============="); System.out.println(collection.contains("西瓜")); System.out.println(collection.isEmpty()); } }3.4 类的collection Student
package cn.itcast.study; //学生信息 public class Student { private String name; private int age; public Student() { // TODO Auto-generated constructor stub } public Student(String name, int age) { super(); this.name = name; this.age = age; } 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; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } }CollectionDemo2
package cn.itcast.study; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; public class CollectionDemo2 { public static void main(String[] args) { //新建collection对象 Collection collection = new ArrayList(); Student s1 = new Student("a",1); Student s2 = new Student("b",2); Student s3 = new Student("c",3); //添加到collection中 collection.add(s1); collection.add(s2); collection.add(s3); System.out.println("元素个数:"+collection.size()); System.out.println(collection.toString()); //删除 // collection.remove(s1); // System.out.println("删除后元素个数:"+collection.size()); //遍历 System.out.println("==========第一种========="); for (Object object : collection) { Student s = (Student)object; System.out.println(s.toString()); } System.out.println("==========第二种========="); Iterator iterator = collection.iterator(); while(iterator.hasNext()) { Student s = (Student) iterator.next(); System.out.println(s.toString()); } //判断 System.out.println(collection.contains(s1)); System.out.println(collection.isEmpty()); } }特点:有序、有下标、可以重复 list代码案例:
package cn.itcast.study; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; /** * List子孩子的使用 * 特点:有序、有下标、可以重复 * @author 11218 * */ public class ListDemo1 { public static void main(String[] args) { //先创建集合对象 List list = new ArrayList<>(); //添加元素 list.add("苹果"); list.add("小米"); list.add(0,"华为"); System.out.println("元素个数:"+list.size()); System.out.println(list.toString()); //删除元素 // list.remove("苹果"); // list.remove(0);//序列为0的元素删除 // System.out.println("元素个数:"+list.size()); // System.out.println(list.toString()); //3使用for遍历 System.out.println("==========第一种=========="); for(int i = 0;i<list.size();i++) { System.out.println(list.get(i)); } //使用增强for System.out.println("==========第二种=========="); for (Object object : list) { System.out.println(object); } //使用迭代器 System.out.println("==========第三种=========="); Iterator it = list.iterator(); while(it.hasNext()) { System.out.println(it.next()); } //使用列表迭代器 System.out.println("==========第四种=========="); ListIterator lit = list.listIterator(); while(lit.hasNext()) { System.out.println(lit.nextIndex()+":"+ lit.next()); } //倒序输出 ListIterator lit2 = list.listIterator(); System.out.println("==========倒序=========="); while(lit2.hasPrevious()) { System.out.println(lit2.previousIndex()+":"+ lit2.previous()); } //判断 System.out.println(list.contains("苹果")); System.out.println(list.isEmpty()); //获取位置 System.out.println(list.indexOf("华为")); } }list操作的一些小注意点: 1.在利用remove的时候默认的int参数类型为所删除的下标,而要想删除集合中包含的数字则需要利用强转换引用类型,object和Integer,例如: [20,30,40,50,60]中想要删除20则可以有 remove((Object)20)或者remove(new Integer(20)); 2.sublist切割的时候注意,包含头不包含尾,例如: [20,30,40,50,60],执行sublist(1,3) 则sublist得到的为:[30,40]
package cn.itcast.study; import java.util.ArrayList; import java.util.List; /** * list的使用 * @author 11218 * */ public class ListDemo2 { public static void main(String[] args) { //创建集合 List list = new ArrayList(); //添加数字数据(自动装箱) list.add(20); list.add(30); list.add(40); list.add(50); list.add(60); System.out.println("元素个数:"+list.size()); System.out.println(list.toString()); //删除 /** * remove默认是下表 * 如果要删除必须remove((Object)20)或者remove(new Integer(20)); */ // list.remove(new Integer(20)); // System.out.println("元素个数:"+list.size()); // System.out.println(list.toString()); //subList,返回了集合,含头不含尾 List sublist = list.subList(1, 3); System.out.println(sublist.toString()); } }特点: 数组结构实现,查询快,增删慢。
ArrayList是list集合下面有序的实例类,实现了增删改查等功能。 重点:ArrayList里面的remove,indexOf,contains等方法中有equals方法的影响,要想实现new出的新的对象与原来的相不相等那么源代码中的equals就不饿能够很好的识别,因为源代码中的equals继承自Object类的equals,比较的是两个object的地址是否相同与本意相悖,此时就需要重写equals方法,实现ArrayList的删除、查找、包含。
示例代码: Student类中重写equals方法
@Override public boolean equals(Object obj) { //判断是不是同一个对象 if(this==obj) { return false; } //判断对象是不是为空 if(obj==null) { return false; } //判断是不是Student类型 if(obj instanceof Student) { Student s= (Student)obj; //比较属性 if(this.name.equals(s.getName()) && this.age==s.getAge()) return true; } //不满足条件返回false return false; }ArrayListDemo1
package cn.itcast.study; import java.util.ArrayList; import java.util.Iterator; import java.util.ListIterator; public class ArrayListDemo1 { public static void main(String[] args) { //创建集合 ArrayList arrayList = new ArrayList<>(); //添加元素 Student s1 = new Student("刘德华",20); Student s2 = new Student("gcd",25); Student s3 = new Student("wcw",21); //遍历元素 arrayList.add(s1); arrayList.add(s2); arrayList.add(s3); //遍历元素 System.out.println("==========for循环========="); for(int i = 0;i<arrayList.size();i++) { System.out.println(arrayList.get(i)); } System.out.println("==========增强for循环========="); for (Object object : arrayList) { System.out.println(object); } System.out.println("==========迭代器========="); Iterator it = arrayList.iterator(); while(it.hasNext()) { System.out.println(it.next()); } System.out.println("==========列表迭代========="); ListIterator list = arrayList.listIterator(); while(list.hasNext()) { System.out.println(list.next()); } //删除 arrayList.remove(new Student("刘德华",20));//继承object的remove;equals(this==object) System.out.println(arrayList.toString()); //判断 System.out.println(arrayList.isEmpty()); Student s = new Student("刘德华",20); s=s1; System.out.println(arrayList.contains(s)); //查找 System.out.println(arrayList.indexOf(new Student("gcd",25))); } }ArrayList核心源码分析:
关键词名名词解释DEFAULT_CAPACITY默认容量 (10)DEFAULTCAPACITY_EMPTY_ELEMENTDATA默认空的元素数组容量(0)elementData存放元素的数组size实际元素个数add()元素添加源码摘取:(建议从上至下待数走一遍)
public boolean add(E e) { ensureCapacityInternal(size + 1); // 确保内部容量 elementData[size++] = e; return true; } private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//判断集合数组容量与默认空元素数组容量 minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);//赋予最小容量10 } ensureExplicitCapacity(minCapacity); } private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity);//组合序列化 }特点: 数组结构实现,查询快,增删慢(几乎不用了)
代码实现:
package cn.itcast.study; import java.util.Enumeration; import java.util.Vector; /** * vector集合使用 * 存储结构:数组 * @author 11218 * */ public class VectorDemo1 { public static void main(String[] args) { //创建集合 Vector vector = new Vector(); //添加 vector.add("草莓"); vector.add("西瓜"); System.out.println("元素个数:"+vector.size()); //删除 // vector.remove(0); // vector.remove("西瓜"); //遍历 //使用枚举器 Enumeration en= vector.elements(); while (en.hasMoreElements()) { Object object = (Object) en.nextElement(); System.out.println(object); } } }**特点:**链表结构实现,增删快,查询慢。 示例代码:
package cn.itcast.study; import java.util.Iterator; import java.util.LinkedList; import java.util.ListIterator; /** * linkedList的使用 * 存储结构:双向链表 * @author 11218 * */ public class LinkedListDemo1 { public static void main(String[] args) { //创建集合 LinkedList linkedList = new LinkedList<>(); //添加元素 Student s1 = new Student("刘德华",20); Student s2 = new Student("gcd",25); Student s3 = new Student("wcw",21); linkedList.add(s1); linkedList.add(s2); linkedList.add(s3); System.out.println("元素个数:"+linkedList.size()); System.out.println(linkedList.toString()); // //删除 // linkedList.remove(s1); // System.out.println("删除之后:"+linkedList.size()); //遍历 System.out.println("==========for遍历============"); for(int i = 0;i<linkedList.size();i++) { System.out.println(linkedList.get(i)); } System.out.println("==========增强for遍历============"); for (Object object : linkedList) { System.out.println(object); } System.out.println("==========迭代遍历============"); Iterator it = linkedList.iterator(); while(it.hasNext()) { System.out.println(it.next()); } System.out.println("==========列表迭代遍历============"); ListIterator lit = linkedList.listIterator(); while(lit.hasNext()) { System.out.println(lit.next()); } //判断 System.out.println(linkedList.contains(s1)); System.out.println(linkedList.isEmpty()); //获取 System.out.println(linkedList.get(0)); System.out.println(linkedList.indexOf(s1)); } }核心源码分析:(小编力推自己先带着初始化去看然后带着加一个元素去看,能够很快理解源码)
关键词名名词解释size集合长度 (初始为0)Node first头节点Node last尾节点add()添加元素linkedLast()元素源码摘取:
public boolean add(E e) { linkLast(e); return true; } void linkLast(E e) { final Node<E> l = last; final Node<E> newNode = new Node<>(l, e, null); last = newNode; if (l == null) first = newNode; else l.next = newNode; size++; modCount++; }特点:无序、无下标、元素不可重复。 方法:全部继承于collection。
与集合collection的方法使用一样。
示例代码:
package cn.itcast.study; import java.util.HashSet; import java.util.Iterator; import java.util.Set; /** * set接口的使用 * 特点:无序、没有下标、不能重复 * @author 11218 * */ public class SetDemo1 { public static void main(String[] args) { //创建集合 Set<String> set = new HashSet<>(); //添加数据 set.add("苹果"); set.add("小米"); set.add("华为"); System.out.println("数据个数:" + set.size()); System.out.println(set.toString()); //删除 set.remove("小米"); System.out.println(set.toString()); //遍历(重点) System.out.println("===========使用增强for=========="); for (String string : set) { System.out.println(string); } System.out.println("===========使用迭代器=========="); Iterator it = set.iterator(); while(it.hasNext()) { System.out.println(it.next()); } //判断 System.out.println(set.contains("华为")); System.out.println(set.isEmpty()); } }重点: 1.基于HashCode计算元素存放位置。 2.当存入元素的哈希码相同时,会调用equals进行确认,如果结果为true,则拒绝存入。
HashSet需要了解HashSet的工作流程, (1)根据Hashcode计算存储位置,如果此位置为空,则直接保存,如果不为空则执行第二步 (2)在执行equals方法,如果equals方法为true,则为重复,否则形成列表。 问题: (1)对于原来hashcode编码可能会导致new的对象与集合的元素,hashcode计算的位置不同导致不能排重。 (2)对于原来equals方法是对于地址的比较无法正确比较内容,导致无法排重。 解决方案: 改写hashcode和equals
示例代码: Person
package cn.itcast.study; /** * 人类 * @author 11218 * */ public class Person { private String name; private int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } 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; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } //改写hashCode @Override public int hashCode() { int n1 = this.name.hashCode(); int n2 = this.age; return n1+n2; } //改写equals @Override public boolean equals(Object obj) { if(this==obj) { return true; } if(obj==null) { return false; } if(obj instanceof Person) { Person p = (Person) obj; if(this.name.equals(p.getName()) && this.age == p.getAge()) { return true; } } return false; } }HashSetDemo2
package cn.itcast.study; import java.util.HashSet; import java.util.Iterator; /** * HashSet的使用 * 存储结构(数组+链表+红黑树) * (1)根据Hashcode计算存储位置,如果此位置为空,则直接保存,如果不为空则执行第二步 * (2)在执行equals方法,如果equals方法为true,则为重复,否则形成列表。 * @author 11218 * */ public class HashSetDemo2 { public static void main(String[] args) { HashSet<Person> hashSet = new HashSet<>(); //添加数据 Person p1 = new Person("刘德华",20); Person p2 = new Person("abc",22); Person p3 = new Person("xcg",21); hashSet.add(p1); hashSet.add(p2); hashSet.add(p3); hashSet.add(new Person("刘德华",20)); System.out.println("元素个数:"+hashSet.size()); System.out.println(hashSet.toString()); //删除操作 // hashSet.remove(p1); // System.out.println(hashSet.remove(new Person("刘德华",20))); // System.out.println("元素个数:"+hashSet.size()); // 遍历 System.out.println("==========增强for========="); for (Person person : hashSet) { System.out.println(person.toString()); } //迭代器 System.out.println("==========迭代器========="); Iterator it = hashSet.iterator(); while(it.hasNext()) { Person p = (Person) it.next(); System.out.println(p.toString()); } //判断 System.out.println(hashSet.isEmpty()); System.out.println(hashSet.contains(new Person("刘德华",20))); } }其中对于hashCode的改写,jdk自带的补充
@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; }(1)31是质数,减少散列的原因。(位置尽量不一样) (2)31提高执行效率 31*i=(i<<5)-i
重点: 1.基于排列顺序实现元素不重复。 2.实现了SortedSet接口,对集合元素自动排序。 3.元素对象的类型必须实现Comparable接口,指定排序规则。 4.通过CompareTo方法确定是否为重复元素。
补充知识点(红黑树简单概念): 先了解二叉查找树(图解): 红黑树在其基础上增加红黑色,使其平衡查找。
示例代码:
package cn.itcast.study; import java.util.Iterator; import java.util.TreeSet; /** * TreeSet的使用 * 存储结构:红黑树 * @author 11218 * */ public class TreeSetDemo1 { public static void main(String[] args) { //创建集合 TreeSet<String> treeSet = new TreeSet<>(); //添加 treeSet.add("acb"); treeSet.add("xzh"); treeSet.add("def"); System.out.println("元素个数"+treeSet.size()); System.out.println(treeSet.toString()); //删除 // treeSet.remove("a"); // System.out.println("元素个数:"+treeSet.size()); // System.out.println(treeSet.toString()); //遍历 System.out.println("==========增强for==========="); for (String string : treeSet) { System.out.println(string); } System.out.println("==========迭代==========="); Iterator it=treeSet.iterator(); while(it.hasNext()) { System.out.println(it.next()); } //判断 System.out.println(treeSet.isEmpty()); System.out.println(treeSet.contains("acb")); } }要求: TreeSet泛型元素要实现comparable接口,compareTo()方法返回值为0,认为重复元素。 TreeSet可以通过Comparator接口直接对泛型制定比较。
第一种对元素comparable接口的实现
Person
package cn.itcast.study; /** * 人类 * @author 11218 * */ public class Person implements Comparable<Person>{ private String name; private int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } 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; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Person other = (Person) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } //先姓名后年龄 @Override public int compareTo(Person o) { int n1=this.getName().compareTo(o.getName()); int n2=this.age-o.getAge(); return n1==0?n2:n1; } }TreeSetDemo2
package cn.itcast.study; import java.util.Iterator; import java.util.TreeSet; /** * TreeSet保存数据 * 存储结构:红黑树 * 要求:元素必须要实现comparable接口,compareTo()方法返回值为0,认为重复元素 * @author 11218 * */ public class TreeSetDemo2 { public static void main(String[] args) { //创建集合 TreeSet<Person> person = new TreeSet<>(); //添加元素 Person p1 = new Person("xckhskfh",20); Person p2 = new Person("sdxhu",22); Person p3 = new Person("xcg",21); Person p4 = new Person("xcg",20); person.add(p1); person.add(p2); person.add(p3); person.add(p4); System.out.println("元素个数:"+person.size()); System.out.println(person.toString()); //删除 person.remove(new Person("xcg",21)); System.out.println(person.size()); //遍历 System.out.println("===========增强for============"); for (Person person2 : person) { System.out.println(person2); } System.out.println("===========迭代器==========="); Iterator it = person.iterator(); while(it.hasNext()) { Person p = (Person)it.next(); System.out.println(p.toString()); } //判断 System.out.println(person.isEmpty()); System.out.println(person.contains(new Person("xcg",20))); } }第二种利用comparator直接对泛型制定比较
package cn.itcast.study; import java.util.Comparator; import java.util.TreeSet; public class TreeSetDemo3 { public static void main(String[] args) { //创建集合,并制定比较规则 TreeSet<Person> person=new TreeSet<>(new Comparator<Person>() { @Override public int compare(Person o1, Person o2) { int n1=o1.getAge()-o2.getAge(); int n2=o1.getName().compareTo(o2.getName()); return n1==0?n2:n1; } }); //添加元素 Person p1 = new Person("xckhskfh",20); Person p2 = new Person("sdxhu",22); Person p3 = new Person("xcg",21); Person p4 = new Person("xcg",20); person.add(p1); person.add(p2); person.add(p3); person.add(p4); System.out.println("元素个数:"+person.size()); System.out.println(person.toString()); } }TreseSet案例
要求:使用TreeSet集合实现字符串按照长度进行排序,长度一样按照字母序列排序
代码示例:
package cn.itcast.study; import java.util.Comparator; import java.util.TreeSet; public class TreeSetDemo3 { public static void main(String[] args) { //创建集合,并制定比较规则 TreeSet<Person> person=new TreeSet<>(new Comparator<Person>() { @Override public int compare(Person o1, Person o2) { int n1=o1.getAge()-o2.getAge(); int n2=o1.getName().compareTo(o2.getName()); return n1==0?n2:n1; } }); //添加元素 Person p1 = new Person("xckhskfh",20); Person p2 = new Person("sdxhu",22); Person p3 = new Person("xcg",21); Person p4 = new Person("xcg",20); person.add(p1); person.add(p2); person.add(p3); person.add(p4); System.out.println("元素个数:"+person.size()); System.out.println(person.toString()); } }