总结集合.

总结集合

集合:
Collection:
	List:
		ArrayList:
			底层:自动扩容的数组。初始容量为10,扩容机制->int newCapacity = oldCapacity + (oldCapacity >> 1); 每次扩容原容量的1.5倍
			优点:根据索引查找效率最高;元素有序可重复
			缺点:增加删除效率较低,线程不安全
			应用场景:查找多而增删少的场景
			
		Vector:是List的实现类,它的继承链是java.util.AbstractCollection<E> -->java.util.AbstractList<E>-->java.util.Vector
			底层:和ArrayList一样,可变长的数组,但扩容机制是每次扩容原容量的2倍
			优点:根据索引查找效率最高;元素有序可重复,线程安全
			缺点:效率比ArrayList低
			
		LinkedList:
			底层:双向链表(链表是一种数据结构,每个节点上除了存储数据还会存储下一个节点的地址,双向链表会存储前一个与下一个节点的地址)
			          可以操作首尾数据
			优点:有序,可重复。增删效率比较快
			缺点:按索引查找比较慢,线程不安全。
			应用场景:大量增删操作,少量查找操作 
			
			
			ListIterator迭代器。List接口下的一种Iterato迭代器。作用是在使用迭代器一边遍历一边修改元素时,会造成ConcurrentModificationException异常。
			而为此准备的ListIterator迭代器可以解决这个问题。它的add和remove方法可以一边遍历一边修改元素
	
	
	Set:
		HashSet:无序,不可重复
			底层:基于HashMap的key。是一个数组+链表。该数组为一个节点数组,每个数组都存入一个链表头。这种数组元素存入链表头的结构被称为“桶”。
				每次存入任意引用数据类型时,通常会执行下列操作:
					1.先将存入的数据使用hashCode()方法计算该数据地址值获得int类型的hash值
					2.将该获取的int值通过hash算法取得在数组上存入的位置,既桶位。该算法根据jdk版本各有不同。但目的都是让数据尽量散列(较为平均的存入节点数组)
					3.将该数据存入所得的桶位中,若该位置上没有数据,则将该数据作为此处链表的链表头;若有数据,则遍历该链表,并使用equals方法比较,只存入不相等的。
					
			注意:当链表长度>8且数组长度>64时,会将链表变为红黑树!
				当用HashSet存储对象时,若想保证两个有相同成员变量值的对象不重复时,仅仅重写该对象的equals方法是不够的。因为确定桶位时,可能将同一属性值的两个变量分配到
				不同的桶位里,此时他们无法被equals同时方法检测。所以我们要同时重写hashCode方法,让桶位根据对象的属性值来分配。这样相同属性值的对象会被分配在同一桶位中,
				再由equals比较其内容。
				
				规律:equals相同,hashCode一定相同;
					hashCode相同,equals不一定相同
					
			优点:同时具有链表和数组的特点,按照索引查找和增删效率都有提高(但任然比不上ArrayList的查和LinkedList的增删)
			缺点:无序,线程不安全
			应用场景:实现不存储相同数据,查询,增删效率较高的时候建议使用HashSet
			
		TreeSet:无序,不可重复,但由于底层是平衡二叉树,所以存入的数据会自动升序。
			底层:平衡二叉树(由TreeMap支持)
			
			注意:当存储引用类型数据时,由于TreeSet的自动排序,会导致类型不匹配异常。此时,若我们想要去除异常并完成去重则需要自己定义比较规则。
			此时,借助Comparable接口和Compartor接口来实现
			
			比较器:
				内部比较器|自然排序:Comparable。
				默认存在,定义在类的内部,固定是硬编码的习惯
				使用方法:相应的实体类实现Comparable接口,并重写CompareTo方法。根据方法返回值来决定排序方式:大于0则正序排,等于0则去重,小于0则倒序排
				例子:
						package com.mzq.practice;
						import java.io.Serializable;
						import java.util.Objects;

						public class Students implements Comparable<Students>, Serializable {
							private static final long serialVersionUID = -7424681982164699241L;
							private int age;
							private String name;
						//    public static int A=10;

							//无参构造
							public Students() {
								super();
							}

							//有参构造
							public Students(int age, String name) {
								super();
								this.age = age;
								this.name = name;
							}

							public int getAge() {
								return age;
							}

							public void setAge(int age) {
								this.age = age;
							}

							public String getName() {
								return name;
							}

							public void setName(String name) {
								this.name = name;
							}

							@Override
							public boolean equals(Object o) {
								if (this == o) return true;
								if (o == null || getClass() != o.getClass()) return false;
								Students students = (Students) o;
								return age == students.age &&
										Objects.equals(name, students.name);
							}

							@Override
							public int hashCode() {
								return Objects.hash(age, name);
							}

							
							@Override
							public int compareTo(Students o) {
								return this.getAge()-o.getAge();//按照年龄
							}

							@Override
							public String toString() {
								return "Students{" +
										"age=" + age +
										", name='" + name + '\'' +
										'}';
							}
						}
				
				外部比较器|定制排序:定义在一个类型的外部的比较方式:实现Comparator<T>接口,重写compare(T t1, T t2)方法。由于该接口只有一个抽象方法,且只用于比较,功能比较单一
				所以,一般使用匿名内部类或Lambda表达式来实现,不另外建类。
					例子:
						TreeSet <Students>set=new TreeSet<Students>();
						TreeSet <Students>set=new TreeSet<Students>((p1,p2) ->p1.getAge()-p2.getAge());//lambda表达式简化外部比较器
						//Comparator<Students> co=(p1,p2)->p1.getAge()-p2.getAge();//lambda表达式简化外部比较器写法2
						Comparator <Students>co=new Comparator<Students>() {
							@Override
							public int compare(Students o1, Students o2) {
								return o1.getAge()-o2.getAge();
							}
						};//匿名内部类简化外部比较器,将co填入treeset的参数列表里
						
		
	Map:
		HashMap<k,v>:底层:数组+链表+红黑树
			k(键): 可以为任意引用数据类型数据  相当于 Set 无序不可重复
			v(值): 可以为任意引用数据类型数据  相当于 Collection 可重复无序
			一个key只能对应一个value->映射关系,可以根据key操作value
			常用于存具有映射关系的两个值
			
			扩容以及存储相关的概念:
				1.该数据结构为节点数组+链表
				2.每个节点上存hash值,key值,value值,下一个节点的地址
				3.key值通过hashCode方法的到整数的hash值;该hash值再根据某种hash算法确定桶位索引。此过程会尽量保证散列。
				4.判断该桶位上是否有节点,若有,则将该数据加在该节点所在的链表的最后;若无,则将该数据作为头结点放入该桶位。
				5.jdk1.8后,当数组长度超过64,且链表长度都大于8,就会将链表结构换成红黑树
				6.每个HashMap的默认容量是16;当容量超过扩容临界值是,会扩为原来的27.扩容临界值只与加载因子有关,默认的加载因子是0.75,而临界值=当前容量*加载因子
				8.扩容最大不超过2^30;
				
			遍历的三方法:使用keySet();value;Map.Entry遍历,例子如下:
				HashMap<Teacher,String>map=new HashMap<Teacher,String>();
				Teacher t1=new Teacher("qzm","java");
				Teacher t2=new Teacher("mzq","bigdata");
				Teacher t3=new Teacher("mzq","bigdata");
				map.put(t1,t1.getLecture());
				map.put(t2,t2.getLecture());
				map.put(t3,t3.getLecture());
				
				//keySet()
				Set<String> names = map.keySet();
				for (String s : names) {
					System.out.println(s + "--->" + map.get(s));
				}
				
				//Values()只能遍历值,且该方法返回的类型是collection
				Collection<String> values=map.values()
				for (String s : names) {
					System.out.println(s));
				}

				//Map.Entry遍历
				Set<Map .Entry<Teacher,String>> set=map.entrySet();
				Iterator<Map.Entry<Teacher,String>> it=set.iterator();
				while (it.hasNext()){
					Map.Entry<Teacher,String> en= it.next();
					System.out.println("教师姓名:"+en.getKey().getName()+";教授课程:"+en.getValue());
				}
				
				
		TreeMap<k,v>:
			底层:红黑树,所以key会自动升序
			注意:当用key存储引用类型数据时,也要自定义比较器,方法同TreeSet
			遍历方式:参考HashMap
			
		Properties:
			作用:通常不作为容器,而作为读取配置文件用;这样我们可以实现软编码,增强灵活性。
			使用步骤:
            1.定义一个配置文件 xx.properties (键值对都是字符串)
            2.创建Properties类型的对象,调用load从流中加载(输入流的数据源就是配置文件)
            3.从配置文件中读取数据,加载使用
				例子:
						Properties pro = new Properties();
						//也可以用IO流
						pro.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties"));//表示从当前线程里获取类加载器,并读取资源文件夹中的对应文件。
						System.out.println(pro.getProperty("username"));
						System.out.println(pro.getProperty("password"));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值