JAVA--Java 集合框架
集合 & 数组
- 集合由来:数组是定长的,集合是可变长度的
- 集合与数组:
- 数组既可以存储 基本数据类型,亦可以存储引用数据类型(Student类类型)(基本数据类型存储的是值,引用数据类型存储的是地址值);集合只能存储引用类型(集合中也可以存储基本数据类型,但是在存储时会自动装箱,变成对象: 100 ---> new Integer(100))
- 数组定长;集合可变长
- 元素个数固定--数组;元素个数不固定--集合
1.Collection(单列集合的根接口)
1.1. List
有序;
存取顺序一致;
有索引;
元素可重复
Array List & LinkedList 都是List;前面部分表示底层是使用什么来实现的。
泛型: Collection
c = new ArrayList (); // 表示c集合只能存储String类型的元素
1.1.1 ArrayList
| 方法名 | 描述 |
|---|---|
| add() | 添加元素,返回值为布尔类型,List的add()方法返回值 为true |
| remove(index/元素) | 删除index处元素(list.remove(1)) 或者 删除指定元素(list.remove("a")) |
| clean() | 清空集合 |
| contains() | 判断是否包含某个元素,返回布尔值 |
| toArray() | 转数组 |
| addAll() | 参数为 集合 |
| removeAll() | |
| containsAll() | |
| retainAll() | 取交集 |
| iterator() | 迭代器 |
**数组转集合 ** asList()
String[] arr = {"a","b","c"};
List<String> list = Arrays.asList(arr); // <String> -- 可省略
//list.add("d"); // 数组转的集合 不能添加和删除元素 ,但可以使用集合的其他方法
int[] arr = {1,2,3};
List list = Arrays.asList(arr); // 此处的泛型要写 <int[]>,因为集合中存储的引用类型 是 数组类型,理由见下
System.out.println(list); // [[I@140e19d] 集合中只能存储 引用类型, 数组中元素是 基本类型,所以将整个数组 堪称一个对象保存到 集合中, 因此输出 数组的地址
// 基本数据类型的数组转换为集合
Integer[] arr2 = {11,22,33};
List<Integer> list1 = Arrays.asList(arr2);
System.out.println(list1); // [11, 22, 33]
集合转数组 (带泛型)
Object[] arr = list.toArray();
System.out.println(Arrays.toString(arr)); // [a, b, c]
/* 集合转换数组时,
* 数组长度 <= 集合的size时,转换后的数组长度 == 集合的 size
* 数组长度 > 集合的size时,转换后的数组长度 为设置的值 */
String[] arr2 = list.toArray(new String[5]); // 数字代表数组长度,
System.out.println(Arrays.toString(arr2)); // [a, b, c, null, null]
List 方法
-
add 方法:
/* add()方法,如果是List集合,则一直返回true,因为list集合可以重复 如果是set集合,添加非重复元素时true, 重复元素时 false * */ Collection c = new ArrayList(); // 父类引用指向子类对象 //Collection<String> c = new ArrayList<String>(); // 表示c集合只能存储String类型的元素 boolean b1 = c.add("abc"); // 添加引用类型 boolean b2 = c.add(true); // 添加基本数据类型。自动装箱 new Boolean(true) boolean b3 = c.add(100); // 添加基本数据类型。自动装箱 new Integer(100) c.add(300); System.out.println(c); // [abc, true, 100,300] -
remove()
c.remove(100)
- clean(); 清空集合
- contains()
c.contains(100); // 返回布尔值
- toArray() -- 转数组
Object[] arr = c.toArray();
System.out.println(Arrays.toString(arr)); // [true, 100, 300]
-
addAll(), removeAll(), containsAll(), retainAll() --- 参数为集合
- retainAll() 取交集
// c1:[a,b,c,abc] // c2:[a,b,c] boolean bb = c1.retainAll(c2); System.out.println(bb); // 将c1 c2的交集赋值给c1. 如果c1与之前相比有变化,bb为true, 反之为 false -
迭代遍历 iterator()
Collection c = new ArrayList(); // 父类引用指向子类对象 boolean b1 = c.add("abc"); // 添加引用类型 boolean b2 = c.add(100); // 添加基本数据类型。自动装箱 new Boolean(true) boolean b3 = c.add("b"); // 添加基本数据类型。自动装箱 new Integer(100) Iterator it = c.iterator(); // 获取迭代器 while (it.hasNext()){ System.out.println(it.next()); } -
List 特有方法:
- add("a"), add(1,"b") --> index处添加元素
- remove(1) --> 删除index处的元素
- get(index) -- > 获取index处的元素,可以用来遍历
- set(1, "z") -->修改iindex处的元素
1.1.2 LinkedList
- LinkedList特有方法:
| 方法名 | 描述 |
|---|---|
| addFirst() | 链表头插 |
| addLast() | 链表尾插 |
| getFirst() | |
| getLast() | |
| removeFirst() | |
| removeLast() | |
| get(index) |
1.2. Set
无序;
存取顺序不一致;
无索引;
不可重复
Set 的方法与 List相同,主要学习 Set 如何保证 元素不重复
1.2.1 HashSet
| 方法名 | 描述 |
|---|---|
| add() | 返回值为布尔类型,添加非重复元素,返回true,否则 返回false |
HashSet<Person> hs = new HashSet<>();
hs.add(new Person("张三",23));
hs.add(new Person("张三",23));
hs.add(new Person("李四",24));
hs.add(new Person("李四",24));
// 在Person类中 重写 hashCode() 和 equals()之前
System.out.println(hs); //[Person{name='张三', age=23}, Person{name='李四', age=24}, Person{name='张三', age=23}, Person{name='李四', age=24}]
// 在Person类中 重写 hashCode() 和 equals()之后
System.out.println(hs); //[Person{name='张三', age=23}, Person{name='李四', age=24}]
当HashSet调用add()方法存储对象时,先调用对象的hashCode()方法得到一个哈希 值,然后在集合中查找是否有哈希值相同的对象,
如果没有,直接存入集合
如果有,就和哈希值相同的对象挨个进行equals()比较,比较结果为false,则存入集合
将自定义类的对象存入HashSet时,类中必须重写hashCode()和equals()方法。
1.2.2 TreeSet
TreeSet集合是用来对元素进行排序的, 同时保证元素的唯一性
2.Map
- 键值对
- 一个映射不能包含重复的键,键唯一
- 每个键最多只能映射到一个值
| 方法 | 描述 |
|---|---|
| put() | 添加元素 , 键值不重复,直接添加,键值重复,更新值。把被覆盖的值返回,类型为值的类型 |
| clear() | 移除所有 键值对 |
| remove() | 根据键删除值,并返回 值 |
| boolean containsKey() | 判断集合是否包含指定的键 |
| boolean containsValue() | 判断集合是否包含指定的值 |
| boolean isEmpty() | 判断集合是否为空 |
| values() | 获取所有值的集合 |
map集合的遍历
map接口没有Iterator()方法,不能使用迭代器遍历。但是可以获取键的集合,键的 集合有iterator()方法,可以使用迭代器遍历。
HashMap<String, Integer> map = new HashMap<>();
map.put("张三",23);
map.put("李四",24);
map.put("王五",25);
map.put("赵六",26);
int v = map.get("张三"); // 根据键 获取值
System.out.println(v);
// 获取所有的键
Set<String> keySet = map.keySet();
Iterator<String> it = keySet.iterator();
while(it.hasNext()){
String key = it.next();
System.out.println(map.get(key));
}
// foreach 遍历
for (String key : map.keySet()) {
System.out.println(map.get(key));
}
法二:
// Map.Entry<>, 说明Entry是Map的内部接口(接口内的接口),将键和值 封装成了Entry对象,并存储在Set集合中。
Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
// 获取每一个对象
Iterator<Map.Entry<String, Integer>> it = entrySet.iterator();
while (it.hasNext()){
// 获取每一个 Entry 对象
Map.Entry<String, Integer> en = it.next();
String key = en.getKey();
int value = en.getValue();
System.out.println(key+"=="+value);
}
// foreach
for(Map.Entry<String, Integer> en : map.entrySet()){
System.out.println(en.getKey()+"---"+en.getValue());
}
计算字符串中每个字符的个数
String str = "aaacccccbbbb";
char[] arr = str.toCharArray();
HashMap<Character,Integer> map = new HashMap<>();
for(char c : arr){
/*if(!map.containsKey(c)){
map.put(c,1);
}else {
map.put(c, map.get(c)+1);
}*/
map.put(c, !map.containsKey(c) ? 1 : map.get(c)+1);
}
for(Character key : map.keySet()){
System.out.println(key + "---"+map.get(key));
}
HashMap & Hashtable 的区别
- 共同点: 底层都是 哈希 算法, 都是 双列集合
- 区别
- hashMap是线程不安全的,效率高 ; Hashtable线程安全,效率低
- HashMap可以 存储null键 和null 值; HashTable不可以
3.可变参数
- 可变参数实际是一个数组
- 如果一个方法有可变参数, 并且有多个参数, 可变参数肯定是最后一个
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
print(arr);
print(11,22,33);
}
public static void print(int ... arr){ // 可变参数实际上就是 一个数组
for (int i : arr) {
System.out.println(i);
}
}
ArrayList 嵌套


浙公网安备 33010602011771号