【Java基础】第四章 | 集合

目录

| 总框架

| List及其实现类

| Set及其实现类

| Map


| 总框架

集合的基本框架

  • 首先,掌握顶层的Collection及其方法(这些方法是所有集合通用的方法)。

  • 然后,学习Collection的两个子接口List和Set的特性、及其各自的实现类的使用。

 

Collection —— 集合之父

  • Collection的所有方法和索引无关。

public boolean add  (E e);   //添加元素
public void clear ();   //保留集合对象,但是清空所有元素
public boolean remove (E e);   //删除指定对象
public boolean contains ( E e );    //判断集合是否存在指定元素
public boolean isEmpty();   //判断集合是否为空
public int size();   //获取集合元素个数
public Object[] toArray();   //把集合转数组

Collections —— 集合工具类 & 自定义类排序

  • 基本都是静态方法,直接用类名调用即可

public static void shuffle(List<?> list);   //打乱集合元素(只能打乱List集合元素)
public static <E> boolean addAll (Collection<T> 集合名 , 元素1,元素2...... );   //向集合添加多个元素
public static <T> void sort ( List<T> list );   //将集合元素按照ASCII码的升序规则排序(只能排序List集合)
public static <T> void sort ( List<T> list , Comparator <? super T> );   //将集合的元素按照指定规则排序(常用于自定义类型)

下面详细介绍一下自定义类型使用Collections的sort方法的详细步骤

//方法一:原始sort方法 + “自定义类型实现Comparable接口 + 重写其compareTo方法”

//Step1.自定义类,需要手动实现Comparable<E>接口
public class Person implements Comparable<Person>{
	//Step2.重写接口中的compareTo方法
	@Override
	public int compareTo(Person person){
		//Step3.return 写上降序还是升序(this.排序参照变量 - 参数.排序参照变量 : 升序)(参数.排序参照变量 - this.排序参照变量 : 降序)
		return this.getAge() - person.getAge();   //升序
	}
}

//Step4.直接对Person的类使用sort即可按照age升序排序
Person p = new Person();
Collection<Person> personList = new ArrayList<>();
personList.add(new Person("Klee",8));
personList.add(new Person("Sagiri",12));
sort(p);   //按照age对Person进行升序排序
//方法二:“集合名 + 重写Comparator及其compare方法(匿名内部类)” 作为sort参数

Person p = new Person();
Collection<Person> personList = new ArrayList<>();
personList.add(new Person("Klee",8));
personList.add(new Person("Sagiri",12));

//按照age对Person进行升序排序
//Step1.直接调用sort方法,传入两个参数:一个是集合对象,另一个是Comparator的匿名类
//Step4.直接对Person的类使用sort即可按照age升序排序
sort(p , new Comparator{
    //Step2.重写接口中的compareTo方法
	@Override
	public int compareTo(Person person){
		//Step3.return 写上降序还是升序(this.排序参照变量 - 参数.排序参照变量 : 升序)(参数.排序参照变量 - this.排序参照变量 : 降序)
		return this.getAge() - person.getAge();   //升序
});   
  • Comparator和Comparable的区别:

    Comparator(是一个类):相当于找一个第三方的裁判,比较不同的值的大小

    Comparable(是一个接口):自己this 和 别的参数比较,自己需要实现Comparable接口,重写比较的规则Comparator方法

Iterator —— 遍历元素

  • Iterator和索引没关系,因此迭代器是一种通用的取出集合元素的一种方式。

Iterator<E e> iterator = 集合对象名.iterator();

//迭代器循环的方式一(常用)
while(iterator.hasNext()){
	System.out.println(iterator.next());
}

//迭代器循环的方式二(了解)
for(Iterator<String> it = coll.iterator() ; it2.hasNext ; ){
	String e = it.next();
	System.out.println(e);
}

| List及其实现类

List的特点

  • 允许存储重复的元素

  • 集合是有序的 (存储元素和取出元素的顺序是一致的)

  • 集合中带索引值(特有带索引的方法)

List实现类:ArrayList

  • Collection的方法,ArrayList也能用

  • 下面介绍一下ArrayList的方法(这些方法 LinkedList也能用,但是效率低)

Collection<String>  list = new ArrayList<>(); //若E为基本数据类型,则必须使用其包装类

System.out.println(arrayList);     //ArrayList重写了toString

arrayList.add(E e);    //添加元素。返回boolean
arrayList.add(int index , E e);   //在索引处插入元素
arrayList.set(int index , E e);   //替换索引处的元素
arrayList.get(int index);    //获取索引元素。返回元素
arrayList.remove(int index);    //删除索引元素。返回删除元素
arrayList.remove(E e);   //删除元素
arrayList.size();    //获取长度。

List实现类:LinkedList

List< E e > linkedList = new LinkedList<>( );

public void add ( E e ) ;       //添加元素到列表末尾
public void addFirst ( E e ) ;    //添加元素到列表开头
public void addLast ( E e ) ;    //添加元素到列表末尾,此方法等效于add
public void push ( E e ) ;       //将元素推入此列表所表示的堆栈 (开头) ,此方法等效于addFirst

//下列五个方法不能在空集合中使用。因而常搭配 if( ! LinkedList . isEmpty ){  } 在括号中使用
public E getFirst (  ) ;        //返回列表的首元素
public E getLast (  ) ;         //返回列表末尾元素
public E removeFirst (  ) ;     //移除并返回此列表的首元素
public E removeLast (  ) ;     //移除并返回此列表的末尾元素
public E pop (  ) ;           //从此列表表示的堆栈处弹出一个元素,此方法等效于removeFirst( )

public boolean isEmpty (  );   //若列表为空 返回true

List实现类:Vector

  • 已经被淘汰

  • Vector 的大小可以根据需要增大或缩小,以适应创建 Vector后进行添加或移除项的操作

  • Vector是JDK1.0最初支持的数据类型,与现在的Collection不同步(多线程)不同,Vector是同步(单线程)的,因此处理速度会很慢

  • 在JDK1.2版本后,Vector也实现了Collection接口.

    也就是说,在JDK1.0的时候,Vector不支持所有的Collection和List的方法!

    在JDK1.2之后,Vector才支持Collection和List的方法。


| Set及其实现类

  • Set集合是集合总父类Collection的子类,是TreeSet HashSet的父类。其中HashSet 是 LinkedHashSet 的父类。

Set的特点

  • Set不允许存储重复的元素(先比较哈希值,若哈希值相同再比较内容,若内容相同则不保存到集合内)

    因此,若想向Set存储自定义类型,则必须重写hashCodes和equals方法

    若不重写hashCode,则使用的是Object的方法,两个对象的Object肯定是不一样的,所以都能存进集合!!

    若不重写equals,则比较的是地址,而不是内容。而不同对象的地址肯定不同,所以也都能存进集合!!

    总之,重写hashCode和equals的目的是:不出现“因为对象不同,所以哈希值一定不同、地址必不同”,而存储了相同元素进HashSet集合的Bug。

  • 集合是无序的 (存储元素的顺序和取出元素的顺序有可能不一致)例外如:LinkedHashSet是有序的。无序集合取出的元素可能有序

  • 集合中没有索引值,因而不能使用普通的for循环遍历,只能用增强for或者迭代器遍历

Set实现类:HashSet

  • HashSet底层 在JDK1.8是 数组+链表。 JDK1.8后是 数组+链表+红黑树,当链表的长度 >8 , 则链表会转换红黑树

  • 常用方法如下:

Set<String> hashSet = new HashSet<>();

hashSet.add("one");   //添加元素
hashSet.contains("one");   //判断是否存在元素
hashSet.remove("one");   //删除元素
hashSet.clear();   //清空元素
hashSet.size();   //获取元素个数

//遍历元素
for(String str : hashSet){
	//...
}

Set实现类 & HashSet的子类:LinkedHashSet

Set的子类:TreeSet

  • TreeSet 是一个有序集合,它的作用是提供有序的Set集合。其继承于 AbstractSet 类

  • TreeSet 实现了 NavigableSet 接口,意味着它支持一系列的导航方法。比如查找指定目标最匹配项

  • TreeSet 实现了 Serializable 接口,因此它支持序列化

  • TreeSet 是通过 TreeMap 实现的一个有序的、不可重复的集合,底层维护的是红黑树结构。当TreeSet的泛型对象不是java的基本类型的包装类时,对象需要重写 Comparable 的 compareTo()方法

  • 语法

//构造方法

//默认构造方法。使用改
TreeSet()

// 创建的 TreeSet 包含 collection
TreeSet(Collection<? extends E> collection)

// 指定 TreeSet 的比较器
TreeSet(Comparator<? super E> comparator)

// 创建的 TreeSet 包含set
TreeSet(SortedSet<E> set)
 

| Map

  • Map是一个接口,且有两个泛型

  • Map的Key都不能重复!

  • Map和Set一样,依靠哈希值、以及内容的对比,来判断是否存在重复的Key。因此自定义类作为Map的Key,必须重写hashCode和equals方法

  • Map集合 和 Collection集合 是完全不同的一个体系!

Map的子类:HashMap

  • HashMap的集合底层是哈希表【JDK1.8后的哈希表构成为:数组+单向链表/红黑树(链表长度>8)】

    HashMap不保证插入顺序,但是循环遍历时,输出顺序是不会改变的。

  • 下面介绍HashMap常用方法:

//创建
Map<String,String> map = new HashMap<>();

//成员方法
public V put (K key , V value);  //存放KV
public V remove(Object key);   //删除KV,若K存在则返回被删除的V,若K不存在则返回null
public V get(Object key);   //获取K对应的V
public boolean contaimKey(Object key);   //判断是否包含K
public Set<E> keySet();   //返回Map的Key组成的Set集合
map.entrySet();   //返回键值对构成的集合  Set<Map.Entry<String,String>> set

//遍历:使用迭代器
Iterator it = map.iterator();
while(it.hasNext()){
	//..
}

//遍历:使用foreach
for(String key : map.keySet()){
	String str = map.get(key);
}

//遍历:【特有】通过Entry遍历键值对
Set<Map.Entry<String,String>> set = map.entrySet();
for(Map.Entry<String,String> entry : map.entrySet()){
    String key = entry.getKey();
    String value = entry.getValue();
}

HashMap的子类:LinkedHashMap

  • LinkedHashMap的集合底层是 哈希表+链表(保证迭代的顺序)

    LinkedHashMap是有序

  • 下面介绍LinkedHashMap常用方法 和HashMap方法一致

    Map<String,String> mapLink = new LinkedHashMap<>();

Map的实现类:HashTable

  • 已经淘汰

  • 其底层是一个哈希表。该集合也是一个双列集合。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Graskli

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值