集合框架
集合的概述
集合(容器)
程序存储数据的方式:
-
变量:单一的 数据
-
数组:一组 具有 相同数据类型 的数据
-
1号问题: 元素的数据类型都是相同的
-
2号问题: 长度不可变
-
-
对象:一组 具有 关联性 的数据(变相解决了数组的1号问题)
存储学生(Student)数据:创建学生对象,存储学生姓名、年龄、身高、体重
存储多个学生数据:Student[]
-
集合:
-
丰富多样的强大的数据存储(Java 给你提供的一大堆 API)
-
集合的体系结构
在 java.util 包(工具)。
接口 Collection: 存储的是 可重复(不唯一)、无序 的数据
-
接口 List:存储的是可重复(不唯一),有序的数据
使用接口要找他们的实现类
-
ArrayList
-
LinkedList
-
....
-
-
接口 Set:存储的是不可重复(唯一),无序的数据
-
HashSet
-
TreeSet
-
....
-
接口 Map: 存储的是键值对(key键-value值,键和值一一对应)数据
-
HashMap
-
HashTable
-
Properties
-
-
TreeMap
-
....
List集合
ArrayList
动态数组。
构造方法:
-
ArrayList<E>()
常用方法:
-
add(E e) : boolean 存储指定类型(E:泛型类型)的元素
-
add(int index, E element) : void 在指定下标位置存储指定类型的元素,原有位置的元素会依次后移
-
remove(int index) : E 删除指定下标位置的元素,返回被删除的元素
-
remove(Object obj) : boolean 删除指定的元素(如果有重复的,只会删除第一个找到的元素)
-
set(int index, E element) : E 修改指定下标位置的元素,返回被替换的元素
-
get(int index) : E 根据下标查询元素
-
size() : int 查询集合中存储的元素数量
-
contains(Object o) : boolean 判断集合中是否存在指定的元素
-
indexOf(Object o) : int 查询指定元素在集合中的下标,找不到会返回 -1
-
lastIndexOf(Object o) : int 从后往前查找指定元素在集合中的下标,找不到会返回-1
注意:从后往前查找,只不过是方向变化,下标还是正向的下标(不会变!)
-
clear() : void 清空集合
-
isEmpty() : boolean 判断集合是否是空的(没有一个元素)
LinkedList
构造方法:
-
LinkedList<E>()
常用方法:
-
addFirst(E e) : void 向前追加元素
-
addLast(E e) : void 向后追加元素
-
removeFirst() : E 删除第一个元素
-
removeLast() : E 删除最后一个元素
-
getFirst() : E 查询第一个元素
-
getLast() : E 查询最后一个元素
-
....
其他方法略,大多和 ArrayList 一致,因为这些方法都是定义在 List 接口中,所以同为 List 接口实现类,当然都会重写相应的方法。
注意:方法名虽然相同,代表的只是方法功能一致,但不代表实现一致!
例如:add()、remove() ....
ArrayList和LinkedList的区别(面试题)
相同点:
-
都是 List 接口的实现类,可以存储可重复的,有序的数据
不同点:
-
ArrayList 底层数据结构是数组结构,在实现数据的查询时,因为数组结构有下标,所以效率较高。但是,在增加或删除数据时,因为数组结构长度不可变,所以会创建一个新的数组,导致效率较低。
它适合于查询较多,增删较少的情况。
-
LinkedList 底层数据结构是链表结构,在增加或删除数据时,尤其是首尾的增删,因为链表结构增加节点或删除节点,只需要修改下一个连接的地址即可,效率较高。但是,在实现数据的查询时,没有下标,只能从首节点依次进行查询,效率较低。
它适合于增删较多,查询较少的情况。
Set集合
HashSet
构造方法:
-
HashSet<E>()
常用方法:
-
add(E e) : boolean 存储元素(去重数据)
-
remove(E e) : E 删除数据
-
size() : int 获取集合的元素数量
-
contains(Object o) : boolean 判断是否包含指定的元素
-
...
因为 Set 和 List 都是继承自 Collection 接口,所以很多方法也是相同的。
注意: 如果用 Set 存储引用数据类型数据,需要重写相应类的 equals 和 hashCode 方法。不然,不认为是重复数据,不会去重。
集合的遍历
List集合遍历
-
循环下标实现
例如:遍历新闻数据
for (int i = 0; i < list.size(); i++) { News news = list.get(i); System.out.println(news); }
-
增强 for 实现
例如:遍历新闻数据
for (News news : list) { System.out.println(news); }
-
迭代器
// 迭代器:Iterator // iterator() : Iterator<E> Iterator<News> iterator = list.iterator(); // hasNext() : boolean 判断是否还有下一个元素 // next() : E 取出下一个元素 // if (iterator.hasNext()) { // News next = iterator.next(); // System.out.println(next); // } while (iterator.hasNext()) { News next = iterator.next(); System.out.println(next); }
Set集合遍历
-
增强 for 实现
for (News news : newsSet) { System.out.println(news); }
-
迭代器
Iterator<News> iterator = newsSet.iterator(); while (iterator.hasNext()) { News next = iterator.next(); System.out.println(next); }
泛型
泛型:给集合限制元素的类型。
泛型是在 JDK 1.5 出现的特性。
它可以有效解决类型转换问题。
泛型都可以用在:
-
类上
// 集合 public class ArrayList<E> { } // 在创建集合对象时,只要指定了 E 的具体类型,那么 add 方法的参数或返回值也就指定了对应的类型 public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } public E remove(int index) { }
-
方法上
// Arrays类的方法 // 在调用该方法时,传入什么类型数据,返回的就是什么类型的数据 public static <T> List<T> asList(T... a) { return new ArrayList<>(a); }
在方法参数中出现了
...
,它被称为可变参数,比较灵活。它意味着,你传递多少个指定类型的参数都可以,0个,1个,2个....
可以把它在处理时看作是一个数组来处理。
public class Demo03 { public static void main(String[] args) { // printNames(); printNames("张三", "李四", "王五"); } public static void printNames(String... names) { for (String name : names) { System.out.println(name); } } }
-
泛型还可以限制类型必须是某个类型的子类
<? extends 类型>
泛型使用任何符号代表都可以。这些符号就是一个某种类型的表示。
常见的符号:
E(Element,元素)
T(Type,类型)
K(Key,键)
V(Value,值)
....
泛型在指定具体类型时,必须是引用数据类型。
-
String
Java给基本类型都准备了相应的引用类型(基本类型相应的包装类型)
-
byte -> Byte
-
short -> Short
-
int -> Integer
-
long -> Long
-
float -> Float
-
double -> Double
-
char -> Character
-
boolean -> Boolean
关于包装类型,后续再分解。
Map集合概述
Map 集合是一种键值对数据的存储方案。
key-value,其中 key 是唯一的 ,而 value 是可以重复的。
Map 是无序存储(Hash)。
Map集合使用
-
HashMap
-
HashTable
-
Properties
-
-
TreeMap
构造方法:
-
HashMap<K, V>()
常用方法:
-
put(K key, V value) : V 存储/更新(相同键再次调用该方法)键值对数据,返回被替换的值(如果是存储,那么返回的是 null)
-
get(Object key) : V 根据键获取值
-
size() : int 获取集合中存储的键值对数量
-
containsKey(Object key) : boolean 判断集合中是否包含指定的键
-
containsValue(Object value) : boolean 判断集合中是否包含指定的值
-
remove(Object key) : V 根据键删除,返回的是被删除的值
-
keySet() : Set<K> 获取所有键的集合(键是唯一的,所以是Set集合)
-
entrySet() : Set<Entry<K, V>> 获取所有键值对的集合
-
Entry:
-
getKey() : K 获取 Entry 中的键
-
getValue() : V 获取 Entry 中的值
-
-
-
values() : Collection<V> 获取所有值的集合(Map存储,值是无序的,但是可重复,所以是Collection集合)
-
clear() : void 清空集合中的键值对
-
...
Map集合的遍历
-
获取所有的键,遍历键根据键获取值
Set<String> keySet = map.keySet(); for (String key : keySet) { String value = map.get(key); System.out.println(key + "=" + value); }
-
获取所有键值对,遍历键值对,从中获取键和值
Set<Entry<String,String>> entrySet = map.entrySet(); for (Entry<String, String> entry : entrySet) { String key = entry.getKey(); String value = entry.getValue(); System.out.println(key + "=" + value); }
-
forEach方法(1.8)
map.forEach((key, value) -> { System.out.println(key + "=" + value); });
Collections工具类
Arrays。
Collection 和 Collections 的区别?(面试题)
-
Collection 是一个集合的顶级接口,用于存储可重复的,无序的数据
-
Collections 是一个集合的工具类,里面定义了大量的静态方法,用于更为便捷的操作集合
常用方法:
-
sort(List<T> list) : void 可以实现对集合的升序排序
-
min(Collection<? extends T> coll) : T 获取集合中的最小值
-
max(Collection<? extends T> coll) : T 获取集合中的最大值
-
reverse(List<?> list) : void 反转集合元素
-
shuffle(List<?> list) : void 打乱集合元素
ArrayList的扩容原理(面试题)
默认仅仅创建集合对象,不存储: 内部的数组会初始化为一个静态常量(空数组)
默认的初始化容量: 10(长度为10的数组)
进行扩容时,每次扩容: 1.5 倍
集合初始化时, 指定集合初始值大小:
如果确定集合要存储的元素个数,那么 ArrayList 在创建对象时,建议指定 initialCapacity 为你要存储的元素个数。
ArrayList<Integer> list = new ArrayList<>(3);
HashMap 使用 HashMap(int initialCapacity) 初始化,如果暂时无法确定集合大小, 那么指定默认值( 16) 即可。 正例: initialCapacity = (需要存储的元素个数 / 负载因子) + 1 。 注意负载因子(即 loader factor) 默认 为 0.75,如果暂时无法确定初始值大小,请设置为 16(即默认值) 。
HashMap<String, String> map = new HashMap<>(16);
参见阿里巴巴开发手册要求。
第三方的工具:Hutool
概述
Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。
Hutool中的工具方法来自每个用户的精雕细琢,它涵盖了Java开发底层代码中的方方面面,它既是大型项目开发中解决小问题的利器,也是小型项目中的效率担当;
Hutool的设计思想是尽量减少重复的定义,让项目中的util这个package尽量少,总的来说有如下的几个思想:
方法优先于对象
自动识别优于用户定义
便捷性与灵活性并存
适配与兼容
可选依赖原则
无侵入原则
安装(导入jar包)
-
下载 jar 包
hutool-all
-
在项目中新建一个目录:lib
-
拷贝 jar 包到 lib 目录
-
右键 jar 包 -> Build Path -> add to build path
-
在项目中会出现一个 Referenced Libraries 关联库
使用
集合工具类:
-
CollectionUtil
-
newArrayList(T... values) : ArrayList<T> 快速创建一个指定容量的集合
-
join(Iterable<T> iterable, CharSequence conjunction) : String 将集合中的元素通过指定字符拼接为字符串
-
union(Collection<T> coll1, Collection<T> coll2) : Collection<T> 取两个集合的并集
-
....
-
-
MapUtil
-
newHashMap(int size) : HashMap<K, V> 快速创建一个指定容量的Map集合(它会自动帮我们算好初始化容量)
-
...
-
随机数工具类:
-
RandomUtil
-
randomInt(int min, int max) : int 生成 [min, max) 范围的随机整数
-
randomNumbers(int length) : String 生成指定长度的随机字符串(整数)
-
...
-
字符串工具类:
-
StrUtil
-
format(CharSequence template, Object... params) : String
String format2 = StrUtil.format("我的姓名:{},我的年龄:{},我的余额:{}", name, age, money); System.out.println(format2);
-
isNotEmpty(CharSequence str) : boolean 判断字符串是否不为空(null、""空字符串)
-
....
-
....