集合的简介
在学集合之前,我通常以为数组就是集合,其实并不然,集合就是一种灵活的容器。而数组是一种固定但存放样式多的容器。
何谓灵活呢?就是其可以通过指定的语句来改变 添加 删除里面的引用类型。
如下图:
集合
上图中除了ArrayList和HashSet和HashMap外其余都是接口,不可以以创建对象。
因此想要new,就得使用这三个常用的子类
API下的定义
1.Collection是单列表的顶层接口
2.有些集合允许重复而有些不能
例如:List集合是可以重复的,set集合是不允许重复的。
3.集合有序和无需,例如List集合是有序的而set是无序的。
4.Collection接口没有直接具体的子类,而是有很多的子接口比如set和list就是比较庞大的两大子接口
List集合特点及应用
API下的定义 点这里----》入口
集合的命名很有特点
像ArrayList(是一个比较常用的类) ,后边的List(名字)是该集合所属的体系,那么ArrayList说明其属于List体系,前面的名Array,说明ArrayList的底层是通过数组的形式实现的。
下面我们就拿List中最常用的ArrayList类来演示
ArrrayList中有三个比较常有的方法
分别是
1.void add(int index, E element):将指定元素插入此列表中的指定位置
2.int size():返回此列表中的元素数。
3.E get(int index):返回此列表中指定位置的元素。
E:表示泛型,可以先理解为Object类型
public class Student {
private String name;
private int age;
public Student() {
}
public Student(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 "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
import java.util.List;
import java.util.ArrayList;
/*
单列集合(collection)的特点之List集合
特点:
有序(元素的存储顺序一致),可重复。
注意:
List是接口,所以通过ArrayList类完成接口的实例化
1.void add(int index, E element): 将指定元素插入此列表中的指定位置
2.int size():返回此列表中的元素数。
3.E get(int index):返回此列表中指定位置的元素。
使用集合的步骤:
1.创建集合的对象
2.创建集合的元素
3.将对象添加到集合元素中
4.遍历集合
*/
public class Test {
public static void main(String[] args) {
//创建集合对象
List list = new ArrayList();
//创建元素对象
Student s1 = new Student("张x明",20);
Student s2 = new Student("张x明",20);
Student s3 = new Student("钟x堂",19);
Student s4 = new Student("邹x明",18);
//将元素添加到集合对象中 add为boolean类型,用来表示是否添加成功的同时添加元素
list.add(s1);
list.add(s2);
list.add(s3);
list.add(s4);
//打印集合
System.out.println(list);
//获取索引值为2的元素
Object obj = list.get(2); //注意get是E(泛型),所以获取它需要用Object类
System.out.println("索引为2的元素是:" + obj);
//获取元素的个数
System.out.println("元素的个数为:" + list.size());
//遍历集合(前面三个方法一起综合使用)
for (int i = 0;i<list.size();i++){
Object obj2 = list.get(i);
System.out.println("索引" + i + "的元素为" + obj2 );
}
}
}
结果
增强for循环和迭代器
import java.util.List;
import java.util.ArrayList;
/*
增强for格式
for(元素的数据类型 变量名:要遍历的数组或者集合对象){
//循环体、变量也就是元素
}
*/
public class Test {
public static void main(String[] args) {
//创建对象
List list = new ArrayList();
//创建元素对象
//将元素对象添加入集合中
list.add(10);
list.add(20);
list.add(30);
list.add(40);
//利用for循环
for(Object obj : list){
System.out.println(obj);
}
}
}
import java.util.List;
import java.util.ArrayList;
/*
增强for格式
for(元素的数据类型 变量名:要遍历的数组或者集合对象){
//循环体、变量也就是元素
}
*/
public class Test {
public static void main(String[] args) {
//创建对象
List list = new ArrayList();
//创建元素对象
//将元素对象添加入集合中
list.add(10);
list.add(20);
list.add(30);
list.add(40);
//利用for循环
for(Object obj : list){
Integer ii = (Integer)obj;
System.out.println(ii);
}
}
}
其实我们可以用iter然后回车直完成这个语句
增强for的底层是iterator(迭代器),简单来说增强for就是迭代器的简写形式。
迭代器的演示
/*
迭代器
概述:
对过程的重复称为迭代
迭代器是遍历collection集合通用方式
迭代器常用方法
E next():返回迭代的下一个元素对象
boolean hasNext():如果有元素可以迭代,则返回true
注:
迭代器是list体系中独有的遍历方式,可以在对集合遍历过程的同时进行添加、删除等操作
不过要调用列表迭代器的方式来实现
*/
public class Test {
public static void main(String[] args) {
//需求:通过迭代器遍历List集合
//1.创建集合对象
List list = new ArrayList();
//2.创建元素对象
//3.把元素对象加入集合中
list.add("a");
list.add("b");
list.add("c");
list.add("d");
//4.遍历集合
//根据集合对象创建迭代器对象
Iterator it = list.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
}
列表迭代器
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
/*
迭代器
概述:
对过程的重复称为迭代
迭代器是遍历collection集合通用方式
迭代器常用方法
E next():返回迭代的下一个元素对象
boolean hasNext():如果有元素可以迭代,则返回true
注:
迭代器是list体系中独有的遍历方式,可以在对集合遍历过程的同时进行添加、删除等操作
不过要调用列表迭代器的方式来实现
*/
public class Test {
public static void main(String[] args) {
//需求:通过迭代器遍历List集合
//1.创建集合对象
List list = new ArrayList();
//2.创建元素对象
//3.把元素对象加入集合中
list.add("a");
list.add("b");
list.add("c");
list.add("d");
//4.遍历集合
//根据集合对象创建迭代器对象
//不使用Iterator(普通迭代器)是因为普通的不可以修改列表(增加,删除)
ListIterator it = list.listIterator();
while (it.hasNext()) {
String s = (String) it.next();
//如果集合有b这个字符,就加入java字符
if ("b".equals(s)) {
/*不写成s.equals(b)是因为如果s为null时,程序会报错
这样写就可以避免这个错误,这是一个小技巧*/
//list.add("java");这样写程序会报ConcurrentModificationException(并发修改异常)的错误
it.add("java");
}
System.out.println(s);
}
System.out.println(list);
}
}
如果直接是哟list.add加入就会显示并发异常的报错
如果使用普通的迭代器,就不能对list进行操作。
只有用这个语句,才可以声明为列表迭代器
ListIterator it = list.listIterator();
it.add("java");
最终结果
注:next()每被调用一次就会指向下一个元素。所以在遍历时要注意next()的出现次数。
泛型的简介
import java.util.List;
import java.util.ArrayList;
/*
泛型:泛指任意类型,又称为参数化类型,对具体类型的作用起到辅助作用,类似于方法的参数
集合泛型的解释:
表示集合中存放指定类型的元素
好处:
类型安全
避免了类型转换
*/
public class Test {
public static void main(String[] args) {
//不使用泛型的集合
List list = new ArrayList();
list.add("abc");
list.add("wda");
list.add("vsd");
list.add(10);
for (Object o : list) {
String s = (String)o;
System.out.println(s);
}
}
}
如果直接添加Integer类型,就会直接出现类型转换异常。
import java.util.List;
import java.util.ArrayList;
/*
泛型:泛指任意类型,又称为参数化类型,对具体类型的作用起到辅助作用,类似于方法的参数
集合泛型的解释:
表示集合中存放指定类型的元素
好处:
类型安全
避免了类型转换
*/
public class Test {
public static void main(String[] args) {
//不使用泛型的集合
List list = new ArrayList();
list.add("abc");
list.add("wda");
list.add("vsd");
for (Object o : list) {
String s = (String)o;
System.out.println(s);
}
System.out.println("---------------------");
//使用泛型操作
List<String> list1 = new ArrayList<>();//声明一个String类型的list
list1.add("adx");
list1.add("awd");
list1.add("adf");
//list1.add(10);程序直接报错,泛型规定了String类型,因为不属于String类型所以报错。
for (String s : list1) {
System.out.println(s);//不用再去转换类型,避免了类型转换
}
}
}
程序直接报错,泛型规定了String类型,因为不属于String类型所以报错。
结果
注:泛型一般之和集合一起使用
List<String> list1 = new ArrayList<>()
jdk7后这样的格式为菱形泛型(即前面声明了类型,后面只需要保持菱形即可,例如上面声明了String类型,后面只需要保持菱形)
Collections工具类
从文字描述可以看到,此类仅包含对集合进行操作或返回的静态方法。因此可以通过 类名.的形式进行调用。
可以看到里面的方法大多数是static的。
/*
sort(List<T>)
根据元素的自然顺序(0-9、a-z),将指定列表升序排序
max(Collection<T>)、min(Collection<T>)
返回集合的最大值
reverse(list<T>)
反转List集合元素
shuffle(List<T>)
使用默认的随机源随机置换指定的列表
*/
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
public class Test {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(5);
list.add(8);
list.add(6);
list.add(9);
list.add(10);
list.add(2);
list.add(3);
list.add(4);
list.add(7);
System.out.println(list);
//求出最大值
Integer max = Collections.max(list);
System.out.println("集合中的最大值是:" + max);
//排序集合
Collections.sort(list);
System.out.println("排序之后的集合是:" + list);
//反转集合元素(如果在升序排序的情况下,反转相当于降序)
Collections.reverse(list);
System.out.println("反转后集合元素:" + list);
//打乱集合中的元素(相当于洗牌)
Collections.shuffle(list);
System.out.println("打乱后的集合元素:" + list);
}
}
Set集合的特点和应用
public class Student {
private int age;
private String name;
public Student(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
import java.util.HashSet;
import java.util.Set;
/*
单列集合Collections之Set集合
特点:
无序(元素的存储顺序不一致)、唯一
*/
public class Test {
public static void main(String[] args) {
Set s = new HashSet();
Student s1 = new Student(18,"张三");
Student s2 = new Student(18,"李四");
Student s3 = new Student(18,"赵五");
Student s4 = new Student(18,"赵五");
s.add(s1);
s.add(s2);
s.add(s3);
s.add(s4);
System.out.println(s);
}
}
到这里有人就会问,set不是去重 吗?
怎么这里就可以重复了,原因:
解决方法:重写equals与hasCode方法。
import java.util.Objects;
public class Student {
private int age;
private String name;
public Student(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(age, name);
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
import java.util.HashSet;
import java.util.Set;
import java.util.Iterator;
/*
单列集合Collections之Set集合
特点:
无序(元素的存储顺序不一致)、唯一
*/
public class Test {
public static void main(String[] args) {
Set<Student> s = new HashSet<>();
Student s1 = new Student(18, "张三");
Student s2 = new Student(18, "李四");
Student s3 = new Student(18, "赵五");
Student s4 = new Student(18, "赵五");
s.add(s1);
s.add(s2);
s.add(s3);
s.add(s4);
System.out.println(s);
System.out.println("使用迭代器打印");
Iterator<Student> it = s.iterator();
while (it.hasNext()) {
Student s5 = it.next();
System.out.println(s5);
}
System.out.println("使用增强for打印");
for (Student student : s) {
System.out.println(student);
}
}
}
可以看到输入和输出的顺序是不一样的,这就是无序性。
Map集合的特点和应用
import java.util.HashMap;
import java.util.Map;
import java.util.Iterator;
import java.util.Set;
/*
Map集合的特点
特点:
双列集合,元素由键值(Entry)构成:
key(键) -- value(值)
注意:
键(key)不可以重复,值(value)可以重复
应用:
Map<T1,T2>map = new HashMap<>();
解释:
T1:表示键的数据类型
T2:表示值的数据类型
成员方法:
V put(K key , V value):添加元素(键值对的形式)。
元素第一次添加返回null
重复添加,新的值会覆盖旧的值,并且返回旧值
V get(Object key): 根据键获取其对应的值。
Set<K> keySet: 获取所有键的集合。
*/
public class Test {
public static void main(String[] args) {
Map<Integer, Student> map = new HashMap<>();
Student s1 = new Student(18, "张三");
Student s2 = new Student(20, "李四");
Student s3 = new Student(19, "赵五");
Student s4 = new Student(18, "张三");
Student stu1 = map.put(1, s1);
System.out.println("stu1 = " + stu1);
Student stu2 = map.put(1, s2);
System.out.println("stu2 = " + stu2);
System.out.println("-----------------------");
map.put(1, s1);
map.put(2, s2);
map.put(3, s3);
map.put(4, s4);
System.out.println(map);
System.out.println("-----------------------");
//根据键获取值
Student stu3 = map.get(2);
System.out.println(stu3);
System.out.println("------------------------");
//遍历双列集合
Set<Integer> keys = map.keySet();
//把双列变成单列
Iterator<Integer> it = keys.iterator();//迭代对象是键
while (it.hasNext()) {
Integer key = it.next();//一个获取键
Student value = map.get(key);//一个获取值
System.out.println("key = " + key + ",value = " + value);
}
System.out.println("通过增强for遍历双列集合");
for (Integer key : keys) {
Student va = map.get(key);
System.out.println("key = " + key + ",value = " + va);
}
}
}