集合进阶
1.1集合类的特点:提供一种存储空间可变的存储模型,存储的数据容量可以随时发生改变
1.2集合类体系结构
1.3 Collection的集合概念和使用
Collection集合概述
是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素
JDK不提供此接口的任何直接实现,它提供更具体的子接口(如Set和List)实现
创建Collection集合的对象
多态的方式
具体的实现类ArrayList
package chapter;
import java.util.ArrayList;
import java.util.Collection;
//创建collection集合的对象 多态的方式 ArrayList()
public class CollectionDemo01 {
public static void main(String [] args){
//创建
Collection<String> c=new ArrayList<String>();
//添加元素,boolean add(E e)
c.add("hello");
c.add("world");
c.add("java");
//输出集合对象
System.out.println(c);
}
}
[hello, world,java]
1.4 Collection集合常用方法
package chapter;
import java.util.ArrayList;
import java.util.Collection;
//创建collection集合的对象 多态的方式 ArrayList()
public class CollectionDemo01 {
public static void main(String [] args){
//创建
Collection<String> c=new ArrayList<String>();
//添加元素,boolean add(E e)
// System.out.println(c.add("hello"));
// System.out.println(c.add("world"));
// System.out.println(c.add("world"));
//add 返回永远都是true
c.add("hello");
c.add("world");
c.add("java");
//boolean remove(Object o):从集合中移除指定的元素
//System.out.println(c.remove("world"));
//void clear();清空所有元素
//c.clear();
//boolean contains(Object o):判断集合中是否存在指定的元素
// System.out.println(c.contains("world"));
//boolean isEmpty();判断集合是否为空
System.out.println(c.isEmpty());
System.out.println(c.size());
//输出集合对象
System.out.println(c);
}
}
1.5 Collection集合的遍历
Iterator:迭代器,集合的专用遍历方式
Iterator<E> iterator(): 返回此集合中元素的迭代器,通过集合的iterator()方法得到
迭代器是通过集合的iterator()方法得到的,所以我们说它是依赖于集合而存在的
iterator的常用方法
E next(): 返回迭代中的下一个元素
boolean hasNext(): 如果迭代具有更多元素,则返回true
package chapter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
//创建collection集合的对象 多态的方式 ArrayList()
public class CollectionDemo01 {
public static void main(String [] args){
//创建
Collection<String> c=new ArrayList<String>();
c.add("hello");
c.add("world");
c.add("java");
Iterator<String> it = c.iterator();
// System.out.println(it.next());
// System.out.println(it.next());
// System.out.println(it.next());
// System.out.println(it.next());//NoSuchElementException表示被请求的元素不存在
//boolean hasNext();如果迭代具有更多元素,则返回true
if(it.hasNext()){
System.out.println(it.next());
}
if(it.hasNext()){
System.out.println(it.next());
}
if(it.hasNext()){
System.out.println(it.next());
}
if(it.hasNext()){
System.out.println(it.next());
}
}
}
hello
world
java
//用while循环改进
while(it.hasNext()){
String s=it.next();
System.out.println(s);
}
1.6 集合的使用步骤
1.6集合的使用步骤
案例:Collection集合存储学生对象并遍历
需求:创建一个存储学生对象的集合,存储3个学生对象,使用程序实现在控制台遍历该集合
package itheima03;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionDemo {
public static void main(String[] args){
//创建Collection集合对象
Collection<Student> c =new ArrayList<Student>();
//创建学生对象
Student s1=new Student("林青霞",30);
Student s2=new Student("张曼玉",30);
Student s3=new Student("王祖贤",30);
//把学生添加到集合
c.add(s1);
c.add(s2);
c.add(s3);
//遍历集合(迭代器)
Iterator<Student> it=c.iterator();
while(it.hasNext()){
Student s=it.next();
System.out.println(s.getName()+","+s.getAge());
}
}
}
林青霞,30
张曼玉,30
王祖贤,30
2、List
2.1 List集合概述和特点
List集合概述:有序集合(也称为序列),用户可以精准控制列表中每个元素的插入位置,用户可以通过整数索引访问元素,并搜索列表中的元素;与Set集合不同,列表通常允许重复的元素
List集合特点:有序,存储和取出元素一致;可重复:存储的元素可以重复
package itheima03;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
public class CollectionDemo {
public static void main(String[] args){
//创建集合对象
List <String> list =new ArrayList<String>();
//添加元素
list.add("hello");
list.add("world");
list.add("java");
list.add("world");
//输出
System.out.println(list);
//迭代器方式遍历
Iterator<String> it=list.iterator();
while(it.hasNext()){
String s=it.next();
System.out.println(s);
}
}
}
[hello, world, java, world]
hello
world
java
world
2.2 List 集合特有方法
package itheima03;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
public class CollectionDemo {
public static void main(String[] args){
//创建集合对象
List <String> list =new ArrayList<String>();
//添加元素
list.add("hello");
list.add("world");
list.add("java");
//void add(int index,E element):在此集合中的指定位置插入指定的元素
// list.add(1,"javaee");
// list.add(11,"javaee");
// E remove(int index);删除指定索引处的元素,返回被删除的元素
// System.out.println(list.remove(1));
//IndexOutOfBoundsException;
// System.out.println(list.remove(11));
// System.out.println(list.set(1, "javaee"));
//IndexOutOfBoundsException;
// System.out.println(list.set(11, "javaee"));
//get () 返回指定索引处的元素
// System.out.println(list.get(1));
//IndexOutOfBoundsException;
//System.out.println(list.get(11));
//输出
// System.out.println(list);
//遍历集合;
// System.out.println(list.get(0));
// System.out.println(list.get(1));
// System.out.println(list.get(2));
for(int i=0;i<list.size();i++){
String s=list.get(i);
System.out.println(s);
}
}
}
[hello, javaee, world, java]
索引越界
world
[hello, java]
world
[hello, javaee, java]
world
[hello, world, java]
hello
world
java
案例:List集合储存学生对象并遍历
需求:创建一个储存学生对象的集合,存储3个学生对象,使用程序实现在控制台遍历该集合
package itheima03;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
public class ListDemo {
public static void main(String [] args){
//创建List集合对象
List<Student> list=new ArrayList<Student>();
//创建学生对象
Student s1=new Student("林青霞", 30);
Student s2=new Student("张曼玉",35 );
Student s3=new Student("王祖贤",33);
//将学生添加到集合
list.add(s1);
list.add(s2);
list.add(s3);
//
Iterator<Student> it=list.iterator();
while(it.hasNext()){
Student s=it.next();
System.out.println(s.getName()+","+s.getAge());
}
System.out.println("-------");
//for循环方式
for(int i=0;i<list.size();i++){
Student s=list.get(i);
System.out.println(s.getName()+","+s.getAge());
}
}
}
林青霞,30
张曼玉,35
王祖贤,33
-------
林青霞,30
张曼玉,35
王祖贤,33
2.3并发修改异常
ConcurrentModificationException
产生原因:迭代器遍历的过程中,通过集合对象修改了集合中元素的长度,造成了迭代器获取元素中判断预期修改值和实际修改值不一致
解决方案:用for循环遍历,然后用集合对象做相应的操作即可
package itheima03;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
public class CollectionDemo {
public static void main(String[] args){
//创建集合对象
List <String> list =new ArrayList<String>();
//添加元素
list.add("hello");
list.add("world");
list.add("java");
// Iterator<String> it=list.iterator();
//
// while(it.hasNext()){
// String s=it.next();
// if(s.equals("world")){
// list.add("javaee");
// }//并发性异常
// }
for(int i=0;i<list.size();i++){
String s=list.get(i);
if(s.equals("world")){
list.add("javaee");
}
}
System.out.println(list);
}
}
[hello, world, java, javaee]
2.4ListIterator:列表迭代器
通过List集合的ListIterator()方法得到,所以说它是List集合特有的迭代器
用于允许程序员沿任一方向遍历列表的列表迭代器,在迭代期间修改列表,并获取列表中迭代器的当前位置
逆向遍历
2.5 增强for循环
增强for: 简化数组和Collection集合的遍历
实现Iterator接口的类允许其对象称为增强型for语句的目标
它是JDK5之后出现的,其内部原理是一个Iterator迭代器
package myList;
import java.util.List;
import java.util.ArrayList;
public class ForDemo {
public static void main(String[] args){
int [] arr={1,2,3,4,5};
for(int i:arr){
System.out.println(i);
}
System.out.println("--------");
String[] strArray ={"hello","world","java"};
for(String s: strArray){
System.out.println(s);
}
System.out.println("--------");
List<String> list =new ArrayList<String>();
list.add("hello");
list.add("world");
list.add("java");
for(String s:list){
System.out.println(s);
}
System.out.println("--------");
// //内部是一个Iterator迭代器
// for(String s:list){
// if(s.equals("world")){
// list.add("javaee");//ConcurrentModificationException
// }
// }
//
}
}
1
2
3
4
5
--------
hello
world
java
--------
hello
world
java
--------
案例:list集合存储学生用三种方式遍历
package myList;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
public class listDemo {
public static void main(String[] args){
//创建List集合对象
List<Student> list=new ArrayList<Student>();
//创建学生对象
Student s1=new Student("林青霞", 30);
Student s2=new Student("张曼玉",35 );
Student s3=new Student("王祖贤",33);
//将学生添加到集合
list.add(s1);
list.add(s2);
list.add(s3);
//迭代器的方式
Iterator<Student> it=list.iterator();
while(it.hasNext()){
Student s=it.next();
System.out.println(s.getName()+","+s.getAge());
}
System.out.println("-------");
//普通for,带有索引的遍历方式
for(int i=0;i<list.size();i++){
Student s=list.get(i);
System.out.println(s.getName()+","+s.getAge());
}
System.out.println("-------");
//增强for,最方便的遍历方式
for(Student s:list){
System.out.println(s.getName()+","+s.getAge());
}
}
}
林青霞,30
张曼玉,35
王祖贤,33
-------
林青霞,30
张曼玉,35
王祖贤,33
-------
林青霞,30
张曼玉,35
王祖贤,33
2.6 数据结构
数据结构是计算机存储。组织数据的方式,是指相互之间存在一种或多种特定关系的数据元素的集合,通常情况下,精心选择的数据结构可以带来更高的运行或存储效率。
2.7 常见数据结构栈
栈是一种数据先进后出的模型
2.8 常见数据结构之队列
队列是一种数据先进先出的模型
2.9 常见数据结构之数组
查询数据通过索引定位,查询任意数据耗时相同,查询速度快
删除数据时,要将原始数据删除,同时后面每个数据前移,删除效率低
添加数据时,添加位置后的每个数据后移,再添加元素,添加效率极低
2.10常见数据结构之链表
链表是一种增删快的模型(对比数组)
查询数据D是否存在,必须从头(head)开始查询
查询第三个数据,必须从头(head)开始查询
2.11 List集合子类特点
list 集合常用子类:ArrayList,LInkedList
ArrayList:底层数据结构是数组,查询快,增删慢
LinkedList:底层数据结构是链表,查询慢,增删快
练习:分别使用ArrayList和LinkedList完成存储字符串并遍历
package myList;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Iterator;
public class listDemo {
public static void main(String[] args){
//创建集合对象
ArrayList <String> array=new ArrayList<String>();
array.add("hello");
array.add("world");
array.add("java");
for(String s:array){
System.out.println(s);
}
System.out.println("--------");
Iterator <String> it=array.iterator();
while(it.hasNext()){
String s=it.next();
System.out.println(s);
}
System.out.println("--------");
for(int i=0;i<array.size();i++){
String s=array.get(i);
System.out.println(s);
}
System.out.println("--------");
LinkedList<String> linkedlist=new LinkedList<String>();
linkedlist.add("hello");
linkedlist.add("world");
linkedlist.add("java");
for(String s:linkedlist){
System.out.println(s);
}
}
}
hello
world
java
--------
hello
world
java
--------
hello
world
java
--------
hello
world
java
案例:ArrayList集合存储学生对象用三种方式遍历
package myList;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Iterator;
public class listDemo {
public static void main(String[] args){
ArrayList<Student> array=new ArrayList<Student>();
Student s1=new Student("林青霞",30);
Student s2=new Student("张曼玉",35);
Student s3=new Student("王祖贤",33);
array.add(s1);
array.add(s2);
array.add(s3);
for(Student s:array){
System.out.println(s.getName()+","+s.getAge());
}
System.out.println("--------");
Iterator <Student> it=array.iterator();
while(it.hasNext()){
Student s=it.next();
System.out.println(s.getName()+","+s.getAge());
}
System.out.println("--------");
for(int i=0;i<array.size();i++){
Student s=array.get(i);
System.out.println(s.getName()+","+s.getAge());
}
}
}
林青霞,30
张曼玉,35
王祖贤,33
--------
林青霞,30
张曼玉,35
王祖贤,33
--------
林青霞,30
张曼玉,35
王祖贤,33
2.12 LInkedList集合的特有功能
3.Set
3.1Set集合概述和特点
set集合特点:不包含重复元素的集合
没有带索引的方法,所以不能使用普通for循环遍历
set集合练习,存储字符串并练习
package myList;
import java.util.Set;
import java.util.HashSet;
//HashSet:对集合的迭代顺序不作任何保证
public class SetDemo {
public static void main(String[] args){
//创建集合对象
Set<String> set=new HashSet<String>();
//添加元素
set.add("hello");
set.add("world");
set.add("java");
//不包含重复元素
set.add("world");
//遍历
for(String s:set){
System.out.println(s);
}
}
}
world
java
hello
3.2哈希值
哈希值:是JDK根据对象或者字符串或者数字算出来的int类型的数值
Object类中有一个方法可以获取对象的哈希值
public int hashCode(): 返回对象的哈希码值
对象的哈希值特点:
同一个对象多次调用hashCode()方法返回的哈希值是相同的
默认情况下,不同对象的哈希值是不同的,而重写hashCode()方法,可以实现让不同对象的哈希值相同
package myList;
public class HashDemo {
public static void main(String[] args){
//创建学生对象
Student s1=new Student("林青霞",30);
//用一个对象多次调用hashCode()方法返回的哈希值是相同的
System.out.println(s1.hashCode());
System.out.println(s1.hashCode());
System.out.println("--------");
Student s2=new Student ("林青霞", 30);
//默认情况下,不同对象的哈希值是不同的
//通过方法重写,可以实现不同对象的哈希值是相同的
System.out.println(s2.hashCode());
System.out.println("--------");
System.out.println("hello".hashCode());//99162322
System.out.println("world".hashCode());//113318802
System.out.println("java".hashCode());//3254818
System.out.println("--------");
System.out.println("重地".hashCode());//1179395
System.out.println("通话".hashCode());//1179395
}
}
705927765
705927765
--------
366712642
--------
99162322
113318802
3254818
--------
1179395
1179395
3.3 HashSet集合概述和特点
HashSet集合特点:
底层数据结构是哈希表
对集合的迭代顺序不作任何保证,也就是说不保存存储和取出的元素顺序一致
没有带索引的方法,所以不能使用普通for循环遍历
由于是Set集合,所以是不包含重复元素的集合
HashSet集合练习:
存储字符串并遍历
package myList;
import java.util.HashSet;
public class HashDemo {
public static void main(String[] args){
//创建集合对象
HashSet<String> hs=new HashSet<String>();
//添加元素
hs.add("hello");
hs.add("world");
hs.add("java");
//遍历:对集合的迭代顺序不作任何保证
hs.add("world");
for(String s:hs){
System.out.println(s);
}
}
}
world
java
hello
3.4HashSet集合保证元素唯一性源码分析
3.5 常见数据结构之哈希表
哈希表:JDK8之前,底层采用数组+链表实现,可以说是一个元素为链表的数组
JDK8以后,在长度比较长的时候,底层实现了优化
案例:HashSet集合存储学生对象并遍历
需求:
第六步:在学生类重写两个方法 hashCode()和equals()自动生成即可
package myList;
import java.util.HashSet;
public class HashSetDemo {
public static void main(String[] args){
//创建HashSet集合对象
HashSet<Student> hs=new HashSet<Student>();
//创建学生对象
Student s1=new Student("林青霞",30);
Student s2=new Student("张曼玉",35);
Student s3=new Student("王祖贤",33);
Student s4=new Student("王祖贤",33);
//把学生添加到集合
hs.add(s1);
hs.add(s2);
hs.add(s3);
hs.add(s4);
//遍历集合
for(Student s:hs){
System.out.println(s.getName()+","+s.getAge());
}
}
}
3.6LinkedHashSet集合概述和特点
LinkedHashSet集合特点:
哈希表和链表实现的Set接口,具有可预测的迭代顺序
由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
由哈希表保证元素唯一,也就是没有重复的元素
LinkedHashSet集合练习
存储字符串并遍历
package myList;
import java.util.LinkedHashSet;
public class LinkedHashSetDemo {
public static void main(String[] args){
LinkedHashSet <String> l=new LinkedHashSet<String> ();
//添加元素
l.add("hello");
l.add("world");
l.add("java");
l.add("world");
//遍历集合
for(String s:l){
System.out.println(s);
}
}
}
hello
world
java
3.7 TreeSet集合概述和特点
TreeSet集合特点:
元素有序,这里的顺序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体排序方式取决于构造方法
TreeSet():根据其元素的自然排序进行排序
TreeSet(Comparator comparator): 根据指定的比较器进行排序
没有带索引的方法,所以不能使用普通for循环遍历
由于是Set集合,所以不包含重复元素的集合
package myList;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args){
//创建集合元素
TreeSet<Integer> ts=new TreeSet<Integer>();
//添加元素;
ts.add(10);
ts.add(40);
ts.add(30);
ts.add(50);
ts.add(20);
ts.add(30);
//遍历集合
for(Integer i:ts){
System.out.println(i);
}
}
}
10
20
30
40
50
3.8 自然排序Comparable的使用
存储学生对象并遍历,创建TreeSet集合使用无参构造方法
要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
结论:用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的
自然排序,就是让元素所属的类实现Comparable接口,重写compareTo(To)方法
重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
3.9 比较器排序Comparator的使用
存储学生对象并遍历,创建TreeSet集合使用带参构造方法
要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
结论:
用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的
比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(To1,To2)方法
重写方法时,一定要注意排序规则必须按照需求的主要条件和次要条件来写
案例:成绩排序
案例:不重复的随机数
package myList;
import java.util.TreeSet;
import java.util.Set;
import java.util.HashSet;
import java.util.Random;
public class TreeSetDemo01 {
public static void main(String [] args){
//
// Set<Integer> set =new HashSet<Integer>();
Set<Integer> set=new TreeSet<Integer>();
//
Random r=new Random();
while (set.size()<10){
//
int number =r.nextInt(20)+1;
set.add(number);
}
for(Integer i:set){
System.out.println(i);
}
}
}
3
5
6
8
9
11
13
15
17
20