集合框架,(后续补图)

线性数据结构1 栈,带你了解线性数据结构 阅读详情

集合框架

1.集合家族体系

Collection是父接口

List和Set是子接口

Map也是一个接口

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uoa4euHA-1607303007236)(.\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-jwciJwrL-1607303007252)(.\img\ArrayList无参构造.png)]

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

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

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-01zDgOpy-1607303007292)(.\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

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-NzshxLFh-1607303007299)(.\img\add方法.png)]

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

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

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

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

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

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

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

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r5p4Kn55-1607303007357)(.\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倍 
 * @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-oKExPN3x-1607303007364)(.\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类型

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集合,与LinkeHashSet不同,TreeSet是按照比较规则定义的顺序,LinkedHashSet是按照插入的顺序,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>());
	}
}


图拉姆西有限性猜想完全解决:匹配与奇星图是关键 在图论与组合数学中,拉姆西理论探讨的是在足够大的结构中必然出现特定规律性子结构的现象,其核心概念是拉姆西数,用于量化这一“必然出现”所需的最小结构规模。其基本原理在于,当系统规模超越某个阈值时,无序中必然蕴含有序。这一理论具有重要的技术价值,它为理解复杂系统的内在规律、网络分析与算法设计中的极值问题提供了理论基础。典型的应用场景包括社交网络分析、编码理论以及计算机科学中的下界证明。本文聚焦于图拉姆西有限性猜想,该猜想旨在分类哪些图对具有有限的拉姆西数。研究表明,**匹配**和**奇星图**是决定有限性的两类 阅读详情

相关推荐

最大独立集问题:从图论核心到工程实践的求解策略与应用

在图论中,独立集是指图中任意两个顶点之间都没有边直接相连的顶点集合,而最大独立集则是所有独立集中顶点数量最多的那个。其核心原理在于从复杂的关联网络中,寻找一个满足特定约束(顶点间无连接)的最大子结构。这一概念具有重要的技术价值,因为它为许多现实世界中的资源分配、冲突避免和优化调度问题提供了数学模型。例如,在无线通信中用于避免信号干扰的频段分配,在社交网络中用于识别互不相识的最大用户群体,或在任务调度系统中用于寻找能并行执行的最大任务子集,这些都可以建模为最大独立集问题。求解最大独立集是NP难问题,意味着没有

weixin_33965305的博客 716

5.4 自然数

集合论 5.4 自然数

诗弈羽弦的博客 886

基础集合论 第三章 2 自然数集

后继 对于任意集合 a,a, 称 a∪{a} a \cup \{ a \} 为 aa 的后继,记作 a+:a^+: a+=a∪{a}a^+ = a \cup \{a\} 易知 a∈a+,a⊆a+,a \in a ^+, a \subseteq a ^+, 定义 0=∅,1=0+,2=1+,...0 = \emptyset , 1 = 0^+, 2 = 1^+, ... 定理 1

jiongjiong 的专栏 1481

集合之间的继承关系

集合之间的关系:

whycmpx的博客 988

【信息科学与工程学】【数据科学】数据科学领域 第六篇 算法设计 01

算法设计

weixin_49199313的博客 1501

Utrust4701F与Utrust2700R读写器在银河麒麟系统的安装及测试步骤说明

Utrust4701F与Utrust2700R读写器支持银河麒麟系统,广泛应用会员管理、支付管理等领域。本文将重点介绍Utrust4701F与Utrust2700R读写器在银河麒麟系统的安装及测试步骤说明。以上方法适用于主流国产操作系统,如 优麒麟(UbuntuKylin)/ 中标麒麟(NeoKylin) / UOS(统信操作系统)/ 中兴新支点 / 红旗 linux(redflag linux)/ 普华 Linux(I-soft OS) / 威科乐恩 Linux(WiOS)等

华翔天诚科技 1833

java集合类后续

6:Collection介绍 .一般很少直接使用Collection,一般直接使用它的子接口,这样明确功能。 .public interface Collectionextedns interable使用了泛型 7:List .List接口扩充了collection,所以拥有更多的方法,使用更方便,可以复用。 .实现子类ArrayList .//介绍List接口 Listli

WangXin_cn_com的博客 502

WSL2下用QEMU模拟ARM开发板:从编译uboot到调试全流程(附常见错误解决)

本文详细介绍了在WSL2环境下使用QEMU模拟ARM开发板的完整流程,包括uboot编译、内核调试等关键步骤。通过QEMU模拟vexpress-a9开发板,开发者可以高效搭建嵌入式开发环境,解决常见错误并提升开发效率。

solidity8miner的博客 286

编译原理(第四章)——首符号集和后继符号集的求法

一、首符号集的求法 注:(1)ay是由x经过0到多步推出来的 且a是终结符号,若x是终结符号,First( x ) = { x }; 举例: 二、后继符号集的求法 (1)定义 1.例如:再求FOLLOW( T )的时候,在产生式右边寻找含有T的产生式,并且把它的右边的终结符号写入集合中。 例题: 注解:对于文法开始符号,#都要加进去。 三、构造首符号集 构造符号的FIRST集步骤: 构造文...

qq_40240576的博客 7646

5分钟搞定DataDome滑块验证码:最新Capsolver API实战教程(含代理配置)

本文提供了一份利用Capsolver API快速自动化破解DataDome滑块验证码的实战教程。文章深入剖析了DataDome验证码的环境指纹与行为分析机制,并重点详解了确保成功率的住宅代理配置、API集成步骤及令牌使用等核心环节,帮助开发者高效集成稳定可靠的自动化解决方案。

milk8的博客 494

Zynq 双核AMP 通信

4、配置离线编译(这里不讲),配置linux的内核地址空间(0x4000_0000改为0x2000_0000),以及单核启动。CPU1设置为0x2000_0000~0x3FFF_FFFF(也可以小于0x3FFF_FFFF)如果禁用CPU1的L2 cache,在CPU1的bsp里面添加编译时候所需要的宏。3、配置工程,将vivado产生的.xsa文件复制到amp_com项目目录下。9、使用petalinux-package --boot 打包。一、vivado工程。5、编译u-boot。

y183128184的博客 1087

List简易笔记一

1.集合:动态存储多个引用数据类型变量的容器,它空间可扩展(动态数组,实际上是数组的复制迁移)。 2.集合中常用概念: 有序:按添加的顺序来存值就叫有序。 可排序:按照一定规则(比如按数字由小到大或大到小,按字典顺序)来排序并存值。 唯一性:不可重复。 3.集合家族系谱图: 3.1:Collection:存储无序,可重复的单一对象 3.1.1:List:存储有序,可重复的单一对象 1:ArrayList:存储有序,可重复的单一对象,底层采用Object[]存值; 2:LinkedList:存储有

weixin_42420792的博客 937

Web3前沿技术的智能合约安全审计

随着Web3技术的快速发展,智能合约作为区块链应用的核心组件,其安全性问题日益突出。本文旨在系统性地介绍智能合约安全审计的技术体系,帮助开发者理解智能合约安全风险,掌握安全审计的方法论和工具链。智能合约安全的基本概念常见漏洞类型及其原理安全审计的技术方法实际审计案例分析安全审计工具和资源首先介绍基本概念和背景然后分析常见漏洞和安全风险接着详细讲解安全审计技术提供实际案例和代码示例最后讨论工具资源和未来趋势智能合约:运行在区块链上的自执行程序,代码即法律安全审计。

AI天才研究院 1547

DFS剪枝实战:从图着色问题看算法竞赛中的优化策略

深度优先搜索(DFS)是解决组合优化问题的经典算法框架,但其指数级的时间复杂度常导致程序在数据规模稍大时即面临超时挑战。其核心优化思想在于剪枝——通过预判并舍弃不可能通向最优解的搜索分支,从而大幅缩小解空间。这一技术在图论问题中价值尤为突出,例如图的着色问题,它要求用最少的颜色为顶点着色,使得相邻顶点颜色不同,这直接对应着资源分配、任务调度等实际场景中的冲突避免需求。通过结合最优性剪枝、顺序优化等策略,DFS能够从暴力枚举升级为高效精确解法。本文以经典的“分考场”问题(即图最少着色数问题)为例,深入剖析DF

weixin_34168834的博客 227

自适应滤波器在噪声消除中的应用:系统设计与实现

本文设计并实现了一种基于LMS算法的自适应噪声消除系统,能够有效消除周期性背景噪声,提升信噪比10dB以上。系统采用模块化设计,包含音频输入、自适应滤波、信号分析和可视化等核心模块,支持实时处理与参数动态调整。通过Python实现,提供图形界面进行参数设置、频谱对比和音频播放功能,为语音增强提供了一种实用解决方案。

huanghm88的专栏 128

车间数据孤岛终于破了!C#上位机+MQTT打通产线与MES,数据延迟从小时级降到秒级

本文针对工业上位机开发中常见的车间数据与企业管理系统(MES)割裂问题,提出基于C#和MQTT协议的完整解决方案。通过EMQX MQTT Broker实现数据实时双向传输,将质量追溯时间从2小时缩短至10秒,生产计划自动下发,实现秒级数据延迟。方案采用分层解耦架构,支持设备更换和系统升级,核心优势包括低延迟、高可靠性和易扩展性。文章详细介绍了MQTT协议选型理由、整体架构设计、技术选型(EMQX Broker和MqttNet客户端),并提供了C#实现代码和部署流程。该方案已在实际产线验证,可有效解决&quo

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 480

離散數學複習

離散數學

weixin_46616813的博客 427

零基础入门simulink建模仿真--基于Simulink的QPSK调制与解调仿真建模示例

QPSK是一种相位调制技术,将两个比特映射到一个符号上,每个符号对应四个可能的相位之一(0°、90°、180°、270°)。通过Simulink,我们可以通过模块化的建模方式实现QPSK的调制和解调过程,并观察信号在信道中的传输效果。通过本指南,我们介绍了如何基于Simulink搭建一个完整的QPSK调制与解调仿真模型,并进行仿真和性能评估。背景介绍:理解QPSK调制与解调的基本原理及其应用。所需工具和环境:列出进行QPSK仿真所需的工具和环境。步骤详解。

amy_mhd的博客 1309

YOLO 目标检测-基础配置 0206

conda其实是python的环境管理器,所以我们常说的pyhton环境究竟又是什么呢,其实所谓的python环境,可以简单理解成能让python代码能够正常运作的所有组件,其核心主要包括三样东西,pyhton解析器(这里类似linux中的bash解析器一样,就是联通代码和硬件,使得代码能被硬件所理解),依赖包集合,环境变量(路径配置)。

weixin_60457545的博客 1044

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

二分图最小顶点覆盖:从矩阵行列删除到匈牙利算法实战

在数据处理与算法优化中,对矩阵行与列的筛选操作是常见需求,其本质常可抽象为图论中的覆盖问题。具体而言,二进制矩阵可建模为二分图,其中行与列分别对应两侧顶点,矩阵中的‘1’则代表边。此时,删除最少的行和列以消除所有‘1’,等价于求解该二分图的最小顶点覆盖。Kőnig定理揭示了二分图中最小顶点覆盖与最大匹配的等价关系,这为高效求解提供了理论基础。匈牙利算法或Hopcroft-Karp算法可用于计算最大匹配,进而构造出最优的行列删除方案。该技术价值在于将看似复杂的组合优化问题转化为可高效计算的图论问题,在特征选择

cumo3681的博客 526

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

算法解题方法论:从问题建模到代码实现与优化的完整思维链路

算法是计算机科学的核心基础,其本质是一套解决问题的清晰指令集。理解算法原理,关键在于掌握如何将现实问题抽象为可计算模型,并选择合适的数据结构与策略进行高效求解。这一过程的技术价值在于培养严谨的计算思维和高效的工程实现能力,广泛应用于软件开发、数据分析、人工智能及各类算法竞赛等场景。本文聚焦于动态规划、图论等经典算法模型,深入探讨从理解题意、抽象建模、算法选型到代码实现与调试优化的完整解题链路,并分享滑动窗口、二分答案等高级思维技巧,旨在帮助学习者构建系统性的问题解决知识体系,实现从‘看懂题解’到‘独立解题’

weixin_34377919的博客 326

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

城市绿地智能调度建模实战:从竞赛到落地的完整闭环

城市基础设施智能调度是运筹优化与时空数据分析的典型交叉场景,其核心在于将多源异构传感器数据转化为可执行的控制决策。本文基于小美赛A题真实案例,系统阐释混合整数非线性规划(MINLP)问题的工程化建模路径:如何通过滚动时域优化(RHO)处理长周期时间约束,利用改进遗传算法(GA)求解带物理与人因约束的帕累托前沿,并以GIS空间几何编码实现‘喷淋不越界’等硬约束的可计算表达。技术价值体现在模型可解释性、鲁棒性验证与市政KPI对齐能力;应用场景覆盖智慧园林、市政水务及物联网边缘调度系统。文中所有代码、数据校准细节

weixin_30745553的博客 351

关于集合的总结 后续进行补充

集合类的由来:对象用于封装特有数据,对象多了需要存储,如果对象的个数不确定。就使用集合容器进行存储。 集合不可以存储基本数据类型值。 List集合是有序的,元素都有索引(角标),元素可以重复。 Set集合不能重复,无序。 对于List集合,子类 Vector:内部是数组数据结构,是同步的。增删查询都很慢 ArrayList:内部是数组数据结构,是不同步的,替代了Vect

fangmingzhmg的博客 667

集合继承关系图解

参考:http://www.cnblogs.com/jing99/p/7057245.html集合的特点:用来存储不同类型的对象(基本数据类型除外),存储长度可变。 Java集合中实际存放的只是对象的引用,每个集合元素都是一个引用变量,实际内容都放在堆内存或者方法区里面,但是基本数据类型是在栈内存上分配空间的,栈上的数据随时就会被收回的。集合框架图: 上述类图中,实线边框的是实现类,比如Arra

biexiaofei的博客 1万+

InnoDB 内存结构总览:Change Buffer、AHI 与 Log Buffer

本文系统梳理InnoDB内存结构中的ChangeBuffer、Adaptive Hash Index(AHI)与LogBuffer。ChangeBuffer缓存二级索引页不在内存时的变更,减少随机IO,仅在页加载时合并;聚簇索引修改立即执行,因数据本身不可延后。AHI基于高频等值查询自动构建哈希索引,加速定位,仅支持等值操作。LogBuffer为redo log内存缓冲,配合磁盘日志实现崩溃恢复。三者均服务于性能优化,其中ChangeBuffer与AHI共享BufferPool空间,而LogBuffer独立

bksczm的博客 289

V8 机制、手写核心函数与 TypeScript 类型体操

或固定初始化(如数组先定长、对象先给全字段)保持类型与形状稳定;这些都比"换框架"更基础。只能处理纯数据(丢函数、Date、RegExp、循环引用报错)。生产级深拷贝要处理:原始值短路、循环引用、V8(Chrome / Node 的 JS 引擎)不是"解释一行跑一行"那么简单,它用。图:V8 执行流程——解释执行 + 热点优化,优化失败会 Deopt 回退。JS 内存自动管理,但"自动"不等于"不会漏"。是"固定间隔最多执行一次"。手写 Promise 是"懂异步"的试金石。是"停下后才执行最后一次",

qq_38468358的博客 346
上一篇: 多人协作、公司必备GIT 解决git乱码
下一篇: logicFlow自定义节组&自定义节点
金木君
博客等级 码龄6年 7粉丝 33原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值