集合11111

集合框架

1
.集合家族体系

Collection是父接口

List和Set是子接口

Map也是一个接口

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oLkYFlgZ-1622787250471)(.\img\集合体系.png)]

2.List接口
2.1 ArrayList

ArrayList

ArrayList 有序的 有下标 线程不安全 允许为null

  • 1.初始为一个空的Object数组
    • 2.当我们第一次添加元素的时候将 数组的长度赋值为10
      3.当集合长度不够用的时候,扩容是原来的1.5倍
      4.查询快 添加 删除 慢
package com.qfedu.test1;

import java.util.Date;

/**
 * 	新闻信息类
 * 	标题
 * 	作者
 * 	日期
 * 	内容	
 * @author WHD
 *
 */
public class News {
	private String title;
	private String author;
	private Date date;
	private String content;
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
	public Date getDate() {
		return date;
	}
	public void setDate(Date date) {
		this.date = date;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public News() {
	}
	public News(String title, String author, Date date, String content) {
		this.title = title;
		this.author = author;
		this.date = date;
		this.content = content;
	}
	@Override
	public String toString() {
		return "News [title=" + title + ", author=" + author + ", date=" + date + ", content=" + content + "]";
	}
	
}

package com.qfedu.test1;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
/**
 * 	ArrayList 有序的 有下标 线程不安全 允许为null
 * 	1.初始为一个空的Object数组
 * 	2.当我们第一次添加元素的时候将 数组的长度赋值为10
 * 	3.当集合长度不够用的时候,扩容是原来的1.5倍
 * 	4.查询快 添加 删除 慢 
 * @author WHD
 *
 */
public class TestNews {
	public static void main(String[] args) {
		// 使用ArrayList集合存放新闻信息
		ArrayList<News> list = new ArrayList<News>();
		Date date = new Date(2020,8,1);
		News n1 = new News("周末竟然和女朋友做这事,全世界都震惊了", "赵四", new Date(), "在家做饭");
		News n2 = new News("周末竟然和女朋友做这事,全世界都震惊了", "广坤", new Date(), "在家洗衣服");
		News n3 = new News("周末竟然和女朋友做这事,全世界都震惊了", "小宝", date, "在家看电视");
		
		
		list.add(n1);
		list.add(n2);
		list.add(n3);
		
		System.out.println("集合原长度" + list.size());
		list.remove(0);
		list.remove(n2);
		System.out.println("删除第二个元素之后集合长度" + list.size());
		News n4 = new News("周末竟然和女朋友做这事,全世界都震惊了", "小沈阳", date, "在家跳舞");
		News modifyNews = list.set(1, n4);
		
		System.out.println("修改之前的元素内容" + modifyNews);
		System.out.println("修改之后的元素内容" + list.get(1));
		System.out.println("清空集合之前" + list.isEmpty());
	
		
		System.out.println("===========================");
		// 遍历集合
		// for循环
		// 第一种方式
		for(int i = 0; i < list.size() ; i ++) {
			System.out.println(list.get(i));
		}
		
		System.out.println("===========================");
		
		// 第二种方式 增强for循环
		// 格式 for(Type name : list){
		// 
		// }
		for(News ns : list) {
			System.out.println(ns);
		}
		System.out.println("===========================");
		
		// 第三种方式 迭代器的方式 
		// 迭代器必须使用while循环类遍历 因为 没有下标
		Iterator<News> it = list.iterator();
		while(it.hasNext()) {
			News next = it.next();
			System.out.println(next);
		}
		
		
		list.clear();
		System.out.println("清空集合之后" + list.isEmpty());
	}
}

遍历ArrayList方法

1.普通for循环遍历

2.增强for循环遍历(foreach)

3.迭代器遍历

总结:

三种遍历方式的优缺点:

  • 1.for循环是基于下标查找的 所以我们可以做一些基于下标的操作
    • 2.如果不需要对下标的操作 推荐使用增强for循环或者迭代器
      3.不要在增加for循环或者迭代器中删除或者添加数据 将会报并发访问异常
      4.增强for内部依然是迭代实现的,是JDK1.5新添加的内容,迭代器是JDK1.2有的
package com.qfedu.test1;

import java.util.ArrayList;
import java.util.Iterator;
/**
 * 	三种遍历方式的优缺点:
 * 	1.for循环是基于下标查找的 所以我们可以做一些基于下标的操作 
 * 	2.如果不需要对下标的操作 推荐使用增强for循环或者迭代器 
 * 	3.不要在增加for循环或者迭代器中删除或者添加数据 将会报并发访问异常
 * @author WHD
 *
 */
public class TestForeach {
	public static void main(String[] args) {
		ArrayList<Integer> list1 = new ArrayList<Integer>(); 
		for (int i = 0; i < 200000; i++) {
			list1.add(i);
		}
		
		long startTime = System.currentTimeMillis();
		for (int i = 0; i < list1.size(); i++) {
			if(i == 1) {
				list1.remove(i);
			}
			System.out.println(list1.get(i));
		}
		long endTime = System.currentTimeMillis();
		System.out.println("普通循环耗时" + (endTime - startTime)); // 1700 毫秒
		
		
		startTime = System.currentTimeMillis();
		// 增强for循环 是JDK1.5 才有的 内部依然使用迭代器实现
		for(Integer i : list1) {
			
			System.out.println(i);
		}
		endTime = System.currentTimeMillis();
		System.out.println("增强循环耗时" + (endTime - startTime)); // 1439毫秒
		
		
		
		startTime = System.currentTimeMillis();
		// 迭代器  1.2 
		Iterator<Integer> it = list1.iterator();
		
		while(it.hasNext()) {
			list1.remove(it.next());
			System.out.println(it.next());
		}
		endTime = System.currentTimeMillis();
		System.out.println("迭代器耗时" + (endTime - startTime)); // 600毫秒
	}
}

ArrayList源代码实现

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8v1VUppY-1622787250473)(.\img\ArrayList无参构造.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VZfAE6Bp-1622787250475)(.\img\初始化数组长度.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N44MQ7a6-1622787250476)(.\img\确保有足够的空间,如果没有就扩容.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rqKqHmnb-1622787250478)(.\img\扩容并且赋值数组.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-czVNA7j8-1622787250478)(.\img\ArrayList删除元素.png)]

总结:ArrayList特点是查询快,添加和删除慢,因为涉及到移动元素,所以我们在一些查询占比高于删除和添加的场景可以使用。比如,电商系统

2.2 Vector

Vector类有和ArrayList相同的API,但是是线程安全的

面试题:

ArrayList和Vector区别?

1.Vector是JDK1.0就有的,ArrayList是JDK1.2才有的

2.Vector无参构造直接给数组长度赋值为10,而ArrayList是第一次添加内容的时候才给数组长度赋值为10

3.Vector扩容是原来的两倍,ArrayList是原来的1.5倍

4.Vector是线程安全的,ArrayList是线程不安全的

遍历方式与ArrayList一致

package com.qfedu.test1;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

public class TestVector {
	public static void main(String[] args) {
		// 此类与ArrayList有相同的API 先存在的  线程安全的 
		Vector v1 = new Vector(); // 无参构造直接初始化为10
		v1.add(20);
		v1.add("赵四");
		v1.add(23.0);
		
		// 热插拔 
		List<Object> v2 = new Vector<Object>();
		v2.add(20D);
		v2.add(21D);
		v2.add(22D);
		v2.add(23D);
		v2.add(24D);
		
		System.out.println("原集合长度" + v2.size());
		System.out.println("删除的元素是" + v2.remove(0));
		System.out.println("删除一个元素以后" + v2.size());
		System.out.println("第一个元素" + v2.get(0));
		v2.set(0, 66D);
		System.out.println("第一个元素" + v2.get(0));
		
		System.out.println("清空之前是否为空" + v2.isEmpty());
		
		System.out.println("================================");
		
		for (int i = 0; i < v2.size(); i++) {
			System.out.println(v2.get(i));
		}
		
		System.out.println("================================");
		for (Object object : v2) {
			System.out.println(object);
		}
		
		System.out.println("================================");
		
		Iterator<Object> it = v2.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
		
		v2.clear();
		System.out.println("清空之后是否为空" +v2.isEmpty());
		
	}
}

2.3 LinkedList

特点:

无序的,可以为null,线程不安全的,双向链表

除了提供和ArrayList方法名称相同的方法之外 还提供了链表数据结构特有的一些

单独用于操作 头部 和 尾部的一些方法

添加、删除效率高

查询效率低

使用场景:

仓库管理系统,或者图书管理系统,涉及到频繁的修改数据的

package com.qfedu.test1;

import java.util.LinkedList;

/**
 * 	LinkedList 也是List接口的实现类 也是Deque接口的实现类
 * 	LinkedList既是一个线性表也是一个队列(双向链表)
 *	除了提供和ArrayList方法名称相同的方法之外 还提供了链表数据结构特有的一些
 *	单独用于操作 头部 和 尾部的一些方法 	
 * @author WHD
 *
 */
public class Test1 {
	public static void main(String[] args) {
		LinkedList list = new LinkedList();
		// 无序的 是指空间不连续 
		list.add("a");
		list.add(20);
		list.addFirst("B");
		list.addLast("C");
		list.add(1, "中文");
		
		
		System.out.println("集合长度" + list.size());
		System.out.println("第一个元素是" + list.getFirst());
		System.out.println("第二个元素" + list.get(1));
		list.getLast();
		list.removeFirst();
		list.removeLast();
		list.remove();
		
		for (Object object : list) {
			System.out.print(object + "\t");
		}
		System.out.println();
		System.out.println("删除第一个元素以后,集合长度" + list.size());
		
		list.set(1, "A");
		
		for (Object object : list) {
			System.out.print(object + "\t");
		}
		System.out.println();
		
		System.out.println("集合是否为空" + list.isEmpty());
		
		list.clear();
		
		System.out.println("集合是否为空" + list.isEmpty());
		
		
		
	}
}

遍历LinkedList

三种 方式

1.普通for循环

2.增强for循环

3.迭代器

注意:不要使用普通for循环遍历LinkedList

//由于LinkedList是双向链表,因此是算出 i 是在一半前还是一半后,一半前正序遍历、一半后倒序遍历,这就是二分排序。也就是说,LinkedList在get任何一个位置的数据的时候,都会把前面的数据走一遍。假如我有10个数据,那么将要查询1+2+3+4+5+5+4+3+2+1=30次数据,相比ArrayList,却只需要查询10次数据就行了,随着LinkedList的容量越大,差距会越拉越大。

package com.qfedu.test1;

import java.util.Iterator;
import java.util.LinkedList;

public class Test3 {
	public static void main(String[] args) {
		LinkedList<Integer> list = new LinkedList<Integer>();
		for (int i = 0; i < 20; i++) {
			list.addFirst(i);
		}
		System.out.println("=================");
		
		// 1 普通for循环 
		for(int i = 0; i < list.size(); i ++) {
			System.out.println(list.get(i));
		}
		
		
		// 2 增强for循环
		for(Integer i : list) {
			System.out.println(i);
		}
		
		// 3 迭代器
		Iterator<Integer> it = list.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
	}
}

LinkedList源码解读

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3f6xygqt-1622787250479)(.\img\add方法.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WMJ5QkdC-1622787250480)(.\img\addFirst方法.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pwe8MtcR-1622787250481)(.\img\addLast方法.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U1RAa8VL-1622787250482)(.\img\addLast方法内部实现.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hVTQcOil-1622787250483)(.\img\getFirst方法.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f6yJbi2b-1622787250484)(.\img\getLast方法.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VJ08Kepc-1622787250485)(.\img\LinkedList查找元素方法.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5A751MNh-1622787250485)(.\img\removeFirst内部实现.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FXx78Fia-1622787250486)(.\img\remove方法内部实现.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xZVzlIWC-1622787250487)(.\img\每一个元素都是一个Node.png)]

3.Map接口
3.1HashMap

特点:

无序

线程不安全

允许键和值为null 键不能重复

ArrayList是基于数组 有下标 所以查询快 同样也是因为有下标 涉及到移动元素 所以增删慢

LinkedList 基于双向链表 没有下标 所以查询慢 同样也是因为没有下标 增删快

能不能将以上两个集合 结合到一起呢?

可以的 HashMap就是 几乎实现了将两者结合到一起

JDK 1.7 数组 + 单向链表

JDK 1.8 数组 + 单向链表 + 红黑树 当单向的链表的长度大于8时候 转换为红黑树 提高查询效率

扩容 2倍

效率:

增删改查都快只是理想状态,实际中会受到影响,只是会相对提高增删改查的效率,但是缺点是占用空间大

package com.qfedu.test2;

import java.util.ArrayList;
import java.util.HashMap;

public class Test1 {
	public static void main(String[] args) {
		// 定义一个集合 存储成对的信息 
		ArrayList<String> list = new ArrayList<String>();
		list.add("US美国");
		list.add("JP日本");
		list.add("CN中国");
		
		HashMap<String,String> map =new HashMap<String,String>();
		map.put("US", "美国");
		map.put("RU", "俄罗斯");
		map.put("CN", "中国");
		map.put("JP", "小日本");
		System.out.println(map.size());
		// map集合 键和值 都允许为 null 键不能重复 如果重复 那么将覆盖值
		map.put("JP", "日本");
		System.out.println(map.size());
		
		System.out.println(map.get("JP"));
		System.out.println("删除的元素value是" + map.remove("JP"));
		
		System.out.println(map.isEmpty());
		map.clear();
		System.out.println(map.isEmpty());

	}
}

遍历方式

1.获取所有key,根据key获取值

2.获取所有的值

3.获取Set<Entry<?,?>> 获取所有的整条数据的集合

4.获取整条数据的集合迭代器map.entrySet().iterator();

package com.qfedu.test2;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
/**
 * 	HashMap 集合特点
 * 	无序
 * 	线程不安全
 * 	允许键和值为null 键不能重复
 * 	效率
 * 	增删改查
 * 	ArrayList是基于数组 有下标 所以查询快  同样也是因为有下标 涉及到移动元素 所以增删慢
 * 	LinkedList 基于双向链表 没有下标 所以查询慢 同样也是因为没有下标 增删快
 * 	能不能将以上两个集合 结合到一起呢?
 * 	可以的 HashMap就是 几乎实现了将两者结合到一起
 * 	JDK 1.7  数组 + 单向链表 
 * 	JDK 1.8 数组 + 单向链表 + 红黑树  当单向的链表的长度大于8时候 转换为红黑树 提高查询效率
 * 	扩容 2倍 
 *map== {}时,该值为初始容量(初始容量默认为16);当map被填充

/**负载因子,代表了map的填充度有多少,默认是0.75
加载因子存在的原因,还是因为减缓哈希冲突,如果初始桶为16,等到满16个元素才扩容,某些桶里可能就有不止一个元素了。
所以加载因子默认为0.75,也就是说大小为16的HashMap,到了第13个元素,就会扩容成32。
 * @author WHD
 *
 */
public class Test2 {
	public static void main(String[] args) {
		// keySet()  返回所有的key集合 set集合 
		HashMap<String,String> map =new HashMap<String,String>();
		map.put("US", "美国");
		map.put("RU", "俄罗斯");
		map.put("CN", "中国");
		map.put("JP", "小日本");
		
		Set<String> set = map.keySet();
		for (String key : set) {
			System.out.print(key + "\t" + map.get(key));
			System.out.println();
		}
		System.out.println("=================");
		
		// 获取所有的value  values()
		Collection<String> values = map.values();
		for (String value : values) {
			System.out.println(value);
		}
		System.out.println("==================");
		
		Set<Entry<String, String>> entrySet = map.entrySet();
		for(Entry en : entrySet) {
			System.out.println(en.toString());
		}
		System.out.println("==================");
		// 使用迭代器
		Iterator<Entry<String, String>> iterator = map.entrySet().iterator();
		while(iterator.hasNext()) {
			Entry<String, String> next = iterator.next();
			System.out.println(next.getKey() + "===" + next.getValue());
		}
	
	}
}

HashMap数据结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qaAj6UFy-1622787250488)(.\img\HashMap.png)]

3.2Hashtable

面试题:

HashMap和Hashtable的区别?

此类提供与Hashtable相同的实现,但是是线程安全的,默认容量是11,扩容是两倍 + 1,键和值都不允许为null,无序的

package com.qfedu.test2;

import java.util.Hashtable;

/**
 * 	Hashtable 
 * 	无序
 * 	线程安全的
 * 	键和值都不允许null
 * @author WHD
 *
 */
public class Test3 {
	public static void main(String[] args) {
		Hashtable<Integer,String> table = new Hashtable<Integer,String>();
		table.put(1, "A");
		table.put(2, "B");
		table.put(3, "C");
		
		
	}
}


3.3Properties

Properties:属性

Hashtable子类,也是线程安全的,不要使用put或者putAll方法添加内容,因为此类只用于存放键和值都是String类型

使用 + .setProperty(“CN”, “中国”);添加

package com.qfedu.test1;

import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;

/**
 * 	Properties 类 
 * 	Hashtable子类
 * 	线程安全
 * 	键和值都为String
 * 	不要使用put或者putAll方法添加内容
 * 	
 * @author WHD
 *
 */
public class TestProperties {
	public static void main(String[] args) {
//		Properties properties1 = System.getProperties();
//		properties1.list(System.out);
		
		
//		properties.put(20, 20.0); // 不要使用put方法来添加内容
//		
//		properties.get(20);
		
		Properties properties2 = new Properties();
		properties2.setProperty("CN", "中国");
		properties2.setProperty("US", "美国");
		properties2.setProperty("JP", "日本");
		properties2.setProperty("KR", "韩国");
		properties2.setProperty("RU", "俄罗斯");
		
		
		properties2.list(System.out);
		
		
		System.out.println(properties2.size());
		
		System.out.println(properties2.get("CN"));
		
		Set<Entry<Object, Object>> set = properties2.entrySet();
		System.out.println("-- listing properties --");
		for(Entry<Object, Object> entry : set) {
			System.out.println(entry);
		}
		
		
		System.out.println("===============================");
		
		Set<Object> keys = properties2.keySet();
		for(Object key : keys) {
			System.out.println(properties2.get(key));
		}
		System.out.println("===============================");
		
	}
}

3.4TreeMap

TreeMap是可以保证顺序的Map集合,要求键必须可以排序,也就是必须实现Comparable接口,重写CompareTo方法

package com.qfedu.test2;

import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * 	Tree 树 
 * 	TreeMap是有顺序的Map集合 所存放的数据Key值必须可以比较 而且是升序的顺序
 * 	我们自定义的对象必须实现Comparable接口 重写CompareTo方法
 * @author WHD
 *
 */
public class TestTreeMapAndTreeSet {
	public static void main(String[] args) {
		TreeMap<String,String> map  =new TreeMap<String,String>();
		map.put("A","赵四");
		map.put("a","广坤");
		map.put("h","大拿");
		map.put("B","小宝");
		
		map.remove("A");
		
		for(Entry<String,String> entry : map.entrySet()) {
			System.out.println(entry);
		}
		map.clear();
		map.size();
		map.isEmpty();
		
		System.out.println("=================================");
		SortedMap<Person,String> map1 = new TreeMap<Person,String>();
		map1.put(new Person("赵四",20), "A");
		map1.put(new Person("广坤",21), "F");
		map1.put(new Person("小宝",22), "c");
		map1.put(new Person("大拿",23), "B");
		
		System.out.println(map1.size());
		for(Entry<Person,String> entry : map1.entrySet()) {
			System.out.println(entry);
		}
		
		System.out.println("=================================");		
		
	}
}

package com.qfedu.test2;
/**
 *	实现Comparable 自定义比较规则
 */
public class Person implements Comparable<Person>{
	private String name;
	private int age;
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public int compareTo(Person o) {
		if(this.getAge() == o.getAge()) {
			return 0;
		}else if(this.getAge() > o.getAge()) {
			return 1;
		}else {
			return -1;
		}
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}

	
}

4.Set接口
4.1 HashSet

HashSet底层是一个HashMap,因为HashMap键不能重复的特点,所以可以使用HashMap维护一个我们创建HashSet

特点:

  • 无序
    • 不能重复 不允许添加两个对象 A和B A.equals(B) 并且 A和BhashCode相等
      线程不安全
      可以为null
      HashSet去重复是根据对象的hashCode和equals方法比较 都为true 则认为是同一个对象
package com.qfedu.test1;

import java.util.HashSet;
import java.util.Iterator;

/**
 * 	HashSet
 * 	无序
 * 	不能重复 不允许添加两个对象 A和B  A.equals(B) 
 * 	线程不安全
 * 	可以为null
 * 	HashSet去重复是根据对象的hashCode和equals方法比较 都为true 则认为是同一个对象
 * @author WHD
 *
 */
public class TestHashSet {
	public static void main(String[] args) {
		HashSet<String> set = new HashSet<String>();
		set.add("A");
		set.add("hello");
		set.add("20");
		set.add("中国");
		System.out.println("第二次添加A" + set.add("A"));
		
		
		System.out.println(set.size());
		for(String str : set) {
			System.out.println(str);
		}
		
		System.out.println("=======================");
		Iterator<String> it = set.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
		System.out.println("=======================");
		
		
		System.out.println(set.remove("A"));
		System.out.println(set.size());
		
		set.clear(); // 清空集合
		System.out.println(set.isEmpty());
	}
}

4.2LinkedHashSet

HashSet的子类,基于链表的HashSet,可以保证数据的顺序,顺序就是插入的顺序

package com.qfedu.test1;

import java.util.Iterator;
import java.util.LinkedHashSet;

/**
 * 	HashSet是无序的 不能保证顺序
 * 	如果需要保证顺序 并且元素不能重复  可以使用LinkedHashSet
 * 	LinkedHashSet是基于链表的 HashSet  可以保证元素的顺序  插入顺序
 * 
 * @author WHD
 *
 */
public class TestLinkedHashSet {
		public static void main(String[] args) {
			LinkedHashSet<String> set = new LinkedHashSet<String>();
			set.add("A");
			set.add("hello");
			set.add("中国");
			set.add("千锋");
			set.add("666");
			System.out.println("=======================");
			for(String str : set) {
				System.out.println(str);
			}
			System.out.println("=======================");
			Iterator<String> it = set.iterator();
			while(it.hasNext()) {
				System.out.println(it.next());
			}
			System.out.println("=======================");
			set.remove("A");
			
			System.out.println(set.size());
			set.clear();
			
			System.out.println("清空集合以后" + set.isEmpty());
			
			
		}
}
4.3 TreeSet

TreeSet是可以保证顺序的Set集合,与LinkedHashSet不同,TreeSet是-nkedHashSet是按照插入的顺序,TreeSet底层是维护的一个TreeMap,TreeSet要求保存的内容必须可以排序,也就是必须实现Comparable接口,重写CompareTo方法

package com.qfedu.test2;

import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * 	Tree 树 
 * 	TreeMap是有顺序的Map集合 所存放的数据Key值必须可以比较 而且是升序的顺序
 * 	我们自定义的对象必须实现Comparable接口 重写CompareTo方法
 * @author WHD
 *
 */
public class TestTreeMapAndTreeSet {
	public static void main(String[] args) {
		TreeSet<String> set = new TreeSet<String>();
		set.add("你好");
		set.add("A");
		set.add("B");
		set.add("hello");
		
		for(String str : set) {
			System.out.println(str);
		}

		TreeSet<Worker> set1 = new TreeSet<Worker>();
		
		set1.add(new Worker());
		set1.add(new Worker());
		set1.add(new Worker());
		set1.add(new Worker());
		System.out.println(set1.size());

	}
}
package com.qfedu.test2;

public class Worker implements Comparable<Worker>{

	@Override
	public int compareTo(Worker o) {
		return 0; // 此处没有定义比较规则 同一返回0 那么将只能添加一个Worker对象 因为所有的Worker对象相比都相等
	}

}

5.泛型

泛型

作用:相当于一个 占位 符 可以规范数据类型 有点类似于Object的作用 但是注意不能类型转换

适用场景:

接口,类,抽象类,形参,返回值

泛型可以是任何的字母,一般常用的:

T:Type

E:Element

K:Key

V:Value

package com.qfedu.test2;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 	泛型 <T>
 * 	作用:相当于一个  占位  符 可以规范数据类型  有点类似于Object的作用 但是注意不能类型转换 
 * 	使用场景:
 * 	接口 类
 * 	方法形参 返回值  
 * 	占位符 T Type   E Element  K key  V value   
 * @author WHD
 *
 */
public class TestGeneric {
	public static void main(String[] args) {
		AImpl1 ai = new AImpl1();
		ai.m1("hello wolrd");
		
		AImpl2 ai2 = new AImpl2();
		ai2.m1(20);
		B<String> b = new B<String>();
		b.m1();
		B<Integer> b1 = new B<Integer>();
		b1.m2(1);
		E.m1("String");
	}
}

class C<K,V>{
	public V m1(K k) {
		return null;
	}
	
}

class E{
	public static <T> void m1(T t) {
		System.out.println(t);
	}
}

class B<T>{
	public T m1() {
		return null;
	}
	
	public void m2(T t) {
		System.out.println(t);
	}
	
}


interface A<T>{
	void m1(T sb);
	
	void m2(Object obj);
	T m3();
}

class AImpl1 implements A<String>{
	@Override
	public void m1(String sb) {
		
	}
	@Override
	public void m2(Object obj) {
		
	}
	@Override
	public String m3() {
		return null;
	}
	
}

class AImpl2 implements A<Integer>{

	@Override
	public void m1(Integer i) {
		System.out.println(i);
	}

	@Override
	public void m2(Object obj) {
		
	}

	@Override
	public Integer m3() {
		return null;
	}
	
}


class Animal{
	
}


class Dog extends Animal{
	
}

class Cat extends Animal{
	
}

class Test{
	/**
	 * 	? extends Animal 表示泛型可以是Animal或者Animal的子类
	 * @param set
	 */
	public void m1(Set<? extends Animal> set) {
		
	}
	
	public void m2(List<? super Dog> list) {
		
	}
	
//	public void m3(List<Dog extends ?> list) {
//		
//	}
	
	public static void main(String[] args) {
		Test test = new Test();
		test.m1(new HashSet<Dog>());
		test.m1(new HashSet<Cat>());
		test.m1(new HashSet<Animal>());
//		test.m1(new HashSet<String>());
		test.m2(new ArrayList<Dog>());
		test.m2(new ArrayList<Animal>());
//		test.m2(new ArrayList<Cat>());
		test.m2(new ArrayList<Object>());
	}
}

  • 111111
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值