2022-08-06 第八组 卢睿 学习心得
集合
今日重点
- Collection接口
- List
- ArrayList
- LinkedList
- Vector
- Set
- Map
- 集合的遍历
- 迭代器
- 其他的集合
- 面试题
List
数据是有顺序(添加的先后顺序)的,数据是可以重复。
ArrayList:内部结构是数组。比较适合做高频率的查找,遍历。
LinkedList:双向链表。比较适合做高频率的新增和删除。
Vector:和ArrayList几乎一模一样。
面试题:
- Collection和Map接口的区别
- ArrayList和LinkedList的区别
- ArrayList和Vector的区别
public class Ch01 {
public static void main(String[] args) {
// List<String> list = new LinkedList<>();
LinkedList<String> list = new LinkedList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
// 我们在创建对象的时候用的是多态
// 父类对象---子类引用
// 我们创建出来的对象只能够调用父类和子类中都有的方法
list.addFirst("z");
list.addLast("x");
list.removeFirst();
list.removeLast();
// 根据下标索引获取指定位置的元素
System.out.println(list.get(2));
System.out.println(list);
}
}
Collection接口:
List:有顺序,元素可以重复,顺序指的是添加的先后顺序
Set:没有顺序,元素不可以重复,顺序指的是添加的先后顺序
Set其实是有顺序,内部有一个专门排序的算法。
- 所谓的无序不等于随机
- 所谓的无序指的是没有按照添加的先后顺序,其实内部是做了排序的。
面试题:
- List和Set的区别
- HashSet和LinkedHashSet的区别和联系
public class Ch02 {
public static void main(String[] args) {
Set<Integer> set = new HashSet<>();
set.add(Integer.valueOf(200));
set.add(4);
set.add(15);
set.add(38);
set.add(Integer.valueOf(200));
System.out.println(set);
}
}
Set集合如何确保数据的不重复?
保证数据类型的类要重写hashCode和equals方法。
public class Ch03 {
public static void main(String[] args) {
Set<Person> set = new HashSet<>();
set.add(new Person("张三",1001));
set.add(new Person("张三",1001));
set.add(new Person("张三",1001));
set.add(new Person("张三",1001));
// 引用数据类型
// set集合所谓的不能重复,默认情况下比较地址
System.out.println(set);
}
}
TreeSet
排序规则:
要排序的对象的类必须实现Comparable接口
public class Ch04 {
public static void main(String[] args) {
// Set<Integer> tree = new TreeSet<>();
// tree.add(-100);
// tree.add(100);
// tree.add(10);
// tree.add(50);
// Set<String> tree = new TreeSet<>();
// tree.add("1");
// tree.add("a");
// tree.add("哈哈哈哈哈哈");
// tree.add("%");
Set<Person> tree = new TreeSet<>();
tree.add(new Person("张岳",1001));
tree.add(new Person("李四",1010));
tree.add(new Person("费四",1003));
System.out.println(tree);
}
}
LinkedHashSet
在添加数据的同时维护数据的添加顺序,效率要比HashSet略低一些。
public class Ch05 {
public static void main(String[] args) {
LinkedHashSet<String> set = new LinkedHashSet<>();
set.add("1");
set.add("a");
set.add("哈哈哈哈哈哈");
set.add("%");
System.out.println(set);
}
}
比较接口
Comparable接口:自然排序,排序规则是固定。
Comparator接口:临时排序
public class Ch06 {
public static void main(String[] args) {
List<Person> list = new ArrayList<>(16);
list.add(new Person("张岳",1100));
list.add(new Person("李四",1010));
list.add(new Person("刘海柱",1020));
// list.sort(new Comparator<Person>() {
// @Override
// public int compare(Person o1, Person o2) {
// return 0;
// }
// });
list.sort((o1,o2) -> {
if(o1.getId() < o2.getId()){
return -1;
}
if(o1.getId().equals(o2.getId())){
return 0;
}
return 1;
});
System.out.println(list);
}
}
Map接口:
- 存储对值K-V key-value
- key不能重复,value是可以重复的
- 没有顺序(添加的先后顺序)
HashMap内部存储结构
jdk1.7之前:链表 + 数组
jdk1.7及之后:链表 + 数组 + 红黑树
HashMap基本上面试90%问原理!!!
public class Ch07 {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("1001","张岳");
map.put("1002","赵红兵");
map.put("1003","小北京");
map.put("1004","李四");
map.put("1004","张浩然");
map.put("1005","张浩然");
System.out.println(map);
System.out.println(map.get("1003"));
System.out.println(map.values());
System.out.println(map.keySet());
}
}
Hashtable和HashMap几乎一模一样
面试题:
Hashtable和HashMap的区别
1.HashMap是线程异步,线程不安全的,Hashtable是线程同步,线程安全
2.HashMap的key是可以为null的,Hashtable是不可以为null
public class Ch08 {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put(null,null);
System.out.println(map);
Hashtable<String, String> table = new Hashtable<>();
table.put(null,null);
System.out.println(table);
}
}
Properties:属性
Properties是Hashtable的子类,更多地是用来操作属性文件。
List集合的遍历
public class Ch10 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
// 1.for循环
// for (int i = 0; i < list.size(); i++) {
// System.out.println(list.get(i));
// }
// 2.foreach语句
// for (String s : list) {
// System.out.println(s);
// }
// 3.迭代器
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()) {
String s = iterator.next();
iterator.remove();
// System.out.println(s);
}
System.out.println(list);
}
}
遍历
public class Ch11 {
public static void main(String[] args) {
Set<Integer> set = new HashSet<>();
set.add(4);
set.add(15);
set.add(38);
// 2.迭代器
Iterator<Integer> iterator = set.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
// 1.增强for
// for (Integer integer : set) {
// System.out.println(integer);
// }
// for (int i = 0; i < set.size(); i++) {
//
// }
}
}
迭代器
import java.util.*;
public class Ch12 {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("1001","张岳");
map.put("1002","赵红兵");
map.put("1003","小北京");
map.put("1004","李四");
map.put("1005","张浩然");
// 4.迭代器
Set<String> strings = map.keySet();
Iterator<String> iterator = strings.iterator();
while(iterator.hasNext()) {
String s = iterator.next();
System.out.println(s + "->" + map.get(s));
}
// 3.增强for循环
// Entry是hashmap的一个内部类
// 每一组键值对就是一个Entry对象
// Set<Map.Entry<String, String>> entries = map.entrySet();
// for (Map.Entry<String, String> entry : entries) {
// System.out.print(entry.getKey() + "->");
// System.out.println(entry.getValue());
// }
// 2.增强for循环
// Set<String> strings = map.keySet();
// Collection<String> values = map.values();
// 1.for循环
// Set<String> strings = map.keySet();
// for (String s : strings) {
// System.out.println(s + "->" + map.get(s));
// }
}
}
迭代中删除元素
public class Ch13 {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("tom");
names.add("lucy");
names.add("lucy");
names.add("lucy");
names.add("jerry");
// for (int i = 0; i < names.size(); i++) {
// if(Objects.equals(names.get(i),"lucy")){
// names.remove(i);
// // 1.回调指针
// i--;
// }
//// if("lucy".equals(names.get(i))){
////
//// }
// }
// 2.逆序遍历
// for (int i = names.size() - 1; i >= 0; i--) {
// if(Objects.equals(names.get(i),"lucy")){
// names.remove(i);
// }
// }
// 3.使用迭代器(推荐)万无一失
Iterator<String> iterator = names.iterator();
while(iterator.hasNext()) {
String s = iterator.next();
if(Objects.equals(s,"lucy")){
iterator.remove();
}
}
// 4.增强for循环
// for (String s : names) {
// if(Objects.equals(s,"lucy")){
// names.remove(names.indexOf(s));
// }
// }
System.out.println(names);
}
}
其他的集合
- LinkedHashMap,在HashMap的基础上维护了一个双向链表。
- TreeMap:天然支持排序
- Collections:Collections是一个工具类
面试题
线程安全问题:
迭代器是依赖于集合而存在,在判断成功以后,集合中新增了元素,
迭代器不知道,所以就报错。
解决
- 迭代器遍历元素,迭代器删除元素
- 普通for循环遍历,集合删除
public class Ch15 {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("tom");
names.add("lucy");
names.add("lucy");
names.add("lucy");
names.add("jerry");
for (String s : names) {
if(Objects.equals(s,"lucy")){
// names.remove(s);
names.add(s);
}
}
}
}
案例中的Person类
public class Person implements Comparable<Person> {
private String name;
private Integer id;
public Person(String name, Integer id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (!name.equals(person.name)) return false;
return id.equals(person.id);
}
@Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result + id.hashCode();
return result;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", id=" + id +
'}';
}
/*
返回值代表什么?
int
代表排序结果
负数-1:比较的两个值调用者小
0:两个值相等
正数1:比较的两个值调用者大
*/
@Override
public int compareTo(Person p) {
if(this.id > p.id){
return -1;
}
if(this.id.equals(p.id)){
return 0;
}
return 1;
}
}
总结
集合需要掌握的:
1.如何创建需要的集合。多态
2.主要用到的是List和Map
3.各种区别?
4.各种集合API的调用
5.两个比较接口
6.各种集合的特点,从接口层面,到实现类层面
7.重点集合的内部结构。ArrayList,HashSet,HashMap
8.各种集合的遍历
9.并发问题
最重要的集合:
ArrayList、HashMap

浙公网安备 33010602011771号