Java集合 Collection、Map

本文详细介绍了Java集合框架中的Collection、List、Set和Map接口及其主要实现类,包括ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap等。还探讨了迭代器、比较器的概念,以及泛型在Java集合中的应用。此外,提到了Collections工具类的使用,帮助优化集合操作。
摘要由CSDN通过智能技术生成

一、Collection

框架图:
在这里插入图片描述

Collection父接口:

  • 特点:代表一组任意类型的对象,无序、无下标。

常用方法:

方法描述
boolean add(Object obj)添加一个对象数据
boolean addAll(Collection c)将一个集合中的所有对象添加到此集合中
void clear()清空此集合中的所有对象
boolean contains(Object o)检查此集合中是否包含o对象
boolean equals(Object o)比较此集合是否与指定对象相等
boolean isEmpty()判断此集合是否为空
boolean remove(Object o)在此集合中移除o对象
int size()返回此集合中的元素个数
Object[] toArray()将此集合转换成数组

注:遍历的同时不能使用集合删除方法,否则出现并发修改异常,可使用迭代器的删除方法。

1.1迭代器

iterator

Collection extends Iterable;

意味着只要是Collection的子类都有迭代器

含义:遍历集合中的数据

分类:Iterator 和 ListIterator

Iterator 和 ListIterator 区别

Iterator :Collection接口下所有的实现类都可以获取的迭代器,可以在遍历时删除元素

ListIterator :List接口下所有的实现类可以获取的迭代器,可以在遍历时删除、替换、添加元素,也可以指定下标开始遍历,还可以倒叙遍历

//获取迭代器
Iterator<T> itor = 集合.iterator();
//while
while(itor.hasNext()){
   T t = itor.next();
}
注意:迭代器可以在迭代的同事删除当前元素
    
反向迭代器(功能更加强大--复杂情况是考虑使用)
使用列表迭代器 ,Iterator的区别,ListIterator可以向前或向后遍历,添加、删除、修改元素
ListIterator lit=list.listIterator(); // 可以放东西的  listIterator(list.size())
System.out.println("------使用列表迭代器从前往后-------");
while(lit.hasNext()) {
    System.out.println(lit.nextIndex()+":"+lit.next());
}
System.out.println("------使用列表迭代器后往前-------");
while(lit.hasPrevious()) {
    System.out.println(lit.previousIndex()+":"+lit.previous());
}

1.2比较器

作用:排序时使用

分类:

​ 内置比较器:Comparable - compareTo()

​ 外置比较器:Comparator - compare()

使用场景:

​ 内置比较器:对象要想存入TreeSet、TreeMap中,对象所属的类必须要实现内置比较器

​ 外置比较器:当内置比较的规则不满足现在的需求,但又不能改动内置比较器规则时

优先级别:外置比较器 > 内置比较器

二、List

  • 特点:有序、有下标、元素可以重复。
  • 继承Collection接口。

常用方法:

方法描述
void add(int index, Object o)在index位置插入对象o。
boolean addAll(int index, Collection c)将一个集合中的元素添加到此集合中的index位置。
Object get(int index)返回集合中指定位置的元素。
List subList(int fromIndex, int toIndex)返回fromIndex和toIndex之间的集合元素。

List的创建及4种遍历方式:

public class Test {

	public static void main(String[] args) {
		// 创建
		List<String> list=new ArrayList<>();
		//1添加元素
		list.add("苹果");
		list.add("小米");
		list.add("华为");
		// 直接输出
		System.out.println(list);
		System.out.println("-------------");
		// 遍历方法1 for循环
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}
		System.out.println("-------------");
		// 遍历方法2 增强for循环
		for (String string : list) {
			System.out.println(string);
		}
		System.out.println("-------------");
		// 遍历方法3 使用迭代器
		Iterator ito = list.iterator();
		while(ito.hasNext()) {
			System.out.println(ito.next());
		}
		System.out.println("-------------");
		// 遍历方法4 使用列表迭代器 (功能比Iterator更多可向前、向后,增加删除)
		ListIterator lit=list.listIterator(list.size());
		while(lit.hasPrevious()) {// 演示倒序
			System.out.println(lit.previousIndex()+":"+lit.previous());
		}
	}
}

2.1ArrayList

  • 数组结构实现,查询快、增删慢。
  • JDK1.2版本、线程不安全。
  • 底层数据结构是一维数组

2.2LinkedList

  • 链表结构实现,增删快,查询慢。

  • JDK1.2版本、队列模式、栈模式,线程不安全

  • 底层数据结构是双向链表

  • ArrayList和LinkedList区别:

  • ArrayList存储结构是数据,查找、遍历效率高。

  • LinkedList存储结构是双向链表,删除、添加效率高。

​ 添加 - 不扩容的情况:ArrayList快

​ 添加 - 扩容的情况:LinkedList快

​ 删除:LinkedList快

​ 查询:ArrayList快

​ 修改:ArrayList快

注意:工作中常用ArrayList,因为很多需求都需要使用查询功能,ArrayList查询更快

2.3Vector

数组结构实现,查询快、增删慢。
JDK1.0版本,线程安全、运行效率比ArrayList较慢。

2.4Stack

弃用,线程安全

三、Set

  • 特点:无序、无下标、元素不可重复。
  • 方法:全部继承自Collection中的方法。
  • 使用foreach循环遍历:
    for(数据类型 局部变量 : 集合名){
    //循环内部的局部变量,代表当次循环从集合中取出的对象
    }

Set的创建和遍历方法:

public class TestSet {
	public static void main(String[] args) {
		// 创建
		Set<String> set=new HashSet<>();
		//1添加元素
		set.add("苹果");
		set.add("小米");
		set.add("华为");
		// 直接输出
		System.out.println(set);
		System.out.println("-------------");
		// 遍历方法1 增强for循环
		for (String string : set) {
			System.out.println(string);
		}
		System.out.println("-------------");
		// 遍历方法2 使用迭代器
		Iterator ito = set.iterator();
		while(ito.hasNext()) {
			System.out.println(ito.next());
		}
		System.out.println("-------------");		
	}
}

3.1HashSet

  • 基于HashCode实现元素不重复。线程不安全
  • 当存入元素的哈希码相同时,会调用==或equals进行确认,结果为true,拒绝后者存入。

在这里插入图片描述

3.2LinkedHashSet

LinkedHashSet是在HashSet的基础上新维护了一个双向链表

链表实现的HashSet,按照链表进行存储,即可保留元素的插入顺序。

线程不安全

3.3TreeSet

  • 基于排列顺序实现元素不重复。
  • 实现了SortedSet接口,对集合元素自动排序。
  • 元素对象的类型必须实现Comparable接口,指定排序规则(自然排序)。
  • 通过CompareTo方法确定是否为重复元素。
  • 线程不安全

必须实现:

用匿名内部类在构造TreeSet的时候放一个Comparator

或者

用需要排序的类去实现Comparable

注:两个都实现时,Comparator优先级要高

/**
	 * 向TreeSet集合中加入5个员工的对象,根据员工的年龄(升序)进行排序,
	 * 若年龄相同,再根据工龄(降序)来排序,若工龄相同,根据薪水(降序)排序
	 */
	public static void main(String[] args) {
											// 第一种排序方法,Comparator
		TreeSet<Staff> workers = new TreeSet<>(new Comparator<Staff>() {
			public int compare(Staff o1, Staff o2) {
				if (o1.age!=o2.age) {// 升序
					return o1.age-o2.age;
				}else if (o1.ageOfWork!=o2.ageOfWork) {// 降序
					return o2.ageOfWork-o1.ageOfWork;
				}else if (o1.wages!=o2.wages) {// 降序
					return o2.wages-o1.wages;
				}
				return o1.hashCode()-o2.hashCode();
			}
		});
		// 添加
		workers.add(new Staff("zhang3", 20, 1, 3000));
		workers.add(new Staff("li4", 20, 2, 3000));
		workers.add(new Staff("wang5", 20, 1, 4000));
		workers.add(new Staff("zhao6", 30, 5, 3000));
		workers.add(new Staff("zhang3s", 30, 5, 6000));
		// 遍历
		for (Staff staff : workers) {
			System.out.println(staff);
		}
	}
class Staff implements Comparator<Staff>{   // 第二种
	String name;
	int age;
	int ageOfWork;
	int wages;
	public Staff(String name, int age, int ageOfWork, int wages) {
		super();
		this.name = name;
		this.age = age;
		this.ageOfWork = ageOfWork;
		this.wages = wages;
	}
	@Override
	public String toString() {
		return "[name=" + name + ", age=" + age + ", ageOfWork=" + ageOfWork + ", wages=" + wages + "]";
	}
	// Comparator接口实现
	public int compare(Staff o1, Staff o2) {
		if (o1.age!=o2.age) {// 升序
			return o1.age-o2.age;
		}else if (o1.ageOfWork!=o2.ageOfWork) {// 降序
			return o2.ageOfWork-o1.ageOfWork;
		}else if (o1.wages!=o2.wages) {// 降序
			return o2.wages-o1.wages;
		}
		return o1.hashCode()-o2.hashCode();
	}
}

四、Map

4.1HashMap

  • JDK1.2版本,线程不安全,运行效率快。
  • 允许用null 作为key或是value。
  • 存储结构:哈希表。
  • 存key+value,key去重,无序
public class TestMap {
	public static void main(String[] args) {
		HashMap<String,String> countries = new HashMap<String,String>();
		countries.put("CN", "CHINA");
		countries.put("US", "AMERICA");
		countries.put("RU", "RUSSIA");
		countries.put("JP", "JAPAN");
		countries.put("FR", "FRANCE");

		// 遍历  foreach
		// 1.循环键
		for (String k : countries.keySet()) {
			System.out.println(k +"--"+countries.get(k));
		}
		// 2.循环值
		for (String v : countries.values()) {
			System.out.println(v);
		}
		// 3.循环键值对
		Set<Entry<String,String>> entrySet = countries.entrySet();
		for (Entry<String,String> kv : entrySet) {
			System.out.println(kv.getKey()+"--"+kv.getValue());
		}		
	}
}

4.2Hashtable

JDK1.0版本,线程安全,运行效率慢;不允许null作为key或是value。

弃用,存key+value,key去重,无序,线程安全,方法加锁-效率低

4.3LinkedHashMap

概念:

HashMap是哈希表结构,可以保证键的唯一性,并不保证有序性,而LinkedHashMap是Map接口的哈希表和链表实现,具有可预知的迭代顺序。哈希表保证键的唯一性、链表保证键的有序(进出一致)

存key+value,key去重,有序,线程不安全

public class TestLinkedHashMap {
	public static void main(String[] args) {
		HashMap<Student,String> hmap = new HashMap<Student,String>();
		// 乱序(对HashMap来说不是乱序,它有自己的算法)
		hmap.put(new Student("zhang3", 10, 40), "A");
		hmap.put(new Student("li4", 20, 30), "B");
		hmap.put(new Student("wang5", 30, 20), "C");
		hmap.put(new Student("zhao6", 40, 10), "D");
		for (Student k : hmap.keySet()) {
			System.out.println(k +"--"+hmap.get(k));
		}
		
		System.out.println("------------");
		// 链表  值进出一致
		LinkedHashMap<Student, String> map = new LinkedHashMap<Student,String>();
		
		map.put(new Student("zhang3", 10, 40), "A");
		map.put(new Student("li4", 20, 30), "B");
		map.put(new Student("wang5", 30, 20), "C");
		map.put(new Student("zhao6", 40, 10), "D");
		for (Student k : map.keySet()) {
			System.out.println(k +"--"+map.get(k));
		}
	}	
}

运行结果:

Student [name=wang5, age=30, salary=20]--C
Student [name=zhang3, age=10, salary=40]--A
Student [name=li4, age=20, salary=30]--B
Student [name=zhao6, age=40, salary=10]--D
------------
Student [name=zhang3, age=10, salary=40]--A
Student [name=li4, age=20, salary=30]--B
Student [name=wang5, age=30, salary=20]--C
Student [name=zhao6, age=40, salary=10]--D

4.4TreeMap

实现了SortedMap接口(Map的子接口),可以对key自动排序,Key需实现Comparable接口。

排序,线程不安全

public class TestTreeMap {

	public static void main(String[] args) {
		
		TreeMap<Student,String> map = new TreeMap<Student,String>(new Comparator<Student>() {
			@Override
			public int compare(Student o1, Student o2) {
				// 按salary升序
				return o1.salary-o2.salary;
			}
		});
	
		map.put(new Student("zhang3", 10, 40), "A");
		map.put(new Student("li4", 20, 30), "B");
		map.put(new Student("wang5", 30, 20), "C");
		map.put(new Student("zhao6", 40, 10), "D");
		
		System.out.println(map);
	}
}

4.5Properties

Hashtable的子类,要求key和value都是String。通常用于配置文件的读取。

public class TestProp {
	public static void main(String[] args) {		
		// 操作文件
		Properties prop = new Properties();
		InputStream is = TestProp.class.getClassLoader().getResourceAsStream("db.properties");//填写文件		
		try {
			prop.load(is);
			System.out.println(prop.getProperty("username"));
			System.out.println(prop.getProperty("password"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

五、泛型

5.1 概念

概念:

  • Java泛型是JDK1.5中引入的一个新特性,其本质是参数化类型,把类型作为参数传递。
  • 常见形式有泛型类、泛型接口、泛型方法。

语法:

  • <T,…> T称为类型占位符,表示一种引用类型。

泛型限定:

?表示什么类型都可以

? extends A 表示元素必须是A类或A的子类

? super A 表示元素必须是A类或A的父类

优点:

  • 提高代码的重用性。
  • 防止类型转换异常,提高代码的安全性。

5.2 泛型集合

  • 参数化类型、类型安全的集合,强制集合元素的类型必须一致。
  • 特点:
    • 编译时即可检查,而非运行时抛出异常。
    • 访问时,不必类型转换(拆箱)。
    • 不同泛型之间引用不能相互赋值,泛型不存在多态。

六、Collections工具类

集合工具类,定义了除了存取以外的集合常用方法。

方法描述
public static void reverse(List<?> list)反转集合中元素的顺序
public static void shuffle(List<?> list)随机重置集合元素的顺序
public static void sort(List list) /升序排序(元素类型必须实现Comparable接口)
public static int binarySearch( list, T key)二分查找
//Collections工具类
List<Integer> list = new ArrayList<>();
// 批量添加
Collections.addAll(list, 1,4,2,6,3,5 );
System.out.println(list);// [1, 4, 2, 6, 3, 5]

// 第一种sort()排序 (默认的)
Collections.sort(list); // 默认正序
System.out.println(list); // [1, 2, 3, 4, 5, 6]

// 第二种sort()  (自定义排序)
Collections.sort(list, new Comparator<Integer>() {
    public int compare(Integer o1, Integer o2) {
        return o2-o1; // 降序 (自定义)
    }
});
System.out.println(list); // [6, 5, 4, 3, 2, 1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值