Java集合概述
前言
Java集合类存放于java.util包中,是一个用来存放对象的容器
- 集合只能用来存放对象。
- 集合存放的是多个对象的引用,对象本身还是放在堆内存中。
- 集合可以存放不同类型、不限数量的数据类型。
Java集合可分为Set、List、Map三大体系。
Set:无序、不可重复的集合
List:有序,可重复的集合
Map:具有映射关系的集合
1 Set
1.1 HashSet
HashSet按照Hash算法来存储集合中的元素,因此具有很好的存取和查找性能。
HashSet特点:
- 不能保证元素的排列顺序
- 不可重复 --> hashCode不相同
- HashSet不是线程安全的
- 集合元素可以使用null
排列顺序的解释:当向HashSet集合存入一个元素时,会调用该对象的hashCode()方法来得到该对象的hashCode值,根据hashCode值决定该对象在集合中存储位置。
HashSet类 --实现–> set接口 --继承–> Collection接口
基本操作:
创建HashSet: Set set = new HashSet();
-
增、删、判断、清空;
-
add()、remove()、contains()、clear();
package com.set; import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class HashSetDemo01 { public static void main(String[] args) { Set set = new HashSet();// <=>Set<Object> set = new HashSet<Object>(); set.add(1);//添加元素 set.add("a"); System.out.println(set); set.remove(1); //移除元素 System.out.println(set); System.out.println(set.contains(1));//判断是否存在 set.clear(); //清空集合 System.out.println(set); } } //运行结果 //[1, a] //[a] //false //[]
-
遍历(迭代器遍历 / for each迭代集合)
package com.set; import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class HashSetDemo01 { public static void main(String[] args) { Set set = new HashSet();// <=>Set<Object> set = new HashSet<Object>(); set.add("a"); set.add("b"); set.add("c"); set.add("d"); set.add("d"); //set集合并未发生改变,说明set存的值是不重复的 set.add(null); //set可以存null --> 存后发现null位于首位,故hashSet无顺序 System.out.println(set); //使用迭代器遍历集合 Iterator it = set.iterator(); while (it.hasNext()){ System.out.println(it.next()); } //for each迭代集合(推荐!) for (Object obj : set){ //将set每一个值取出赋值给obj System.out.println(obj); } System.out.println(set.size()); //获取集合个数 } } /*运行结果 [null, a, b, c, d] null a b c d null a b c d 5 */
-
泛型的引入
-
Set set1 = new HashSet();
package com.set; import java.util.HashSet; import java.util.Set; public class HashSetDemo01 { public static void main(String[] args) { //如果想让集合只存同样类型的对象,需要使用泛型 Set<String> set1 = new HashSet<String>(); set1.add("abc"); //set1.add(true); //非String对象不能存入 System.out.println(set1); } } //运行结果: //[abc]
1.2 TreeSet
TreeSet是SortedSet接口的实现类,TreeSet可以确保集合元素处于排序状态。
TreeSet支持两种排序方法:自然排序(默认)和定制排序。
1.2.1 自然排序
TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间的大小关系,然后将集合元素按升序排列
- 如果this > obj,返回1
- 如果this < obj,返回-1
- 如果this = obj,返回0
- 必须放入同样类的对象(可使用泛型来限制),否则会出现类型转换异常
自然排序案例:
基本操作与HashSet中一致,遍历操作也相同,故直接给出:
package com.set;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
public class TreeSetDemo01 {
public static void main(String[] args) {
Set<Integer> set = new TreeSet<Integer>();
//TreeSet 自然排序
set.add(5);
set.add(2);
set.add(4);
set.add(3);
System.out.println(set);
set.remove(5);
System.out.println(set.contains(3));
// set.clear();
//遍历同上
//迭代器遍历
Iterator<Integer> it = set.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//for-each遍历
for (Integer i : set){
System.out.println(i);
}
}
}
/*运行结果:
[2, 3, 4, 5]
true
2
3
4
2
3
4
*/
1.2.2 定制排序
TreeSet中存放自己定义的类对象,现需按照自己想要的方式进行排序,需使用定制排序。
实现方法:
- 创建自己的类并实现Comparator<Person>接口,例如Person类,内含name,age属性。
- 在Person类中创建无参构造器+有参构造器。
- Person类中重写compare方法,传入两对象,按照age比较并返回1、-1、0。
TreeSet创建使用:Set<Person> set = new TreeSet<Person>(new Person());
定制排序案例:
package com.set;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
public class TreeSetDemo02 {
public static void main(String[] args) {
Person p1 = new Person("张三", 23);
Person p2 = new Person("里斯", 25);
Person p3 = new Person("王武", 20);
Person p4 = new Person("Lucy", 19);
Set<Person> set = new TreeSet<Person>(new Person());
set.add(p1);
set.add(p2);
set.add(p3);
set.add(p4);
for (Person p : set){
System.out.println(p.name + " "+ p.age);
}
}
}
class Person implements Comparator<Person> { //将person对象存入TreeSet中,并按照年龄排序
int age;
String name;
//无参构造器
public Person(){
}
//有参构造器
public Person(String name, int age){
this.name = name;
this.age = age;
}
@Override
public int compare(Person o1, Person o2) { //年龄正序排列
if (o1.age > o2.age) {
return 1;
} else if (o1.age < o2.age) {
return -1;
} else {
return 0;
}
}
}
//运行结果:
//Lucy 19
//王武 20
//张三 23
//里斯 25
2 List
List代表一个元素有序、且可重复的集合,集合中的每个元素都有其对应的顺序索引。
List对象创建:List<String> list = new ArrayList<String>();
ArrayList和Vector是List接口的两个典型实现,区别:
- Vector是一个古老的集合,通常建议ArrayList。
- ArrayList是线程不安全的,Vector是线程安全的。
常用操作:
函数名称 | 函数功能 |
---|---|
add() | 1)添加元素 2指定位置添加元素 |
addAll() | 指定位置添加另一集合中所有元素 |
remove() | 删除元素(可根据索引也可根据元素名称) |
set() | 更改指定位置元素 |
get() | 根据索引取出指定位置元素 |
indexOf() | 获取指定元素在集合中第一次出现的索引下标 |
lastIndexOf() | 获取指定元素在集合中最后一次出现的索引下标 |
sublist() | 截取list集合,返回新的list集合(左闭右开) |
size() | 返回列表元素个数 |
案例展示:
package com.list;
import java.util.ArrayList;
import java.util.List;
public class ListDemo01 {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("a"); //索引为0
list.add("c"); //索引为1
list.add("c"); //索引为2
list.add("d"); //索引为3
list.add("d"); //允许使用重复元素
System.out.println(list);
list.add(1,"b"); //在指定位置插入数据,其后数据均往后移动
System.out.println(list);
List<String> l = new ArrayList<String>();
l.add("123");
l.add("efg");
list.addAll(0,l); //在指定索引下标位置插入集合
System.out.println(list);
list.remove(4); //根据指定索引下标移除数据
System.out.println(list);
list.set(1,"456"); //根据指定索引下标修改元素
System.out.println(list);
System.out.println(list.get(2)); //取出指定位置元素
System.out.println(list);
System.out.println(list.indexOf("d")); //获取指定元素在集合中第一次出现的索引下标
System.out.println(list.lastIndexOf("d")); //获取指定元素在集合中最后一次出现的索引下标
List<String> sublist = list.subList(2,5); //取出索引下标为[2,5)的元素,注意左闭右开
System.out.println(sublist);
System.out.println(sublist.size());
}
}
/*运行结果:
[a, c, c, d, d]
[a, b, c, c, d, d]
[123, efg, a, b, c, c, d, d]
[123, efg, a, b, c, d, d]
[123, 456, a, b, c, d, d]
a
[123, 456, a, b, c, d, d]
5
6
[a, b, c]
3
*/
3 Map
Map用来保存具有映射关系的数据,因此Map集合里保存两组值,一组值保存Key,另外一组保存Value。
(这里的Map有点类似于python中的字典)
Key不允许重复,且Key与Value存在一对一关系。
3.1 HashMap
常用操作:
函数名称 | 函数功能 |
---|---|
put() | 添加数据 |
get() | 根据key取值 |
remove() | 根据key移除键值对 |
size() | 返回键值对个数 |
containsKey() | 判断map集合中是否包含指定的key |
containsValue() | 判断map集合中是否包含指定的value |
clear() | 清空map集合 |
map.keySet() | 获取map集合中key的集合 |
map.values() | 获取map集合中所有values值 (返回HashMap$Values类型数据) |
基本操作案例:
package com.map;
import java.util.*;
public class MapDemo01 {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("a",1); //添加数据
map.put("c",2);
map.put("e",2);
map.put("f",2);
System.out.println(map);
System.out.println(map.get("c")); //根据key取值
map.remove("c"); //根据key移除键值对
System.out.println(map);
System.out.println(map.size()); //map集合长度
System.out.println(map.containsKey("c")); //判断map集合中是否包含指定的key
System.out.println(map.containsValue(1)); //判断map集合中是否包含指定的Value
map.values(); //获取map集合的所有Value值
System.out.println(map.values().getClass().getName()); //查看返回类型
map.clear();//清空
}
}
/*运行结果:
{a=1, c=2, e=2, f=2}
2
{a=1, e=2, f=2}
3
false
true
java.util.HashMap$Values
*/
遍历操作案例:
两种方式:1、map.keySet() 2、map.entrySet()(推荐使用!)
package com.map;
import java.util.*;
public class MapDemo01 {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("a",1); //添加数据
map.put("e",2);
map.put("f",2);
System.out.println(map);
//遍历map集合,通过map.keySet();
Set<String> keys = map.keySet(); //获取map集合的key的集合
for (String key : keys) {
System.out.println("key: " + key + ", value: " + map.get(key));
}
//通过map.entrySet();(性能更优,推荐使用)
Set<Map.Entry<String,Integer>> entrys = map.entrySet(); //Map.Entry表示映射关系,map.entrySet()返回包含该关系的Set视图
for (Map.Entry<String, Integer> en : entrys){
System.out.println("key: " + en.getKey()+", value: "+ en.getValue());
}
}
}
/*运行结果:
key: a, value: 1
key: e, value: 2
key: f, value: 2
key: a, value: 1
key: e, value: 2
key: f, value: 2
*/
3.2 TreeMap
TreeMap也支持两种排序方法:自然排序与定制排序(与TreeSet类似)
此处仅展示自然排序的使用,定制排序可仿照TreeSet编写。
- 案例展示:
package com.map;
import java.util.Map;
import java.util.TreeMap;
public class MapDemo02 {
public static void main(String[] args) {
Map<Integer, String> map = new TreeMap<Integer, String>();
map.put(4,"a");
map.put(3,"b");
map.put(5,"b");
map.put(2,"e");
System.out.println(map);
//自然排序使用的是英文字典顺序排序,且数字在字母之前
Map<String, String> map1 = new TreeMap<String, String>();
map1.put("a","b");
map1.put("c","d");
map1.put("b","e");
map1.put("d","f");
map1.put("ab","ab");
map1.put("1","11");
map1.put("12","12");
map1.put("2","2");
System.out.println(map1);
}
}
/*运行结果:
{2=e, 3=b, 4=a, 5=b}
{1=11, 12=12, 2=2, a=b, ab=ab, b=e, c=d, d=f}
*/
注:TreeMap自然排序<String排序>使用的是英文字典顺序,且数字在字母之前!
写在最后
因为苦涩,才去品尝,因为感动,才去深爱。
To Demut and Dottie!