JavaSE(十)--集合

本文详细介绍了Java集合框架中的List、Set、Map接口及其常见实现类,包括ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap等。还探讨了泛型在集合中的应用,包括泛型集合、泛型迭代器、泛型类和方法。此外,文章还对比了ArrayList和Vector的区别,并讨论了如何利用HashSet、HashMap、TreeSet、TreeMap进行数据去重和排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.集合

存多个引用数据类型的数据的集合.它的长度可变.(动态)

2.集合中常用概念:

  • 有序性:按照添加顺序来排列.

  • 可排序性:按照一定规则来排序(eg:数字由小到大,或由大到小来排序)

  • 唯一性:只有一个,不可重复.

  • 集合家族系谱图:
    在这里插入图片描述

3 List

3.1:Collection接口

存储无序,可重复的单一对象.

3.1.1 List接口

存储有序,可重复的单一对象.

  • ArrayList类:存储有序,可重复的单一对象.底层采用Object[]存值.
  • LinkedList类:存储有序,可重复的单一对象.底层采用双向链表结构存值.

3.1.2 Set接口

存储无序,唯一的单一对象.

  • HashSet类:存储无序,唯一的单一对象.底层采用HashMap的Key存值.
  • TreeSet类:存储无序,但是可排序,唯一的单一对象.底层采用TreeMap的Key存值.

3.2 Map接口

按照Key-value对存值.

  • HashMap:按照Key-value对存值,Key无序,唯一的.底层采用数组+链表结构存值.
  • TreeMap:按照Key-value对存值,Key无序可排序,唯一的.底层采用二叉树结构存值.

4.ArrayList

存储有序的,可重复的单一对象.底层采用Object[]存值.默认按照1.5倍扩容.

  • 优点:按顺序添加和修改及遍历的效率高.
  • 缺点:删除元素或按指定索引添加元素效率低.
public static void main(String[] args) {
		//创建集合对象
		List stuAges=new ArrayList();
		
		//向集合中添加元素
		stuAges.add(11);
		stuAges.add(99);
		stuAges.add(61);
		//向集合中指定索引位置添加元素时,索引范围:[0,集合.size()]
		stuAges.add(2, 33);
		stuAges.add(3, 71);
		stuAges.add(11);
		
		//遍历集合
		for (int i = 0; i < stuAges.size(); i++) {
			System.out.println(stuAges.get(i));
		}
		System.out.println("------------------------------");
		
		//修改集合中元素,修改元素索引范围为:[0,集合.size()-1]
		stuAges.set(2, 44);
		
		//遍历集合
		for (Object ob : stuAges) {
			System.out.println(ob);
		}
		System.out.println("________________________________");
		
		//删除集合中元素,删除的索引范围:[0,集合.size()-1]
		stuAges.remove(1);
		//删除集合中元素
		stuAges.remove((Object)11);
		//根据过滤器,删除满足条件元素
		stuAges.removeIf(new Predicate() {
			/**
			 * 过滤方法
			 */
			@Override
			public boolean test(Object t) {
				//将判断集合中每个元素转换字符串类型,再判断元素是否以1结尾
				if (t.toString().endsWith("1")) {
					return true;
				}
				return false;
			}
		});
		
		//遍历集合
		for (int i = 0; i < stuAges.size(); i++) {
			System.out.println(stuAges.get(i));
		}
		System.out.println("------------------------------");
		
		//清空集合
		stuAges.clear();
		//遍历集合
		for (Object ob : stuAges) {
			System.out.println(ob);
		}
		System.out.println("________________________________");
	}

5.过滤器(filter)

将需要数据留下,不需要的数据剔除掉.

6.LinkedList

存储有序的,可重复的单一对象.底层采用双向链表结构存值.

  • 优点:添加和删除元素效率高.
  • 缺点:遍历和修改元素效率低.
public static void main(String[] args) {
		//创建集合对象
		LinkedList stuAges=new LinkedList();
		
		//向集合中添加元素
		stuAges.add(11);
		stuAges.add(99);
		stuAges.add(61);
		//向集合中指定索引位置添加元素时,索引范围:[0,集合.size()]
		stuAges.add(2, 33);
		stuAges.add(11);
		//向集合中添加第一个元素
		stuAges.addFirst(22);
		//向集合中添加最后一个元素
		stuAges.addLast(55);
		
		//遍历集合
		for (int i = 0; i < stuAges.size(); i++) {
			System.out.println(stuAges.get(i));
		}
		System.out.println("------------------------------");
		
		//修改集合中元素,修改元素索引范围为:[0,集合.size()-1]
		stuAges.set(2, 44);
		
		//遍历集合
		for (Object ob : stuAges) {
			System.out.println(ob);
		}
		System.out.println("________________________________");
		
		
		//删除集合中第一个元素
		stuAges.removeFirst();
		
		//删除集合中最后一个元素
		stuAges.removeLast();
		
		//删除集合中元素,删除的索引范围:[0,集合.size()-1]
		stuAges.remove(1);
		//删除集合中元素
		stuAges.remove((Object)11);
		//根据过滤器,删除满足条件元素
		stuAges.removeIf(new Predicate() {
			/**
			 * 过滤方法
			 */
			@Override
			public boolean test(Object t) {
				//将判断集合中每个元素转换字符串类型,再判断元素是否以1结尾
				if (t.toString().endsWith("1")) {
					return true;
				}
				return false;
			}
		});
		
		//遍历集合
		for (int i = 0; i < stuAges.size(); i++) {
			System.out.println(stuAges.get(i));
		}
		System.out.println("------------------------------");
		
		//清空集合
		stuAges.clear();
		//遍历集合
		for (Object ob : stuAges) {
			System.out.println(ob);
		}
		System.out.println("________________________________");
	}

7.ArrayList VS Vector(面试)

相同点存储的都是有序的可重复单一对象,底层采用Object[]存值.

  • 1:推出时间不同:Vector在JDK1.2之前就推出了;而ArrayList在JDK1.2后才推出.
  • 2:线程安全性和效率不同:Vector是线程安全的集合,效率低;ArrayList是线程不安全的集合,效率高.
  • 3:扩容不同:Vector按原来2倍扩容;ArrayList按原来1.5倍扩容.
  • 4:方法不同:ArrayList拥有的所有方法Vector都有,Vector还有自己独有的方法.

8.迭代器(Iterator)

遍历访问collection集合中每个元素.

  • 集合名.iterator();获得当前集合跌代器对象.
  • 跌代器对象.hasNext();判断跌代器对象后面是否有元素可跌代.
  • 跌代器对象.next();跌代元素(访问当前元素),
    注意: 集合中每个元素只能调用一次next().
public static void main(String[] args) {
		//创建集合对象
		ArrayList stuAges=new ArrayList();
		
		//向集合中添加元素
		stuAges.add(11);
		stuAges.add(99);
		stuAges.add(61);
		
		//获得集合的迭代器对象
		Iterator it1=stuAges.iterator();
		
		//循环判断迭代器对象后面是否有元素可迭代
		while (it1.hasNext()) {
			//迭代出当前元素
			Object ob=it1.next();
			System.out.println(ob);
		}
	}
	public static void main(String[] args) {
		//创建集合对象
		ArrayList stus=new ArrayList();
		
		//向集合中添加元素
		stus.add(new Student("张三",88));
		stus.add(new Student("李四",38));
		stus.add(new Student("田七",48));
		
		//获得集合的迭代器对象
		Iterator it2=stus.iterator();
		//循环判断迭代器后面是否有元素可迭代
		while (it2.hasNext()) {
			//迭代当前元素,并存在变量中
			Student stu=(Student)it2.next();
			//用变量调用属性输出
			System.out.println(stu.sname+","+stu.sage);
		}
	}

9.Collections

collection集合家族工具类.

10.泛型

将引用数据类型参数化.(将引用数据类型作为参数来传递).语法:<数据类型>

10.1:泛型集合

将数据类型作为集合的参数,集合中每个元素必须都是这个泛型的数据类型。

  • 1:泛型集合的使用:因为普通集合,存数据时要频繁的装箱(什么类型的数据存到集合中都要封装成Object类型),取出数据时要频繁的拆箱(将元素转换原来的类型),使用不方法.所以想到用泛型集合可以减少频繁的装箱和拆箱.
    编译时即可检查,而非运行时抛出异常.
  • 2:泛型集合:一个集合中只能存同一种数据类型.
  • 3:语法: 集合类型<数据类型> 集合名=new 集合类型<数据类型>;
public static void main(String[] args) {
		//准备集合
		List<Student> alist=new ArrayList<Student>();
		//向集合添加元素
		alist.add(new Student("张三1", 18));
		alist.add(new Student("张三2", 18));
		alist.add(new Student("张三3", 18));
		
		//遍历集合
		for (Student stu1 : alist) {
			System.out.println(stu1.sname+"\t"+stu1.sage);
		}
	}

10.2:泛型迭代器

将数据类型作为迭代器的参数,迭代出来的每个元素是泛型的数据类型。

  • 1:泛型迭代器的作用:减少频繁的类型转换的问题。
  • 2:语法:Iterator<数据类型> 跌代器对象名=集合名.iterator();
  • 3:泛型跌代器与泛型集合是黄金搭挡,集合用什么数据类型作为泛型,泛型跌代器就用相同的数据类型作为泛型的数据类型.
	public static void main(String[] args) {
		//准备集合
		List<Student> alist=new ArrayList();
		//向集合添加元素
		alist.add(new Student("张三1", 18));
		alist.add(new Student("张三2", 18));
		alist.add(new Student("张三3", 18));
		
		//获得集合的迭代器
		Iterator<Student> it1=alist.iterator();
		//循环判断迭代器后面是否有元素可迭代
		while (it1.hasNext()) {
			Student stu1=it1.next();
			System.out.println(stu1.sname+"\t"+stu1.sage);
		}
	}

10.3:(扩展)泛型类

将引用数据类型作为类的参数,传到类中.

public class Teacher<T> {
	public String tname;
	public Integer tage;
	//将泛型类型作为成员变量数据类型
	public T num;
	
	@Override
	public String toString() {
		return "Teacher [tname=" + tname + ", tage=" + tage + ", num=" + num + "]";
	}
}
public static void main(String[] args) {
		//创建对象
		Teacher<Double> t1=new Teacher();
		t1.tname="张三";
		t1.tage=11;
		t1.num=3.14;
		System.out.println(t1);
		
		//创建对象
		Teacher<String> t2=new Teacher();
		t2.tname="张三";
		t2.tage=11;
		t2.num="哈哈";
		System.out.println(t2);
	}

10.4:(扩展)泛型方法

将数据类型作为参数传到方法中用.

	/**
	 * 泛型方法
	 * @param count
	 */
	public <T> void show(T count) {
		System.out.println("参数为:"+count);
	}

	public static void main(String[] args) {
		//创建对象
		Student2 stu2=new Student2();
		stu2.show("最近天气真不错哦");
		stu2.show(3.14);
		stu2.show(11);
	}

10.5:泛型属性不能与static或final一起使用.

泛型类,泛型方法可以与static,final,abstract一起使用.

10.6:(扩展)受限泛型:

	<?>:指代任意类型.
	<? extends T>: T的子类
	<? super T>: T的父类

11.(扩展)Stack继承自Vector类,是按压栈的方法存值,取值是按后进先出的方式取值.

12 Set

12.1 HashSet

HashSet:存储无序,唯一的单一对象.底层采用hashMap的key存值.

  • 唯一性:通过HashSet泛型的类中hashCode()和equals()来去重.
    优点:去重.
    在这里插入图片描述
public static void main(String[] args) {
		//准备一个集合
		HashSet<Student> hset1=new HashSet<>();
		//向集合中添加元素
		hset1.add(new Student("张三", 18));
		hset1.add(new Student("李四", 28));
		hset1.add(new Student("王五", 48));
		hset1.add(new Student("赵六", 38));
		hset1.add(new Student("张三", 18));
		
		//获得集合的迭代器
		Iterator<Student> it1=hset1.iterator();
		//循环判断迭代器后面是否有元素可迭代
		while (it1.hasNext()) {
			Student i=it1.next();
			System.out.println(i);
		}
		System.out.println("---------------------------------");
		
		//删除集合中元素
		hset1.remove(new Student("李四", 28));
		
		//遍历集合
		for (Student i2 : hset1) {
			System.out.println(i2);
		}
		System.out.println("*******************************");
		
		//清空集合
		hset1.clear();
		//遍历集合
		for (Student i2 : hset1) {
			System.out.println(i2);
		}
	}

12.2 (了解)LinkedHashSet

存储有序的,唯一的单一对象.底层采用哈希表和链表实现了Set接口,具有可预测的迭代次序.

12.3 TreeSet

存储无序可排序的,唯一单一对象.底层采用TreeMap的Key存值.
注意: TreeSet是一定要用排序器,如果TreeSet的构造方法没有传自定义排序器对象,默认用的是自然排序器,要求TreeSet的泛型类一定要实现自然排序器接口,重写排序方法;如 果TreeSet的构造方法传自定义排序器对象,就按这个对象的排序方法来排序.

  • 可排序性:通过排序器的排序方法返回正数,负数来排序的,返回负数排在左子节点(前面),返回正数排在右子节点(后面).

  • 唯一性:通过排序器的排序方法返回0,静态两相节点相同,去重

  • 优点:可排序,去重性.
    在这里插入图片描述

public static void main(String[] args) {
		//创建一个集合
		TreeSet<Integer> tset1=new TreeSet<>();
		//向集合中添加元素
		tset1.add(66);
		tset1.add(55);
		tset1.add(88);
		tset1.add(44);
		tset1.add(77);
		tset1.add(66);
		
		//获得集合迭代器
		Iterator<Integer> it1=tset1.iterator();
		//循环判断迭代器后面是否有元素可迭代
		while (it1.hasNext()) {
			Integer n1=it1.next();
			System.out.println(n1);
		}
		System.out.println("------------------------------");
		
		//删除集合中元素
		tset1.remove(44);
		
		//遍历集合
		for (Integer n2 : tset1) {
			System.out.println(n2);
		}
		System.out.println("------------------------------");
		
		//清空集合
		tset1.clear();
		//遍历集合
		for (Integer n2 : tset1) {
			System.out.println(n2);
		}
	}

12.4 排序器:

12.4.1:自然排序器(Comparable):

/**
 * 自定义的类型,实现自然排序器接口,重写排序方法
 */
public class Student implements Comparable<Student>{
	public String sname;
	public Integer sage;
	
	public Student() {
		
	}

	public Student(String sname, Integer sage) {
		super();
		this.sname = sname;
		this.sage = sage;
	}
	
	@Override
	public String toString() {
		return "Student [sname=" + sname + ", sage=" + sage + "]";
	}

	/**
	 * 重写自然排序器接口的排序方法
	 * 排序规则:先根据姓名降序排序,当姓名相同时,按年龄升序排序
	 * @param o 表示每一个要比较节点,刚开始指根节点
	 */
	@Override
	public int compareTo(Student o) {
		if (this.sname.compareTo(o.sname)!=0) {
			return -this.sname.compareTo(o.sname);
		} else {//姓名相同
			return this.sage.compareTo(o.sage);
			
//			if (this.sage>o.sage) {
//				return 1;//大的排在后面
//			} else if (this.sage<o.sage){
//				return -1;//小的排在前面
//			}else {//姓名和年龄都相同
//				return 0;//相同对象
//			}
		}
	}
}

12.4.2:自定义排序器(Comparator):

/**
 * 自定义排序器类,重写排序方法
 */
public class MyComparator implements Comparator<StudentA>{

	/**
	 * 重写自定义接口中排序方法
	 * 排序规则:先年龄降序排序,年龄相同再按姓名降序排序
	 */
	@Override
	public int compare(StudentA o1, StudentA o2) {
		if (o1.sage.compareTo(o2.sage)!=0) {
			return -o1.sage.compareTo(o2.sage);
		} else {//年龄相同
			return -o1.sname.compareTo(o2.sname);
		}
	}
}

public static void main(String[] args) {
		//创建一个排序器对象
		MyComparator mc=new MyComparator();
		//创建一个集合,将自定义的排序器对象作为treeSet的构造方法参数
		TreeSet<StudentA> tset1=new TreeSet<>(mc);
		//向集合中添加元素
		tset1.add(new StudentA("hh", 66));
		tset1.add(new StudentA("dd", 66));
		tset1.add(new StudentA("kk", 88));
		tset1.add(new StudentA("aa", 44));
		tset1.add(new StudentA("yy", 77));
		tset1.add(new StudentA("hh", 16));
		
		//获得集合迭代器
		Iterator<StudentA> it1=tset1.iterator();
		//循环判断迭代器后面是否有元素可迭代
		while (it1.hasNext()) {
			StudentA n1=it1.next();
			System.out.println(n1);
		}
		System.out.println("------------------------------");
		
		//删除集合中元素
		tset1.remove(new StudentA("aa", 44));
		
		//遍历集合
		for (StudentA n2 : tset1) {
			System.out.println(n2);
		}
		System.out.println("------------------------------");
		
		//清空集合
		tset1.clear();
		//遍历集合
		for (StudentA n2 : tset1) {
			System.out.println(n2);
		}
	}

12.4.3:匿名内部类自定义排序器:

public static void main(String[] args) {
		//创建一个集合,将自定义的排序器对象作为treeSet的构造方法参数
		TreeSet<StudentB> tset1=new TreeSet<>(new Comparator<StudentB>() {
			/**
			 * 重写自定义排序器接口中排序方法
			 * 排序规则:年龄升序排序,年龄相同按姓名升序排序
			 */
			@Override
			public int compare(StudentB o1, StudentB o2) {
				if (o1.sage.compareTo(o2.sage)!=0) {
					return o1.sage.compareTo(o2.sage);
				} else {//年龄相同
					return o1.sname.compareTo(o2.sname);
				}
				
			}
		});
		//向集合中添加元素
		tset1.add(new StudentB("hh", 66));
		tset1.add(new StudentB("dd", 66));
		tset1.add(new StudentB("kk", 88));
		tset1.add(new StudentB("aa", 44));
		tset1.add(new StudentB("yy", 77));
		tset1.add(new StudentB("hh", 16));
		
		//获得集合迭代器
		Iterator<StudentB> it1=tset1.iterator();
		//循环判断迭代器后面是否有元素可迭代
		while (it1.hasNext()) {
			StudentB n1=it1.next();
			System.out.println(n1);
		}
		System.out.println("------------------------------");
		
		//删除集合中元素
		tset1.remove(new StudentB("aa", 44));
		
		//遍历集合
		for (StudentB n2 : tset1) {
			System.out.println(n2);
		}
		System.out.println("------------------------------");
		
		//清空集合
		tset1.clear();
		//遍历集合
		for (StudentB n2 : tset1) {
			System.out.println(n2);
		}
	}

13 Map

13.1.HashMap

存储key-value对.Key无序的,唯一的单一对象.底层采用数组+链表结构存值.

  • Key的唯一性:通过HashCode()和equals()来保证.
    注意: HashMap的key的泛型类中要重写HashCode()和equals().
    在这里插入图片描述
public static void main(String[] args) {
		//创建一个集合
		Map<Integer, String> hmap1=new HashMap<>();
		//向集合中存值
		hmap1.put(55, "kk");
		hmap1.put(11, "cc");
		hmap1.put(44, "aa");
		hmap1.put(55, "bb");
		
		//将map集合转换为set集合,set集合中每个空间存key-value对
		Set<Entry<Integer, String>> hset1=hmap1.entrySet();
		/*遍历set集合*/
		//获得set集合迭代器对象
		Iterator<Entry<Integer, String>> it1=hset1.iterator();
		//循环判断迭代器后面是否有元素可迭代
		while (it1.hasNext()) {
			Entry<Integer, String> e1=it1.next();
			System.out.println(e1.getKey()+","+e1.getValue());
		}
		System.out.println("--------------------------------");
		
		//删除集合中元素
		hmap1.remove(11);
		
		//将map集合中所有Key存在set集合中
		Set<Integer> set2=hmap1.keySet();
		//遍历所有Key
		for (Integer k : set2) {
			//通过K得到value
			System.out.println(k+","+hmap1.get(k));
		}
	}
public static void main(String[] args) {
		//创建一个集合
		Map<Worker, String> hmap1=new HashMap<>();
		//向集合中存值
		hmap1.put(new Worker("唐三", 1000.0), "kk");
		hmap1.put(new Worker("比比东", 3000.0), "cc");
		hmap1.put(new Worker("千仞雪", 5000.0), "aa");
		hmap1.put(new Worker("唐昊", 10000.0), "bb");
		hmap1.put(new Worker("唐三", 1000.0), "uu");
		
		//将map集合转换为set集合,set集合中每个空间存key-value对
		Set<Entry<Worker, String>> hset1=hmap1.entrySet();
		/*遍历set集合*/
		//获得set集合迭代器对象
		Iterator<Entry<Worker, String>> it1=hset1.iterator();
		//循环判断迭代器后面是否有元素可迭代
		while (it1.hasNext()) {
			Entry<Worker, String> e1=it1.next();
			System.out.println(e1.getKey()+","+e1.getValue());
		}
		System.out.println("--------------------------------");
		
		//删除集合中元素
		hmap1.remove(new Worker("比比东", 3000.0));
		
		//将map集合中所有Key存在set集合中
		Set<Worker> set2=hmap1.keySet();
		//遍历所有Key
		for (Worker k : set2) {
			//通过K得到value
			System.out.println(k+","+hmap1.get(k));
		}
	}

13.2.TreeMap

存key-value对.Key无序但是可排序,唯一的单一对象.底层采用二叉树结构存值.
注意: TreeMap一定要用排序器,如果TreeMap的构造方法中没有传递排序器对象,默认用的是自然排序器,要求TreeMap的Key的泛型类中要实现Comparable接口,重写排序方法;如果TreeMap的构造方法中传递排序器对象,用的是自定义排序器,在自定义排序器类中重写排序方法.

  • Key的唯一性:通过排序器的排序方法返回0,表示Key相同Key不存Value覆盖.
  • Key的可排序性:通过排序器的排序方法返回正数排在右子节点(后面),返回负数排在左子节点(前面).
    在这里插入图片描述
public static void main(String[] args) {
		//创建一个集合
		Map<Integer, String> hmap1=new TreeMap<>();
		//向集合中存值
		hmap1.put(55, "kk");
		hmap1.put(11, "cc");
		hmap1.put(44, "aa");
		hmap1.put(55, "bb");
		
		//将map集合转换为set集合,set集合中每个空间存key-value对
		Set<Entry<Integer, String>> hset1=hmap1.entrySet();
		/*遍历set集合*/
		//获得set集合迭代器对象
		Iterator<Entry<Integer, String>> it1=hset1.iterator();
		//循环判断迭代器后面是否有元素可迭代
		while (it1.hasNext()) {
			Entry<Integer, String> e1=it1.next();
			System.out.println(e1.getKey()+","+e1.getValue());
		}
		System.out.println("--------------------------------");
		
		//删除集合中元素
		hmap1.remove(11);
		
		//将map集合中所有Key存在set集合中
		Set<Integer> set2=hmap1.keySet();
		//遍历所有Key
		for (Integer k : set2) {
			//通过K得到value
			System.out.println(k+","+hmap1.get(k));
		}
	}

13.3.排序器:

13.3.1:自然排序器(Comparable)

/**
 * 员工类,实现自然排序器接口,重写排序方法
 */
public class WorkerA implements Comparable<WorkerA>{
	public String wname;
	public Double salary;
	
	public WorkerA() {
		// TODO Auto-generated constructor stub
	}
	
	public WorkerA(String wname, Double salary) {
		super();
		this.wname = wname;
		this.salary = salary;
	}

	@Override
	public String toString() {
		return "Worker [wname=" + wname + ", salary=" + salary + "]";
	}

	/**
	 * 重写自然排序器接口中排序方法
	 * 排序规则:先按工资降序,工资相同按姓名升序
	 * @param this当前添加员工对象
	 * @param o表示从根节点开始,每个要比较的员工对象
	 */
	@Override
	public int compareTo(WorkerA o) {
		if (this.salary.compareTo(o.salary)!=0) {
			return -this.salary.compareTo(o.salary);
		} else {//工资相同,按姓名排序
			return this.wname.compareTo(o.wname);
		}
	}
}
public static void main(String[] args) {
		//创建集合
		TreeMap<WorkerA, String> tmap2=new TreeMap<>();
		//向集合中添加元素
		tmap2.put(new WorkerA("a小舞", 20000.0), "aa");
		tmap2.put(new WorkerA("c荣荣", 20000.0), "ii");
		tmap2.put(new WorkerA("b竹青", 50000.0), "ww");
		tmap2.put(new WorkerA("c比比东", 20000.0), "cc");
		
		//将map集合转换为set集合,set集合中每个空间存key-value
		Set<Entry<WorkerA, String>> set2=tmap2.entrySet();
		//获得集合的迭代器
		Iterator<Entry<WorkerA, String>> it2=set2.iterator();
		//循环判断
		while (it2.hasNext()) {
			Entry<WorkerA, String> e2=it2.next();
			System.out.println(e2.getKey()+"="+e2.getValue());
		}
		System.out.println("**********************************");
		
		//删除集合中元素
		tmap2.remove(new WorkerA("小舞", 20000.0));
		
		//获得map集合中所有的Key存set中
		Set<WorkerA> set3=tmap2.keySet();
		//遍历
		for (WorkerA k : set3) {
			//通过key得到value值
			System.out.println(k+"="+tmap2.get(k));
		}
	}

13.3.2:自定义排序器(Comparator)

:/**
 * 自定义排序器类,重写排序方法
 */
public class MyComparator implements Comparator<WorkerB>{

	/**
	 * 重写自定义排序器接口中排序方法
	 * 排序规则:工资降序,工资相同按姓名升序
	 * @param o1当前要添加对象
	 * @param o2从根节点开始每个要比较对象
	 */
	@Override
	public int compare(WorkerB o1, WorkerB o2) {
		if (o1.salary.compareTo(o2.salary)!=0) {
			return -o1.salary.compareTo(o2.salary);
		} else {//工资相同
			return o1.wname.compareTo(o2.wname);
		}
	}
}

public static void main(String[] args) {
		//创建排序器对象
		MyComparator mc=new MyComparator();
		//创建集合,将自定义排序器对象作为构造方法的参数
		TreeMap<WorkerB, String> tmap2=new TreeMap<>(mc);
		//向集合中添加元素
		tmap2.put(new WorkerB("a小舞", 20000.0), "aa");
		tmap2.put(new WorkerB("c荣荣", 20000.0), "ii");
		tmap2.put(new WorkerB("b竹青", 50000.0), "ww");
		tmap2.put(new WorkerB("c比比东", 20000.0), "cc");
		
		//将map集合转换为set集合,set集合中每个空间存key-value
		Set<Entry<WorkerB, String>> set2=tmap2.entrySet();
		//获得集合的迭代器
		Iterator<Entry<WorkerB, String>> it2=set2.iterator();
		//循环判断
		while (it2.hasNext()) {
			Entry<WorkerB, String> e2=it2.next();
			System.out.println(e2.getKey()+"="+e2.getValue());
		}
		System.out.println("**********************************");
		
		//删除集合中元素
		tmap2.remove(new WorkerB("小舞", 20000.0));
		
		//获得map集合中所有的Key存set中
		Set<WorkerB> set3=tmap2.keySet();
		//遍历
		for (WorkerB k : set3) {
			//通过key得到value值
			System.out.println(k+"="+tmap2.get(k));
		}
	}

13.4:匿名内部类自定义排序器

public static void main(String[] args) {
		//创建集合,将自定义排序器对象作为构造方法的参数
		TreeMap<WorkerC, String> tmap2=new TreeMap<>(new Comparator<WorkerC>() {

			/**
			 * 重写自定义排序器接口中排序方法
			 * 排序规则:工资降序,工资相同按姓名升序
			 * @param o1当前要添加对象
			 * @param o2从根节点开始每个要比较对象
			 */
			@Override
			public int compare(WorkerC o1, WorkerC o2) {
				if (o1.salary.compareTo(o2.salary)!=0) {
					return -o1.salary.compareTo(o2.salary);
				} else {//工资相同
					return o1.wname.compareTo(o2.wname);
				}
			}
		});
		//向集合中添加元素
		tmap2.put(new WorkerC("a小舞", 20000.0), "aa");
		tmap2.put(new WorkerC("c荣荣", 20000.0), "ii");
		tmap2.put(new WorkerC("b竹青", 50000.0), "ww");
		tmap2.put(new WorkerC("c比比东", 20000.0), "cc");
		
		//将map集合转换为set集合,set集合中每个空间存key-value
		Set<Entry<WorkerC, String>> set2=tmap2.entrySet();
		//获得集合的迭代器
		Iterator<Entry<WorkerC, String>> it2=set2.iterator();
		//循环判断
		while (it2.hasNext()) {
			Entry<WorkerC, String> e2=it2.next();
			System.out.println(e2.getKey()+"="+e2.getValue());
		}
		System.out.println("**********************************");
		
		//删除集合中元素
		tmap2.remove(new WorkerC("小舞", 20000.0));
		
		//获得map集合中所有的Key存set中
		Set<WorkerC> set3=tmap2.keySet();
		//遍历
		for (WorkerC k : set3) {
			//通过key得到value值
			System.out.println(k+"="+tmap2.get(k));
		}
	}

13.5.(了解)Hashtable

哈希表.线程安全,运行效率慢;不允许null作为key或者是value.

public static void main(String[] args) {
		//创建一个集合
		Map<Integer, String> hmap1=new Hashtable();
		//向集合中存值
		hmap1.put(55, "kk");
		hmap1.put(11, "cc");
		hmap1.put(44, "aa");
		hmap1.put(55, "bb");
		//HashTable不可以存null
		//hmap1.put(null, null);
		
		//将map集合转换为set集合,set集合中每个空间存key-value对
		Set<Entry<Integer, String>> hset1=hmap1.entrySet();
		/*遍历set集合*/
		//获得set集合迭代器对象
		Iterator<Entry<Integer, String>> it1=hset1.iterator();
		//循环判断迭代器后面是否有元素可迭代
		while (it1.hasNext()) {
			Entry<Integer, String> e1=it1.next();
			System.out.println(e1.getKey()+","+e1.getValue());
		}
		System.out.println("--------------------------------");
		
		//删除集合中元素
		hmap1.remove(11);
		
		//将map集合中所有Key存在set集合中
		Set<Integer> set2=hmap1.keySet();
		//遍历所有Key
		for (Integer k : set2) {
			//通过K得到value
			System.out.println(k+","+hmap1.get(k));
		}
	}

13.6.HashMap VS HashTable

都按Key-value对存值,实现Map接口,底层采用数组+链表结构存值.

  • 1:推出时间不同:在jdK1.2推出HashMap,HashTable在Jdk1.2之前就推出.
  • 2:初始容量和扩容不同:HashMap的默认初始容量为16,底层按2的倍数扩容;
    HashTable的默认初始容量为11,底层按2倍+1扩容;
  • 3:存null不同:HashMap允许null作为key或者是value;
    HashTable不允许null作为key或者是value;
  • 4:线程安全性不同:HashMap在单线程中使用效率较高,在多线程中使用不安全.
    HashTable在单线程中使用效率较低,在多线程中使用安全.
  • 5:HashTable有HashMap所有的方法,还有自己独有方法.

13.7.Properties

配置文件类,按key-value存取值,要求key和value都是String类型.

  • 适用场景:一般用于配置文件的读取.
public static void main(String[] args) {
		//创建Properties对象
		Properties pp=new Properties();
		//存值
		pp.setProperty("uname", "root");
		pp.setProperty("pwd", "123456");
		
		//获取值
		System.out.println("用户名:"+pp.get("uname")+",密码:"+pp.get("pwd"));
	}

14.小结

  • 1.ArrayList:存储有序,可重复的单一对象.底层采用Object[]存值.
    优点:遍历效率高,按顺序添加和修改
    缺点:删除和按索引添加效率低

  • 2.LinkedList:存储有序,可重复的单一对象.底层采用双向链表结构存值.
    优点:删除和添加效率高
    缺点:遍历效率低,修改效率低.

  • 3.HashSet:存储无序的,唯一的单一对象.底层采用HashMap的Key存值.
    唯一性(去重):通过泛型类中重写HashCode()和equals();

  • 4.TreeSet:存储无序的可排序的,唯一的单一对象.底层采用TreeMap的Key存值.
    注意:TreeSet一定要用排序器,如果TreeSet的构造方法中没有传对象,默认用的自然排序器,要 求TreeSet的泛型类中实现自然排序器(Comparable)接口,重写排序方法;如果 TreeSet的构造方法中传对象了,用自定义排序器,重写排序方法.
    唯一性(去重):通过排序器的排序方法返回0来去重.
    可排序性:通过排序器的排序方法返回负数排在前面,返回正数排在后面.

  • 5.HashMap:按Key-value对存值.Key存储无序的,唯一的单一对象.底层采用数组+链表结构存值.
    Key的唯一性:通过Key的泛型类中重写HashCode()和equals();

  • 6.TreeMap:按Key-value对存值.Key存储无序的可排序的,唯一的单一对象.
    底层采用二叉树结构存值.
    注意: TreeMap一定要用排序器,如果TreeMap的构造方法中没有传对象,默认用的自然排序器,要 求TreeMap的Key的泛型类中实现自然排序器(Comparable)接口,重写排序方法;如果 TreeMap的构造方法中传对象了,用自定义排序器,重写排序方法.
    Key的可排序性:通过排序器的排序方法返回负数排在前面,返回正数排在后面.
    Key的唯一性(去重):通过排序器的排序方法返回0来去重.

  • 7.去重:用HashSet,HashMap,TreeSet,TreeMap去重.首选HashSet.
    HashSet和HashMap采用重写HashCode()和equals()去重;
    TreeSet和TreeMap采用排序器的排序方法返回0去重.

  • 8.排序:用TreeSet和TreeMap来排序.首选TreeSet排序.
    TreeSet和TreeMap采用排序器的排序方法返回负数排在前面,返回正数排在后面来排序的.

个人笔记,思路,仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值