Java 集合可分为 Collection 和 Map 两大体系
单列数据集合
双列数据集合
集合框架全图

Collection接口继承树

Map接口继承树

Collection 接口是 List和Set接口的父接口,该接口里定义的方法既可用于操作 Set 集合,也可用于操作 List 集合add(E obj):添加元素对象到当前集合中addAll(Collection other):添加other集合中的所有元素对象到当前集合中@Test
public void test1(){
Collection coll = new ArrayList();
//add()
coll.add("AA");
coll.add(123);//自动装箱
coll.add("么么哒");
System.out.println(coll); // [AA, 123, 么么哒]
//addAll(Collection other)
Collection coll1 = new ArrayList();
coll1.add("BB");
coll1.add(456);
coll.addAll(coll1);
System.out.println(coll); // [AA, 123, 么么哒, BB, 456]
coll.add(coll1);
System.out.println(coll); // [AA, 123, 么么哒, BB, 456, [BB, 456]]
}
int size():获取当前集合中实际存储的元素个数boolean isEmpty():判断当前集合是否为空集合boolean contains(Object obj):判断当前集合中是否存在一个与obj对象equals返回true的元素boolean containsAll(Collection coll):判断coll集合中的元素是否在当前集合中都存在。即coll集合是否是当前集合的“子集”boolean equals(Object obj):判断当前集合与obj是否相等void clear():清空集合元素boolean remove(Object obj) :从当前集合中删除第一个找到的与obj对象equals返回true的元素boolean removeAll(Collection coll):从当前集合中删除所有与coll集合中相同的元素Object[] toArray():返回包含当前集合中所有元素的数组hashCode():获取集合对象的哈希值iterator():返回迭代器对象,用于集合遍历@Test
public void test2(){
Collection coll = new ArrayList();
coll.add("AA");
coll.add("AA");
Person p1 = new Person("Tom",12);
coll.add(p1);
coll.add(128);//自动装箱
//集合 ---> 数组
Object[] arr = coll.toArray();
System.out.println(Arrays.toString(arr)); // [AA, AA, Person{name='Tom', age=12}, 128]
//hashCode():
System.out.println(coll.hashCode()); // -912175978
}
java.util.Iterator遍历集合中的所有元素
存储元素Iterator,被称为迭代器接口,本身并不提供存储对象的能力,主要用于遍历Collection中的元素public Iterator iterator(): 获取集合对应的迭代器,用来遍历集合中的元素的public E next():返回迭代的下一个元素public boolean hasNext():如果仍有元素可以迭代,则返回 true@Test
public void test3(){
Collection coll = new ArrayList();
coll.add("小李广");
coll.add("扫地僧");
coll.add("石破天");
Iterator iterator = coll.iterator(); //获取迭代器对象
while(iterator.hasNext()) { //判断是否还有元素可迭代
System.out.println(iterator.next()); //取出下一个元素
}
}
void remove()@Test
public void test4(){
Collection coll = new ArrayList();
coll.add(1);
coll.add(2);
coll.add(3);
coll.add(4);
coll.add(5);
coll.add(6);
Iterator iterator = coll.iterator();
while(iterator.hasNext()){
Integer element = (Integer) iterator.next();
if(element % 2 == 0){
iterator.remove();
}
}
System.out.println(coll); // [1, 3, 5]
}

遍历数组和集合的for(元素的数据类型 局部变量 : Collection集合或数组){
//操作局部变量的输出操作
}
//这里局部变量就是一个临时变量,自己命名就可以
举例:
@Test
public void test5(){
Collection coll = new ArrayList();
coll.add("小李广");
coll.add("扫地僧");
coll.add("石破天");
//foreach循环其实就是使用Iterator迭代器来完成元素的遍历的。
for (Object o : coll) {
System.out.println(o);
}
}

public class InterviewTest {
@Test
public void testFor() {
String[] arr1 = new String[]{"AA", "CC", "DD"};
//赋值操作1
// for(int i = 0;i < arr1.length;i++){
// arr1[i] = "MM";
// }
//赋值操作2
for (String s : arr1) {
s = "MM";
}
System.out.println(Arrays.toString(arr1));
}
}
java.util.List替代数组元素有序、且可重复,集合中的每个元素都有其对应的顺序索引ArrayList、LinkedList和Vector
List除了从Collection集合继承的方法外,List 集合里添加了一些根据索引来操作集合元素的方法
void add(int index, Object ele):在index位置插入ele元素Object get(int index):获取指定index位置的元素Object remove(int index):移除指定index位置的元素,并返回此元素Object set(int index, Object ele):设置指定index位置的元素为ele举例:
public class TestListMethod {
public static void main(String[] args) {
// 创建List集合对象
List<String> list = new ArrayList<String>();
// 往 尾部添加 指定元素
list.add("图图");
list.add("小美");
list.add("不高兴");
System.out.println(list); // [图图, 小美, 不高兴]
// 往指定位置添加
list.add(1,"没头脑");
System.out.println(list); // [图图, 没头脑, 小美, 不高兴]
// 删除指定位置元素 返回被删除元素
System.out.println(list.remove(2));
System.out.println(list); // [图图, 没头脑, 不高兴]
// 在指定位置 进行 元素替代(改)
// 修改指定位置元素
list.set(0, "三毛");
System.out.println(list); // [三毛, 没头脑, 不高兴]
}
}
主要实现类Arrays.asList(…) 方法创建集合

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
protected AbstractList() {
}
public boolean add(E e) {
add(size(), e);
return true;
}
...
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
}
例子:
@Test
public void test6(){
List<String> list = Arrays.asList("1", "2", "3");
list.add("a");
}
输出结果:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
插入或删除元素的操作,建议使用LinkedList类,效率较高双向链表)结构存储数据决定的
古老的集合,JDK1.0就有了线程安全的ArrayList作为默认选择
特点:
判断两个元素相等的标准:
hashCode() 方法得到的哈希值相等equals() 方法返回值为true重写hashCode()和equals(Object obj)方法,以实现对象相等规则。即:“相等的对象必须具有相等的散列码”hashCode值散列函数决定该对象在 HashSet 底层数组中的存储位置hashCode()值相等,则会继续调用equals()方法
链表的方式继续链接,存储注意:如果两个元素的 equals() 方法返回 true,但它们的 hashCode() 返回值不相等,hashSet 将会把它们存储在不同的位置,但依然可以添加成功
举例:
public class Person {
String name;
int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
System.out.println("Person equals()...");
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
System.out.println("Person hashCode()...");
return Objects.hash(name, age);
}
}
@Test
public void test1(){
Set set = new HashSet();
set.add("AA");
set.add(123);
set.add("BB");
set.add(new Person("Tom",12));
set.add(new Person("Tom",12));
Iterator iterator = set.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
输出结果:
Person hashCode()...
Person hashCode()...
Person equals()...
AA
BB
123
Person{name='Tom', age=12}
双向链表维护元素的次序添加顺序保存的插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能
举例:
@Test
public void test2(){
LinkedHashSet set = new LinkedHashSet();
set.add("张三");
set.add("张三");
set.add("李四");
set.add("王五");
set.add("王五");
set.add("赵六");
System.out.println("set = " + set);//不允许重复,体现添加顺序
}
输出结果:
set = [张三, 李四, 王五, 赵六]
指定的属性的大小顺序进行遍历红黑树结构存储数据自然排序和定制排序。默认情况下,TreeSet 采用自然排序
自然排序:TreeSet 会调用集合元素的 compareTo(Object obj) 方法来比较元素之间的大小关系,然后将集合元素按升序(默认情况)排列
定制排序:如果元素所属的类没有实现Comparable接口,或不希望按照升序(默认情况)的方式排列元素或希望按照其它属性大小进行排序,则考虑使用定制排序。定制排序,通过Comparator接口来实现。需要重写compare(T o1,T o2)方法
同一个类的对象两个对象是否相等的唯一标准是:
compareTo(Object obj) 或compare(Object o1,Object o2)方法比较返回值举例1:String自然排序
/*
* 自然排序:针对String类的对象
* */
@Test
public void test1(){
TreeSet set = new TreeSet();
set.add("MM");
set.add("CC");
set.add("AA");
set.add("DD");
set.add("ZZ");
//set.add(123); //报ClassCastException的异常
System.out.println(set); // [AA, CC, DD, MM, ZZ]
}
举例2:自定义类自然排序
public class User implements Comparable{
String name;
int age;
public User() {
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
/*
举例:按照age从小到大的顺序排列,如果age相同,则按照name从大到小的顺序排列
* */
public int compareTo(Object o) {
if(this == o){
return 0;
}
if(o instanceof User){
User user = (User)o;
int value = this.age - user.age;
if(value != 0){
return value;
}
return -this.name.compareTo(user.name);
}
throw new RuntimeException("输入的类型不匹配");
}
}
/*
* 自然排序:针对User类的对象
* */
@Test
public void test2(){
TreeSet set = new TreeSet();
set.add(new User("Tom",12));
set.add(new User("Rose",23));
set.add(new User("Jerry",2));
set.add(new User("Eric",18));
set.add(new User("Tommy",44));
set.add(new User("Jim",23));
set.add(new User("Maria",18));
//set.add("Tom");
Iterator iterator = set.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println(set.contains(new User("Jack", 23))); //true
}
举例3:定制排序
/*
* 定制排序
* */
@Test
public void test3(){
//按照User的姓名的从小到大的顺序排列
Comparator comparator = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof User && o2 instanceof User){
User u1 = (User)o1;
User u2 = (User)o2;
return u1.name.compareTo(u2.name);
}
throw new RuntimeException("输入的类型不匹配");
}
};
TreeSet set = new TreeSet(comparator);
set.add(new User("Tom",12));
set.add(new User("Rose",23));
set.add(new User("Jerry",2));
set.add(new User("Eric",18));
set.add(new User("Tommy",44));
set.add(new User("Jim",23));
set.add(new User("Maria",18));
Iterator iterator = set.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
映射关系的数据:key-value
Collection集合称为单列集合,元素是孤立存在的(理解为单身)Map集合称为双列集合,元素是成对存在的(理解为情侣)HashMap、LinkedHashMap、TreeMap和Properties频率最高的实现类

key用Set来存放,不允许重复,即同一个 Map 对象所对应的类,须重写hashCode()和equals()方法
value可以重复entry。所有的entry彼此之间是无序的、不可重复的举例1:
@Test
public void test1(){
//创建 map对象
HashMap map = new HashMap();
//添加元素到集合
map.put("黄晓明", "杨颖");
map.put("李晨", "李小璐");
map.put("李晨", "范冰冰");
map.put("邓超", "孙俪");
System.out.println(map);
//删除指定的key-value
System.out.println(map.remove("黄晓明"));
System.out.println(map);
//查询指定key对应的value
System.out.println(map.get("邓超"));
System.out.println(map.get("黄晓明"));
}
举例2:
@Test
public void test2(){
HashMap map = new HashMap();
map.put("许仙", "白娘子");
map.put("董永", "七仙女");
map.put("牛郎", "织女");
map.put("许仙", "小青");
System.out.println("所有的key:");
Set keySet = map.keySet();
for (Object key : keySet) {
System.out.println(key);
}
System.out.println("所有的value:");
Collection values = map.values();
for (Object value : values) {
System.out.println(value);
}
System.out.println("所有的映射关系:");
Set entrySet = map.entrySet();
for (Object mapping : entrySet) {
//System.out.println(entry);
Map.Entry entry = (Map.Entry) mapping;
System.out.println(entry.getKey() + "->" + entry.getValue());
}
}
使用频率最高的实现类一维数组+单向链表+红黑树进行key-value数据的存储判断两个key相等的标准是:两个 key 的hashCode值相等,通过 equals() 方法返回 true判断两个value相等的标准是:两个 value 通过 equals() 方法返回 true举例:
@Test
public void test1(){
Map map = new HashMap();
map.put(null,null);
map.put("Tom",23);
map.put("CC",new Date());
map.put(34,"AA");
System.out.println(map); // {null=null, CC=Sat Apr 22 17:51:16 CST 2023, 34=AA, Tom=23}
}
双向链表来记录添加元素的先后顺序举例:
@Test
public void test2(){
LinkedHashMap map = new LinkedHashMap();
map.put("Tom",23);
map.put("CC","test");
map.put(34,"AA");
System.out.println(map); // {Tom=23, CC=test, 34=AA}
}
有序状态红黑树结构存储数据自然排序:TreeMap 的所有的 Key 必须实现 Comparable 接口
定制排序:创建 TreeMap 时,构造器传入一个 Comparator 对象
两个key相等的标准:两个key通过compareTo()方法或者compare()方法返回0举例1:自然排序
@Test
public void test1(){
TreeMap map = new TreeMap();
map.put("CC",45);
map.put("MM",78);
map.put("DD",56);
map.put("GG",89);
System.out.println(map); // {CC=45, DD=56, GG=89, MM=78}
}
举例1:定制排序
@Test
public void test2(){
//按照User的姓名的从小到大的顺序排列
TreeMap map = new TreeMap(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof User && o2 instanceof User){
User u1 = (User)o1;
User u2 = (User)o2;
return u1.name.compareTo(u2.name);
}
throw new RuntimeException("输入的类型不匹配");
}
});
map.put(new User("Tom",12),67);
map.put(new User("Rose",23),"87");
map.put(new User("Jerry",2),88);
map.put(new User("Eric",18),45);
map.put(new User("Tommy",44),77);
map.put(new User("Jim",23),88);
map.put(new User("Maria",18),34);
System.out.println(map);
}
古老实现类,JDK1.0就提供了线程安全的数组+单向链表),查询速度快不允许使用 null 作为 key 或 value字符串类型举例1:
@Test
public void test3() throws IOException {
Properties pros = new Properties();
pros.load(new FileInputStream("jdbc.properties"));
String user = pros.getProperty("user");
System.out.println(user);
}
参考操作数组的工具类:Arrays,Collections 是一个操作 Set、List 和 Map 等集合的工具类
排序操作:
reverse(List):反转 List 中元素的顺序sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序查找
复制、替换
添加
同步

@Test
public void test1(){
List list = Arrays.asList(45, 43, 65, 6, 43, 2, 32, 45, 56, 34, 23);
//reverse(List):反转 List 中元素的顺序
// Collections.reverse(list); // [23, 34, 56, 45, 32, 2, 43, 6, 65, 43, 45]
//shuffle(List):对 List 集合元素进行随机排序,每次不一样
// Collections.shuffle(list); // [65, 32, 34, 23, 45, 45, 2, 43, 43, 56, 6]
//sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序
// Collections.sort(list); // [2, 6, 23, 32, 34, 43, 43, 45, 45, 56, 65]
//sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序
Collections.sort(list, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof Integer && o2 instanceof Integer){
Integer i1 = (Integer) o1;
Integer i2 = (Integer) o2;
// return i1 - i2;
return -(i1.intValue() - i2.intValue());
}
throw new RuntimeException("类型不匹配");
}
}); // [65, 56, 45, 45, 43, 43, 34, 32, 23, 6, 2]
System.out.println(list);
}
@Test
public void test2(){
List list = Arrays.asList(45, 43, 65, 6, 43, 2, 32, 45, 56, 34, 23);
System.out.println(list);
Object max = Collections.max(list);
Object max1 = Collections.max(list,new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof Integer && o2 instanceof Integer){
Integer i1 = (Integer) o1;
Integer i2 = (Integer) o2;
// return i1 - i2;
return -(i1.intValue() - i2.intValue());
}
throw new RuntimeException("类型不匹配");
}
});
System.out.println(max); // 65
System.out.println(max1); // 2
int count = Collections.frequency(list, 45);
System.out.println("45出现了" + count + "次"); // 45出现了2次
}
@Test
public void test3(){
List src = Arrays.asList(45, 43, 65, 6, 43, 2, 32, 45, 56, 34, 23);
//void copy(List dest,List src):将src中的内容复制到dest中
//错误的写法:
// List dest = new ArrayList();
//正确的写法:
List dest = Arrays.asList(new Object[src.size()]);
Collections.copy(dest,src);
System.out.println(dest);
}
@Test
public void test4(){
//提供了多个unmodifiableXxx()方法,该方法返回指定 Xxx的不可修改的视图。
List list1 = new ArrayList();
//list1可以写入数据
list1.add(34);
list1.add(12);
list1.add(45);
List list2 = Collections.unmodifiableList(list1);
//此时的list2只能读,不能写
list2.add("AA");//不能写
System.out.println(list2.get(0));//34
}
@Test
public void test5(){
//Collections 类中提供了多个 synchronizedXxx() 方法
List list1 = new ArrayList();
//返回的list2就是线程安全的
List list2 = Collections.synchronizedList(list1);
list2.add(123);
HashMap map1 = new HashMap();
//返回的map2就是线程安全的
Map map2 = Collections.synchronizedMap(map1);
}