1、集合简介
集合和数组类似,都是储存元素的容器,数组像是静态容器(长度一旦创建就不能再改变、元素类型必须统一、只能通过下标去索引元素等),集合像是动态容器(集合的长度可以动态的改变、元素类型可以不一致、可以用某个映射的关系去索引元素等)
java中的集合是一个工具类,可以储存任意数量且具有共同属性的对象。集合的应用场景一般有以下几点
- 无法预测储存数据的数量
- 同时储存具有一对一关系的数据
- 举要进行频繁的数据增删操作
- 数据重复问题
java中的集合主要可以分为Collection和Map两大体系,下图是collection的体系图
2、Collection(接口)
在Collection下,可以分为List和Set两大类
向集合中添加元素
从集合中移除元素
使用迭代器遍历集合
Iterator的对象称为迭代器(设计模式中的一种),主要用于遍历Collection集合中的元素。所有实现了Collection接口的集合类都有一个iterator()方法,用于返回一个实现了Iterator接口的对象。Iterator仅用于遍历集合,Iterator本身并不提供承装对象的能力。如果要创建Iterator对象,就必须有一个被迭代的集合
2.1List(接口)
List集合下的元素可以重复,并会记录元素添加的顺序。
List下有三个实现类:ArrayList(主要实现类,适合在数据查找频率较高的情况下使用)、LinkedList(适合在数据插入、删除频繁的情况下使用)、Vector(古老的实现类,几乎不用不介绍了)
2.1.1ArrayList
ArrayList是对象引用的一个变长数组,所以随机查找时效率很高,增删比较频繁的时候不建议使用。
ArrayList时线程不安全的,而Vector是线程安全的,即使为了使用线程安全也不会使用Vector,因为效率太低了
ArrarList.asList(…)返回的是一个固定长度的List集合,既不是ArrayList实例也不是Vector实例
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class arraylist {
/**
* 从40个学生的班级中,随机抽取两个java成绩大于60分的同学,计算平均分作为班级的平均分
* */
public static void main(String[] args) {
List allScores = new ArrayList<>();
int allStudent = 40;
Random random = new Random();
// 随机产生40个人的成绩
for (int i = 0; i < allStudent; i++) {
allScores.add(i,random.nextInt(101));
}
// 查询所有成绩大于60分的人
List passScores = new ArrayList<>();
for (Object allScore : allScores) {
if((Integer)allScore>60){
passScores.add((Integer)allScore);
}
}
// 随机抽取两名学生同学的分数作为平均成绩
int passLength = passScores.size();
int score1 = (Integer)passScores.get(random.nextInt(passLength));
int score2 = (Integer)passScores.get(random.nextInt(passLength));
System.out.println("抽取的两个学生成绩为"+score1+" "+score2);
System.out.println("平均成绩为"+(score1+score2)/2);
}
}
2.1.2LinkedList
LinkedList内部是链表进行维护的,在我们模拟栈、队列的时候,都可以使用它
import java.util.LinkedList;
public class linkedlist {
public static void main(String[] args) {
LinkedList<String> objects = new LinkedList<>();
objects.add("java");
objects.add("python");
objects.add("C++");
// void addFirst(Object obj) 在该列表开头指定插入的元素
// void addLast(Object obj) 将指定的元素追加到此列表的末尾
// Object getFirst() 返回此列表中的第一个元素
// Object getLast() 返回此列表中的最后一个元素
// Object removeFirst() 从此列表中删除并返回第一个元素
// Object removeLast() 从列表中删除并返回最后一个元素
// objects.addFirst("dd");
String s = objects.getFirst();
System.out.println(s);
for (Object object : objects) {
System.out.println(object);
}
}
}
2.2Set(接口)
Set集合下的元素是不可重复的,并且是无序的,Set接口是Collection的子接口
Set下主要有三个实现类:HashSet(典型的实现类,按Hash算法来储存集合中的元素,因此具有很好的存取和查找性能)、LinkedHashSet(同时使用链表维护元素的次序,使得元素看起来是以插入顺序保存的)、TreeSet(可以确保集合元素处于排序状态)
2.2.1HashSet
只要底层不是数组就不会有下标。所以删除元素只能通过元素内容删除
HashSet是Set接口的典型实现,大多数使用set集合时都使用这个实现类,HashSet按照Hash算法来储存集合中的元素,因此具有很好的存取和查找性能。HashSet的特点如下
不能保证元素的排列顺序
HashSet不是线程安全的
集合元素可以是null
2.2.1TreeSet
底层是二叉树:不可重复,但是有序,对于实现了comparable、comparator接口的类型就可以排序,可以对于八种基本数据类型排序,也可以对String进行排序,仅限于英文
3、Map集合(也是一个接口重要)
list和set接口都是单列集合存数据是一条一条存的,map是双列行集合,成对存的,通过本文的第一张图可以看出如果一个接口是继承collection的就是单列集合
双向型,存放数据无序,key不可以重复,value可以重复
3.1HashMap
底层也是hash表,key不可以重复、value可以重复,key对于的记录无序
添加方法put,返回值是上一个key的值
修改方法,没有修改方法,通过添加同key做覆盖修改
删除方法remove可以根据key删除clear删除整个map
查询方法get的key或者匿名函数
3.2TreeMap
底层是二叉树,key不可以重复,value可以重复,treemap是有序的,可以根据key进行排序,排序的原则是可以进行比较即key的类型实现了(comparable、comparator接口),TreeMap增删改查的方法和HashMap一模一样
import java.util.TreeMap;
public class Demo02 {
public static void main(String[] args) {
// TreeMap<String, Integer> aMap = new TreeMap<>();
// aMap.put("b",12);
// aMap.put("a",10);
// aMap.put("c",50);
// aMap.put("z",12);
// aMap.forEach((k,v)->{
// System.out.println(k+"="+v);
// });
// 给东一个字符串,统计每个字符出现的次数
String str = "sfgskjsngashrbgsdjcnsjdknvasngierumdcakdjs";
// 将字符串转成字符数组
char[] a = str.toCharArray();
// 取出数组中的某个元素,看容器中是否存在
TreeMap<String, Integer> aMap = new TreeMap<>();
for (char c : a) {
Integer value = aMap.get(c+"");
if(value==null){
aMap.put(c+"",1);
}else{
value++;
aMap.put(c+"",value); // 字符串加任何数字都是字符串
}
}
//打印结果
aMap.forEach((k,v)->{
System.out.println(k+""+v);
});
}
}