文章目录
![在这里插入图片描述](https://img-blog.csdnimg.cn/cd72450f9a9e48baa4c16ac835d61027.png)
集合体系
/**
* 明确Collection集合体系的特点
*/
public class Demo1 {
public static void main(String[] args) {
//ArrayList有序 可重复 有索引
Collection list1=new ArrayList<>();
list1.add("java");
list1.add("java");
list1.add("K");
list1.add(23);
list1.add(false);
System.out.println(list1);//[java, java, K, 23, false]
//Hashset无序 不重复 无索引
Collection list2=new HashSet();
list2.add("java");
list2.add("java");
list2.add("K");
list2.add(23);
list2.add(false);
System.out.println(list2);//[java, false, 23, K]
}
}
Collection常用API
public class API {
public static void main(String[] args) {
Collection<String > list=new ArrayList<>();
list.add("Java");
list.add("Java");
list.add("Mysql");
list.add("Some");
list.add("12");
//清空集合
list.clear();
//判断是否为空
list.isEmpty();
//是否包含某个元素
list.contains("Java");
//删除某个元素, 如果有多个重复元素,删除第一个
list.remove("Java");//用Collection定义的集合无法利用索引删除元素,如需利用索引删除元素:ArrayList<String> list=new ArrayList<>();
//集合转换成数组
Object[] arrs=list.toArray();
Collection<String > c1=new ArrayList<>();
c1.add("Java1");
c1.add("Java2");
Collection<String > c2=new ArrayList<>();
c2.add("Mysql");
c2.add("Some");
//把c2中的元素全部导入到c1
c1.addAll(c2);
}
}
Collection的遍历方式
Iterator迭代器
public class C_Iterator {
public static void main(String[] args) {
Collection<String > list=new ArrayList<>();
list.add("Java");
list.add("Java");
list.add("Mysql");
list.add("Some");
list.add("12");
Iterator<String> it=list.iterator();
while (it.hasNext()){
String ele=it.next();
System.out.println(ele);
}
}
}
foreach/增强for循环
既可以遍历集合也可以遍历数组,其内部原理是一个Iterator迭代器,遍历集合相当于是迭代器的简化写法
实现Iterable接口的类才可以使用迭代器和增强for,Collection接口已经实现了Iterable接口。
Collection<String > list=new ArrayList<>();
list.add("Java");
list.add("Java");
list.add("Mysql");
list.add("Some");
list.add("12");
for (String ele:list){
System.out.println(ele);
}
double[] socres={
11.2,21.2,231,211.2};
for (double socre : socres) {
System.out.println(socre);
}
lambda表达式
list.forEach(s -> {
System.out.println(s);
});
List
List<String > list=new ArrayList<>();
list.add("Java");
list.add("Java");
list.add("Mysql");
list.add(1,"some");//在指定位置插入元素,后续元素会后移一位
list.remove(2);//返回被删除的元素
list.get(1);//返回指定位置的元素
list.set(1,"22");//修改指定位置的元素,并返回修改前的元素
ArrayList
如果输入的数据数量超出设定的长度,会自动扩容到原来的1.5倍
LinkedList
![](/qrcode.jpg)
//LinkedList可以完成 队列结构 和 栈结构
//栈
LinkedList<String> stack=new LinkedList<>();
stack.push("1");
stack.push("2");
stack.push("3");
System.out.println(stack);//[3, 2, 1]
stack.pop();//[2, 1]
stack.add("4");
System.out.println(stack);//[2, 1, 4]
//队列
LinkedList<String> queue=new LinkedList<>();
queue.addLast("1");
queue.addLast("2");
queue.addLast("3");
System.out.println(queue);//[1, 2, 3]
queue.removeFirst();//[2, 3]
queue.add("4");
System.out.println(queue);//[2, 3, 4]
Collection的更新和删除
public static void main(String[] args) {
List<String > list=new ArrayList<>();
list.add("Java");
list.add("Java");
list.add("Mysql");
list.add("Some");
list.add("12");
System.out.println(list);//[Java, Java, Mysql, Some, 12]
Iterator<String> it=list.iterator();
//1.迭代器
while (it.hasNext()){
String s=it.next();
if (s.equals("Java")){
//list.remove("Java");//会报错,这样删除元素过后,指针会指向下一个位置,但删除的元素之后的元素会向前移。
it.remove();//删除当前元素,迭代器会自动向前移一位
}
}
System.out.println(list);//[Mysql, Some, 12]
//2.for循环,但需要从后往前遍历,避免漏掉元素
for (int i = list.size()-1; i >=0; i--) {
String ele=list.get(i);
if (ele.equals("Java")){
list.remove("Java");
}
}
System.out.println(list);//[Mysql, Some, 12]
}
Set
Set系列集合特点
无序:存取顺序不一致
不重复:可以去除重复
无索引:没有带索引的方法,所以不能使用普通for循环遍历,也不能通过索引来获取元素
Set集合实现类特点
HashSet:无序、不重复、无索引
LinkedHashSet:有序、不重复、无索引
TreeSet:排序、不重复、无索引
HashSet
哈希值:是JDK根据对象的地址,按照某种规则计算出来的int类型的数值。
public int hashCode()//返回对象的哈希值
同一个对象多次调用hashCoe方法返回的哈希值是相同的
一般情况下,不同对象的哈希值是不同的
Demo 去除重复
public static void main(String[] args) {
Set<Student> sets=new HashSet<>();
Student s1=new Student("Damon",22,'m');
Student s2=new Student("Elena",23,'f');
Student s3=new Student("Elena",23,'f');
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println(s3.hashCode());
sets.add(s1);
sets.add(s2);
sets.add(s3);
System.out.println(sets);
}
public class Student {
private String name;
private int age;
private char sex;
public Student() {
}
public Student(String name, int age, char sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
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 char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
@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 && sex == student.sex && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age, sex);
}
}
LinkedHashSet
TreeSet
Set<Integer> sets1=new TreeSet<>();
sets1.add(11);
sets1.add(4);
sets1.add(32);
sets1.add(20);
System.out.println(sets1);//[4, 11, 20, 32]
Set<String > sets2=new TreeSet<>();
sets2.add("Java");
sets2.add("Mysql");
sets2.add("ab");
sets2.add("Ab");
System.out.println(sets2);//[Ab, Java, Mysql, ab]
实现对对象的排序,方法1:集合自带比较器对象进行规则制定
public static void main(String[] args) {
Set<Student> sets3=new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge()-o2.getAge();
//return Double.compare(o1.getAge(),o2.getAge());
}
});
//简化写法
Set<Student> sets3=new TreeSet<>((Student o1, Student o2) -> o1.getAge()-o2.getAge() );
Student s1=new Student("Damon",30,'m');
Student s2=new Student("Elena",23,'f');
Student s3=new Student("Stefan",11,'f');
sets3.add(s1);
sets3.add(s2);
sets3.add(s3);
System.out.println(sets3);
}
//实现Comparable接口
public class Student implements Comparable<Student>{
private String name;
private int age;
private char sex;
@Override
public int compareTo(Student o) {
return this.age-o.age;
}
可变参数
可变参数用在形参种可以接收多个数据。
可变参数的格式:数据类型…参数名称。
作用
传输参数灵活方便。可以不传参数或者多个参数,也可以传输一个数组
可变参数在方法内部本质上就是一个数组
注意:
一个形参列表中只能有一个可变参数。
可变参数必须放在型参列表的最后。
public static void main(String[] args) {
sum();
sum(1);
sum(2,3);
sum(new int[]{
1,2,3,4,5});
}
/**
* 一个形参列表中只能有一个可变参数,
* 可变参数必须放在型参列表的最后 private static void sum(int age,int... nums)
*/
private static void sum(int... nums) {
System.out.println(nums.length);
System.out.println(Arrays.toString(nums));
}
Collections集合工具类
addAll
Set<Integer> sets1=new TreeSet<>();
//1
sets1.add(11);
sets1.add(4);
sets1.add(32);
sets1.add(20);
//2
Collections.addAll(sets1,11,4,32,20);
1和2结果相同2
shuffle
public static void main(String[] args) {
List<Integer> list1=new ArrayList<>();
Collections.addAll(list1,1,2,4,5);
System.out.println(list1);//[1, 2, 4, 5]
Collections.shuffle(list1);
System.out.println(list1);//[4, 2, 1, 5]
}
sort
public static void main(String[] args) {
//1
List<Integer> list2=new ArrayList<>();
Collections.addAll(list2,11,20,10,9,3);
System.out.println(list2);//[11, 20, 10, 9, 3]
Collections.sort(list2);
System.out.println(list2);//[3, 9, 10, 11, 20]
//2
List<Student> list3=new ArrayList<>();
Collections.sort(set4, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge()-o2.getAge();
}
});
//简化写法
Collections.sort(set4, (Student o1, Student o2) ->o1.getAge()-o2.getAge() );
}
Map
概述
Map集合是一种双列集合,每个元素包含两个数据。
Map集合的每个元素的格式:Key==value(键值对元素)
Map集合也被称为键值对集合。
格式:
Collection集合的格式:[元素1,元素2,元素3…]
Map集合的完整格式:[key1=value1,key2=value2,key3=value3,…]
特点:
Map集合的特点都是由键决定的。
Map集合的键是无序、不重复、无索引的,值可以重复。
Map集合后面重复的键对应的值会覆盖前面重复键的值。
Map集合的键值对都可以为null。
Map<String,Integer> maps=new HashMap<>();
maps.put("a",1);
maps.put("b",2);
maps.put("c",3);//{null=null, a=1, b=2, c=3}
maps.put("c",4);//{null=null, a=1, b=2, c=4}
maps.put(null,null);
实现类特点:
HashMap:元素按照键是无序、不重复、无索引的,值不做要求。
LinkedHashMap:元素按照键是有序(按照添加的顺序)、不重复、无索引的,值不做要求。
TreeMap:元素按照键是排序、不重复、无索引的,值不做要求。
Map常用API
public static void main(String[] args) {
Map<String,Integer> maps=new HashMap<>();
maps.put("a",1);
maps.put("b",2);
maps.put("c",3);//{null=null, a=1, b=2, c=3}
maps.put("c",4);//{null=null, a=1, b=2, c=4}
maps.put(null,null);
//清空集合
maps.clear();
//判断集合是否为空,返回true和false
boolean res1=maps.isEmpty();
//根据键获得对应值,
Integer res2= maps.get("a");
//根据键删除整个元素,会返回键的值
Integer res3=maps.remove("a");
//判断是否包含某个键,返回true和false
boolean res4=maps.containsKey("t");
//判断是否包含某个值,返回true和false
boolean res5=maps.containsValue(1);
// 获取全部键的集合,
Set<String > res6=maps.keySet();
//获取全部值的集合,因为值可能有重复,所以用Collection,Set无重复
Collection<Integer > res7=maps.values();
//集合的大小
maps.size();
//合并其他Map集合
Map<String,Integer> map1=new HashMap<>();
map1.put("a",1);
map1.put("b",2);
Map<String,Integer> map2=new HashMap<>();
map2.put("c",5);
map2.put("b",4);
map2.putAll(map1);
}
Map遍历方式
方式1:键找值
先获取Map集合的全部键的Set集合。
遍历键的Set集合,然后通过键提取对应值。
Map<String,Integer> maps=new HashMap<>();
maps.put("a",1);
maps.put("b",2);
maps.put("c",3);
Set<String> key=maps.keySet();
for (String s : key) {
int value=maps.get(s);
}
方式2:键值对
先把Map集合转换成Set集合,Set集合中每个元素都是键值对实体类型。
遍历Set集合,然后提取键以及提取值。
//1。把Map集合转为Set集合
Set<Map.Entry<String, Integer>> entries = maps.entrySet();
//2。开始遍历
for (Map.Entry<String, Integer> entry : entries) {
String key=entry.getKey();
int value=entry.getValue();
}
方式3:Lambda
maps.forEach(new BiConsumer<String, Integer>() {
@Override
public void accept(String key, Integer value) {
System.out.println(key+"="+value);
}
});
//简易写法
maps.forEach((key, value)-> System.out.println(key+"="+value));
Demo–统计投票人数
public static void main(String[] args) {
//随机一下80个选择
String[] selects={
"A","B","C","D"};
StringBuilder sb=new StringBuilder();
Random r=new Random();
for (int i = 0; i < 80; i++) {
sb.append(selects[r.nextInt(selects.length)]);
}
//定义Map记录信息
Map<Character ,Integer> infos=new HashMap<>();
for (int i = 0; i < sb.length(); i++) {
char c=sb.charAt(i);
if (infos.containsKey(c)){
infos.put(c,infos.get(c)+1);
}else {
infos.put(c,1);
}
}
}
HashMap
特点和底层原理:
有键决定:无序、不重复、无索引。HashMap底层是哈希表结构的。
依赖hashCode方法和equals方法保证键的唯一。
如果键要存储的是自定义对象,需要重写hashCode和equals方法。
基于哈希表,增删改查性能好。
LinkedHashMap
由键决定:有序、不重复、无索引。
这里的有序是保证存储和取出的元素顺序一致。
原理:底层数据结构依然是哈希表 ,只是每个键值对元素又额外的多了一个双联表的机制记录存储的顺序。
TreeMap
由键决定特性:不重复、无索引、可排序。
可排序:按照键数据的大小默认升序排序,只能对键排序。
注意:TreeMap集合是一定要排序的,可以默认排序,也可以将键按照指定规则进行排序。
TreeMap跟TreeSet的底层原理是一样的。
集合嵌套
public class Test2 {
public static void main(String[] args) {
//定义一个Map存储
Map<String , List<String >> data=new HashMap<>();
//定义List存储学生的选择
List<String > selects1=new ArrayList<>();
Collections.addAll(selects1,"A","C");
data.put("Damon",selects1);
List<String > selects2=new ArrayList<>();
Collections.addAll(selects2,"A","B","C");
data.put("Stefan",selects2);
List<String > selects3=new ArrayList<>();
Collections.addAll(selects3,"A","B","D");
data.put("Elena",selects3);
Map<String ,Integer> infos=new HashMap<>();
// for (Map.Entry<String, List<String>> stringListEntry : data.entrySet()) {
// for (String s : stringListEntry.getValue()) {
// if (infos.containsKey(s)){
// infos.put(s,infos.get(s)+1);
// }else {
// infos.put(s,1);
// }
// }
// }
Collection<List<String>> values= data.values();
for (List<String> value : values) {
for (String s : value) {
if (infos.containsKey(s)){
infos.put(s,infos.get(s)+1);
}else {
infos.put(s,1);
}
}
}
System.out.println(infos);
}
}