集合基础回顾

集合
定义:容器
对比:数组–长度固定–可存储基本类型+引用类型
集合–长度不固定–只存引用类型
位置:java.util.*;
体系:
在这里插入图片描述
从上向下依次学习
1.父接口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() //姜此集合转换成数组。

2.Collection旗下子接口List
特点:有序+有下标+能重复

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

记住下面代码加一个ArrayList 的原因:

List<Integer> list = new ArrayList<>(Arrays.asList(20, 30, 40, 50)) ;
list.removeIf(a -> a.equals(20));
list.remove(new Integer(20));//这样可以根据内容删掉。

3.List的实现类ArrayList【重点】
特点:数组结构实现,查询快+增删慢;
涉及到重写equals()方法:【注意,这里中用到了重写equals()方法,而还未牵连到hashCode()方法】

public boolean equals(Object obj) {
	//1.是否为同一对象
	if (this==obj) {
		return true;
	}
	//2.判断是否为空
	if (obj==null) {
		return false;
	}
	//3.判断是否是Student类型
	if (obj instanceof Student) {
		Student student=(Student) obj;
		//4.比较属性
		if(this.name.equals(student.getName())&&this.age==student.age) {
			return true;
		}
	}
	//不满足,返回false
	return false;
}

3.1ArrayList源码分析

默认容量大小:private static final int DEFAULT_CAPACITY = 10;
存放元素的数组:transient Object[] elementData;
实际元素个数:private int size;
创建对象时调用的无参构造函数:

每次扩容为原来的1.5倍。

4.Vector
特点:数组结构实现,查询快+增删慢
与ArrayList不同:运行效率慢,线程安全;

5.LinkedList
特点:链表结构,增删快+查询慢
5.1LinkedList源码分析
3个属性:
链表大小:transient int size = 0;
(指向)第一个结点/头结点: transient Node first;
(指向)最后一个结点/尾结点:transient Node last;
关于Node类型:

private static class Node<E> {
    E item;
    Node<E> next;
    Node<E> prev;

    Node(Node<E> prev, E element, Node<E> next) {
        this.item = element;
        this.next = next;
        this.prev = prev;
    }
}

6.小结
ArrayList:需要开辟连续空间
LinkedList:无需开辟连续空间

7.泛型
背景:JDK1.5引入的新特性,本质:参数化类型,把类型作为参数传递;
常见形式:泛型类、泛型接口、泛型方法;
优点:

  • 提高代码重用性;
  • 防止类型转换机场,提高代码安全性;

7.1泛型类
注意:泛型只能是引用类型;
不同泛型类型的对象不能相互赋值
7.2泛型接口
语法:接口名
注意:不能创建泛型静态常量
在实现接口时,确定泛型类;
7.3泛型方法
语法: 返回类型

public class MyGenericMethod {
	public <T> void show(T t) {
		System.out.println("泛型方法"+t);
	}
}

7.4泛型集合
概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致。
特点:

  • 编译事即可检查,而非运行时抛出异常;
  • 访问时,不必类型转换(拆箱);
  • 不同泛型之间引用不能相互赋值,泛型不存在多态;

8.Set集合概述
8.1子接口Set
特点:无序、无下标、元素不可重复
方法:全部继承自Collection中的方法
8.2实现类HashSet【重点】
特点:基于HashCode计算元素存放位置;当存入的元素的哈希码相同时,会调用equals确认,如果结果为true,则拒绝后者存入。
存储结构:哈希表(数组+链表+红黑树)
留意一下hashSet存储过程,即特点;
使用重写hashCode()和equals()方法案例:
在这里插入图片描述
8.3TreeSet
特点:

  • 基于排序的顺序 实现 不重复;
  • 实现了SortedSet接口,对集合元素自动排序;
  • 元素对象的类型必须是实现Comparable接口 ,指定排序规则,compareTo方法返回为0,判定为重复元素;
  • 通过CompareTo()方法确定是否为重复元素;
  • 存储结构:红黑树
  • 查看Comparable接口的源码,发现只有一个compareTo抽象方法,需要在元素对象的勒种实现它;比如在Person类中去实现:
public class Person implements Comparable<Person>{
    @Override
	//1.先按姓名比
	//2.再按年龄比
	public int compareTo(Person o) {
		int n1=this.getName().compareTo(o.getName());
		int n2=this.age-o.getAge();
		return n1==0?n2:n1;
	}
}

除了实现Comparable接口里的比较方法,TreeSet也提供了一个带比较器Comparator的构造方法,使用匿名内部类来实现它:

/**
 * TreeSet的使用
 * Comparator:实现定制比较(比较器)
 */
public class Demo5 {
	public static void main(String[] args) {
		TreeSet<Person> persons=new TreeSet<Person>(new Comparator<Person>() {
			@Override
			public int compare(Person o1, Person o2) {
				// 先按年龄比较
				// 再按姓名比较
				int n1=o1.getAge()-o2.getAge();
				int n2=o1.getName().compareTo(o2.getName());
				return n1==0?n2:n1;
			}			
		});
		Person p1=new Person("tang",21);
		Person p2=new Person("he", 22);
		Person p3=new Person("yu", 21);
		persons.add(p1);
		persons.add(p2);
		persons.add(p3);
		System.out.println(persons.toString());
	}
}

9.Map体系集合
Map接口特点:
1.存储任意键值对k-v
2.键:无序、无下标、不允许重复(唯一);
3.值:无序、无下标、可重复;
Map体系表:
在这里插入图片描述
方法:

V put(K key,V value)//将对象存入到集合中,关联键值。key重复则覆盖原值。
Object get(Object key)//根据键获取相应的值。
Set<K>//返回所有的key
Collection<V> values()//返回包含所有值的Collection集合。
Set<Map.Entry<K,V>>//键值匹配的set集合

注意Map中附带的Entry<>()方法,可用于对map集合的遍历中,效率更快。

	Map<String,Integer> map=new HashMap<String, Integer>();
		//1.添加元素
		map.put("tang", 21);
		map.put("he", 22);
		map.put("fan", 23);
  //遍历1:使用keySet()方法
        for(String key : map.keySet()){
            System.out.println(key + ":" + map.get(key));
        }
        //遍历2:使用entrySet();效率较高
        for (Map.Entry<String,Integer> entry : map.entrySet()){
            System.out.println(entry.getKey() + ":" + entry.getValue());
        }
        //遍历3:使用迭代器,对map.entrySet()进行迭代
        //遍历4:使用values()方法,不过是遍历value,而非key

9.1Map集合的实现类
HashMap【重点】
背景&特点:

  • JDK1.2版本,线程不安全,运行效率快;
  • 允许用null作为key或者value;
  • 存储结构:哈希表(数据+链表+红黑树)
  • 如果key值一样,重复添加时,会添加失败,但是value会更新

遍历:

  • 使用keySet()遍历;
  • 使用entrySet()遍历;

HashMap源码分析

  • 默认初始化容量:static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
  • 数组最大容量:static final int MAXIMUM_CAPACITY = 1 << 30;
  • 默认加载因子:static final float DEFAULT_LOAD_FACTOR = 0.75f;
  • 链表调整为红黑树的链表长度阈值(JDK1.8):static final int TREEIFY_THRESHOLD = 8;
  • 红黑树调整为链表的链表长度阈值(JDK1.8):static final int UNTREEIFY_THRESHOLD = 6;
  • 链表调整为红黑树的数组最小阈值(JDK1.8):static final int MIN_TREEIFY_CAPACITY = 64;
  • HashMap存储的数组:transient Node<K,V>[] table;
  • HashMap存储的元素个数:transient int size;
  1. 默认加载因子是什么?
    就是判断数组是否扩容的一个因子。假如数组容量为100,如果HashMap的存储元素个数超过了100*0.75=75,那么就会进行扩容。
  2. 链表调整为红黑树的链表长度阈值是什么?
    假设在数组中下标为3的位置已经存储了数据,当新增数据时通过哈希码得到的存储位置又是3,那么就会在该位置形成一个链表,当链表过长时就会转换成红黑树以提高执行效率,这个阈值就是链表转换成红黑树的最短链表长度;
  3. 红黑树调整为链表的链表长度阈值是什么? 当红黑树的元素个数小于该阈值时就会转换成链表。 链表调整为红黑树的数组最小阈值是什么?
    并不是只要链表长度大于8就可以转换成红黑树,在前者条件成立的情况下,数组的容量必须大于等于64才会进行转换。

HashSet源码分析
从源码看出,HashSet的存储结构就是HashMap,HashSet的add()方法调用的就是Map的put方法,把元素作为map的key传进去;

TreeMap与TreeSet的关系与HashMap与HashSet的关系类似;
9.2TreeMap
特点:实现了SortedMap接口(Map的子接口),可以对key自动排序;
存储结构:红黑树
不能直接打印treeMap,需要是实现Comparable接口,因为红黑树需要比较大小;

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

public static void reverse(List<?> list)//反转集合中元素的顺序
public static void shuffle(List<?> list)//随机重置集合元素的顺序
public static void sort(List<T> list)//升序排序(元素类型必须实现Comparable接口)

[https://lazydog036.gitee.io/2020/10/29/JAVA%E9%9B%86%E5%90%88%E6%A1%86%E6%9E%B6/#Collection%E4%BD%93%E7%B3%BB%E9%9B%86%E5%90%88]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值