Collection
Collection
是其子集的父类,所以可以使用多态的规矩,比如:创建一个 ArrayList
对象,用 Collection
接收
Collection<Integer> collection = new ArrayList<>();
注意:Collection
为接口,不能直接创建对象,但可以利用其子类,使用 Collection
方法,就如上方代码一样
Collection 方法基本使用
Collection<Integer> collection = new ArrayList<>();
collection.add(1); // 添加一个数据
ollection.add(2);
System.out.println(collection); // [1, 2]
collection.clear(); // 清空集合中的所有值
System.out.println(collection); // []
collection.add(1);
collection.add(2);
collection.remove(2); // 删除值为 2 的数据
System.out.println(collection); // [1]
boolean contains = collection.contains(1); // 是否包含值为 1 的数据
System.out.println(contains); // true
boolean empty = collection.isEmpty(); // 验证是否为空
System.out.println(empty); // false
int size = collection.size(); // 集合长度
System.out.println(size); // 1
注意:
add
方法是有一个返回值为boolean
,List系列始终为true
,Set
系列由于不能添加重复数据,可能为false
contains
方法如果查询是否包含某个对象,比如Student
类的对象,contains
默认对比的是地址值,若要对比的是数据,需要重写Student
类的equals
方法
Collection 遍历
Intrator 迭代器遍历
可以把 Intrator
看作一个箭头,默认指向第 0 索引,调用一次 next()
,箭头就会向后移动一位。
- 如果后一位没有值,还要强行
next()
访问,就会报异常 hasNext()
方法,判断是否有下一个元素值- 迭代器遍历期间,不能使用添加删除等改变集合的方法
Collection<String> collection = new ArrayList<>();
collection.add("a");
collection.add("b");
collection.add("c");
collection.add("d");
Iterator<String> iterator = collection.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next()); // a
System.out.println(iterator.next()); // b
System.out.println(iterator.next()); // c
System.out.println(iterator.next()); // d
System.out.println(iterator.next()); // 如果 next 已经没有值,强行访问会报异常 NoSuchElementException
}
增强 for 遍历
List
系列和数组可以使用,快捷键 对象名.for
Lambda 表达式遍历
和 js 的 forEach 相似,不过 java 中的 forEach
没有第二个参数 i
collection.forEach(v->{
System.out.println(v);
});
List
Collection
是 List
的父类接口,而 List
又是 ArrayList
的父类接口,其用法和 Collection
差不多,
迭代器,增强 for,lambda 都可以用
LikedList
双向链表:查询慢,守卫操作增删改的速度极快
泛型
基本写法
和 TS 中的泛型类似
泛型类
泛型方法
泛型接口:和泛型类的用法相似
泛型通配符和泛型类型约束
?
表示不确定的类型,可以不传泛型
extends E
表示可以传入的泛型为 E 类以及基于 E 的子类
super E
表示可以传入的泛型为 E 类以及其所有的父类,和extends
刚好相反
Set
Set 不能使用 for 循环遍历,无序也就不能通过索引获取元素
Set 的 API 和 Collection 基本保持一致
- HashSet:无序、不重复、无索引
- LinkedHashSet:有序、不重复、无索引
- TreeSet:可排序、不重复、无索引
HashSet
HashSet 基本使用
由图上结果可知,重复的对象并未被添加到 HashSet
中,因为重写了 hashCode
方法,两个相同对象值拥有相同的 hashCode,如果不重写 hashCode
,对象值一样也不会重复。
LinkedHashSet
当需要存有序数据的时候用 LinkedHashSet
TreeSet
对于数值类型:整数和小数,默认都采用从小到大排序
对于字符和字符串:默认采用 ASCII 码表中的字母代表的数字进行排序
复杂类型排序
比如对 Person
类创建的对象排序,如果直接向 TreeSet
中添加对象,则会报错,因为 TreeSet
无法识别对象的默认排序规则
解决方法一:对指定的 javabean 类实现 Comparable
接口,制定排序规则
解决方法二:在创建 TreeSet
对象的时候直接通过 Comparator
指定排序规则
当然,该代码也可以简写为 Lambda
格式
应用场景中,
ArrayList
使用最多,涉及到去重,HashSet
使用最多
Map
Map
是一个接口,所以也不能直接 new 创建 Map
对象,需要利用多态,间接使用 Map
的方法
Map
的使用和 js 中的 map
相似
Map<String, String> map = new HashMap<>();
map.put("张三", "男");
map.put("李四", "女");
map.put("王五", "人妖");
System.out.println("put: " + map); // {李四=女, 张三=男, 王五=人妖}
map.remove("王五");
System.out.println("remove: " + map); // {李四=女, 张三=男}
map.clear();
System.out.println("clear: " + map); // {}
map.put("张三", "男");
map.put("李四", "女");
map.put("王五", "人妖");
boolean containsKey = map.containsKey("张"); // containsKey 是精确匹配
System.out.println("containsKey: " + containsKey); //false
boolean containsValue = map.containsValue("男");
System.out.println("containsValue: " + containsValue); // true
boolean empty = map.isEmpty();
System.out.println("isEmpty: " + empty); // false
int size = map.size();
System.out.println("size: " + size); // 3
Map
的get
方法就是根据键获取对应的值
Map 遍历
keySet
通过 keySet
方法获取到 Map
对象的键的集合,类似 js 中的 Object.keys
,然后可以通过键找值
Map<String, String> map = new HashMap<>();
map.put("张三", "男");
map.put("李四", "女");
map.put("王五", "人妖");
Set<String> strings = map.keySet();
strings.forEach(s -> System.out.println(s)); // 循环三次,分别打印 李四 张三 王五
entrySet
entrySet
会生成一个键值对数组(Entry
数组),然后遍历数组,从每一个键值对(Entry
)上调用 getKey
方法获取键,getValue
方法获取值
Map<String, String> map = new HashMap<>();
map.put("张三", "男");
map.put("李四", "女");
map.put("王五", "人妖");
Set<Map.Entry<String, String>> entries = map.entrySet();
entries.forEach(entry -> {
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + "=" + value);
// 李四=女
// 张三=男
// 王五=人妖
});
BiConsumer和Lambda简写
# HashMap
HashMap
是基于 Map
的实现类,和 Map
的用法一样。
依赖 hashCode
和 equals
保证 键的唯一
键如果是自定义对象,需要重写 hashCode
和 equals
来保证唯一的键
LinkedHashMap
与 Map
不同的是:存储的 Map 是是有序的
- 正常存储
Map
是无序的 LinkedHashMap
就是在Map
的基础上增加了有序的功能
TreeMap
和 TreeSet
用法基本一致
可变参数
可变参数本质就是一个数组,可以在形参中接收多个不固定参数,和 js 中的 args
是一个效果