Java笔记7-集合(待更)


笔记摘自 廖雪峰的官方网站-Java教程-集合

Java集合简介

集合类型是Java标准库中被使用最多的类型。

在Java中,如果一个Java对象可以在内部持有若干其他Java对象,并对外提供访问接口,我们把这种Java对象称为集合。

Collection
Java标准库自带的java.util包提供了集合类:Collection,它是除Map外所有其他集合类的根接口。Java的java.util包主要提供了以下三种类型的集合:

  • List:一种有序列表的集合,例如,按索引排列的Student的List;
  • Set:一种保证没有重复元素的集合,例如,所有无重复名称的Student的Set;
  • Map:一种通过键值(key-value)查找的映射表集合,例如,根据Student的name查找对应Student的Map。

Java集合的设计有几个特点:一是实现了接口和实现类相分离,例如,有序表的接口是List,具体的实现类有ArrayList,LinkedList等,二是支持泛型,我们可以限制在一个集合中只能放入同一种数据类型的元素,例如:

List<String> list = new ArrayList<>(); // 只能放入String类型

Java访问或遍历集合,总是通过统一的方式——迭代器(Iterator)来实现,它最明显的好处在于无需知道集合内部元素是按什么方式存储的。

Java的集合类定义在java.util包中,支持泛型,主要提供了3种集合类,包括List,Set和Map。Java集合使用统一的Iterator遍历,尽量不要使用遗留接口。

使用List

List是按索引顺序访问的长度可变的有序表,优先使用 ArrayList 而不是 LinkedList

可以直接使用for each遍历List;

List可以和Array相互转换。

List的几个主要的接口方法:

  • 在末尾添加一个元素:boolean add(E e)
  • 在指定索引添加一个元素:boolean add(int index, E e)
  • 删除指定索引的元素:int remove(int index)
  • 删除某个元素:int remove(Object e)
  • 获取指定索引的元素:E get(int index)
  • 获取链表大小(包含元素的个数):int size()

示例:

import java.util.ArrayList;
import java.util.List;

public class Main{
	public static void main(Sring[] args){
		List<String> list = new ArrayList<>();
		list.add("apple"); // size=1
		list.add(null); // List允许添加null, size=2
		list.add("orange"); // size=3
		list.add("apple"); // 允许重复添加元素,size=4
		System.out.println(list.size());

		String second = list.get(1); // null
		System.out.println(second);
		
	}
}

创建List
除了使用ArrayList和LinkedList,我们还可以通过List接口提供的of()方法,根据给定元素快速创建List:

List<Integer> list = List.of(1, 2, 5);

但是List.of()方法不接受null值,如果传入null,会抛出NullPointerException异常。

遍历
方法1:用 for 循环根据索引配合List自带的 get(int) 方法遍历(不推荐);

方法2:我们要始终坚持使用迭代器Iterator来访问List。

Iterator本身也是一个对象,但它是由List的实例调用iterator()方法的时候创建的。Iterator对象知道如何遍历一个List,并且不同的List类型,返回的Iterator对象实现也是不同的,但总是具有最高的访问效率。

Iterator对象有两个方法:**boolean hasNext()**判断是否有下一个元素,**E next()**返回下一个元素。因此,使用Iterator遍历List代码如下:

import java.util.Iterator;
import java.util.List;
public class Main {
    public static void main(String[] args) {
        List<String> list = List.of("apple", "pear", "banana");
        for (Iterator<String> it = list.iterator(); it.hasNext(); ) {
            String s = it.next();
            System.out.println(s);
        }
    }
}

注意:Java的for each循环本身就可以帮我们使用Iterator遍历。把上面的代码再改写如下:

import java.util.List;
public class Main{
	public static void main(String[] args){
		List<String> list = List.of("apple", "orange", "peach");
		for (String s: list){
			System.out.println(s);
		}
	}
}

List 和 Array 转换
方法一:调用toArray()方法直接返回一个Object[]数组,这种方法会丢失类型信息,所以实际应用很少。

import java.util.list;
public class Main{
	public static void main(String[] args){
		List<String> list = List.of("apple", "orange", "banana");
		Object[] array = list.toArray(); // list调用toArray()方法直接返回一个Object[]数组:
		for(Object s : array){
			System.out.println(s);
		}
	}
}
		

方法二:给toArray(T[])传入一个类型相同的Array,List内部自动把元素复制到传入的Array中:

import java.util.list;
public class Main{
	public static void main(String[] args){
		List<String> list = List.of(12,  34, 56);
		Integer[] array_i = list.toArray(new Integer[3]);		
		for(Integer i : array_i){
			System.out.println(i);
		}


		// 注意到这个toArray(T[])方法的泛型参数<T>并不是List接口定义的泛型参数<E>
		// 所以,我们实际上可以传入其他类型的数组,例如我们传入Number类型的数组,返回的仍然是Number类型
		Number[] array_n = list.toArray(new Number[3]);
		for (Number n : array_n) {
            System.out.println(n);
        }

		// 但是,如果我们传入类型不匹配的数组,例如,String[]类型的数组,
		// 由于List的元素是Integer,所以无法放入String数组,这个方法会抛出ArrayStoreException。

	}
}
		

方法三:通过List接口定义的 T[] toArray(IntFunction<T[]> generator) 方法:

Integer[] array = list.toArray(Integer[]::new);

Array变为List

Integer[] array = { 1, 2, 3 };
List<Integer> list = List.of(array);

要注意的是,返回的List不一定就是ArrayList或者LinkedList,因为List只是一个接口,如果我们调用List.of(),它返回的是一个只读List。对只读List调用add()、remove()方法会抛出UnsupportedOperationException。

import java.util.List;
public class Main {
    public static void main(String[] args) {
        List<Integer> list = List.of(12, 34, 56);
        list.add(999); // UnsupportedOperationException
    }
}

可以看看原文的两个练习,以及评论区的解法,详情见此处

编写equals方法

使用Map

编写equals和hashCode

使用EnumMap

使用TreeMap

使用Properties

使用Set

使用Queue

使用PriorityQueue

使用Deque

使用Stack

使用Iterator

使用Collections

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值