稳稳当当学java之Collection和List(16)

本文主要探讨了Java中的Collection和List接口,包括Collection接口的介绍及其使用,详细讲解了List接口,尤其是ArrayList和LinkedList的区别,以及如何进行排序操作。此外,还提到了Set接口的简单介绍和HashSet的实现。
摘要由CSDN通过智能技术生成

第十八章 Collection和List

1.作业回顾

//写一个TestException类,在main方法中接受两个命令行参数,
//将他们转换成整数,并用第二个数除以第一个数,打印结果。
//测试一下情况,某个参数不是数字(异常1),第二个参数为0.(异常2)
public class Day17HomeWork {
	public static void main(String[] args) {
		System.out.println(args[0]);//1
		System.out.println(args[1]);//2
		try {
			int a = Integer.parseInt(args[0]);
			int b = Integer.parseInt(args[0]);
			System.out.println(b / a);//1
		}catch(NumberFormatException e1) {
			System.out.println("参数必须为整数");
		}catch(ArithmeticException e2) {
			System.out.println("不能除0");
		}	
	}
}

2.集合体系接口

数组不是动态的,一个数组一旦创建,它的容量就是固定的不能被修改。为了添加新的元素,需要创建一个容量更大的数组,并且将数据拷贝到新的数组中。

数组新增元素示例:

import java.util.Arrays;

public class Day1802 {
	public static void main(String[] args) {
		int[] arr = new int[5];
		arr[0] = 0;
		arr[1] = 1;
		arr[2] = 2;
		arr[3] = 3;
		arr[4] = 4;
		
//		arr[5] = 5;//java.lang.ArrayIndexOutOfBoundsException
		int[] arr1 = Arrays.copyOf(arr, 6);
		System.out.println(arr1.length);//6
	}
}

集合是动态的,集合允许动态的添加,删除元素。当元素的数量超过集合的容量时,集合会自动扩容。

java中有一系列的集合,它们有各自的用途。
在这里插入图片描述

3.Collection接口

Collection接口是Collection体系中最顶层的接口。一个Collection代表了一组对象,这些对象被称为元素。

Collection示意图:
在这里插入图片描述
集合只能保存对象,不能保存基本数据类型,可以使用包装类。Collection接口定义了所有集合必须实现的通用方法。有些类型的集合允许重复的元素,有些则不允许。有些类型的集合是有序的,有些不是。java并没有提供此接口的具体实现类,而是提供了它的子接口如Set和List的具体实现类。

3.1 Collection接口简介

Collection接口API: 这里的E表示集合中的元素的类型

import java.util.Iterator;

public class Day1803 {
	interface Collection<E> extends Iterable<E> { 
		boolean add(E paramE);//添加一个元素 
		boolean remove(Object paramObject);//删除一个元素 
		int size();//获取集合中元素的数量 
		boolean isEmpty();//判断集合是否为空 
		void clear();//清空集合中的元素 
		boolean contains(Object paramObject);//判断集合中是否包含一个元素 
		Iterator<E> iterator();//获取此集合的一个迭代器,通过迭代器可以遍历集合中的元素 
		//还有很多方法 
	}
}

3.2 Collection接口的使用

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;

public class Day1803 {
	public static void main(String[] args) {
		//使用泛型参数String创建的集合,只能向其加入String类型的元素
		//c是集合类型变量,new HashSet<String>()是集合对象
		Collection<String> c = new HashSet<String>();
		//判断集合是否为空
		System.out.println(c.isEmpty());//true
		//获取集合中元素的数量
		System.out.println(c.size());//0
		
		c.add("张三");//向集合加入一个元素,元素在集合中是无序存储的
		System.out.println(c.isEmpty());//false
		System.out.println(c.size());//1
		c.add("李四");
		c.add("李四");
		c.add("李四");
		c.add("王五");
		c.add("马六");
		//contains方法需要元素实现了equals方法,它会将传入的元素和集合中的所有元素依次
		//使用equals方法进行比较
		System.out.println(c.contains("王五"));//true
		//删除指定所有元素,需要元素实现了equals方法
		c.remove("李四");
		
		//由于Collection集合不记录元素的索引位置,必须使用迭代器来遍历集合 
		//获取集合的迭代器
		Iterator<String> i = c.iterator();
		//hashNext方法判断集合中是否还有下一个元素 
		//next方法获取集合的下一个元素
		while(i.hasNext()) {
			System.out.print(i.next());
		}//张三马六王五
		
		System.out.println();
		
		//foreach可以应用于实现了Iterable接口的集合 
		//Collection接口继承于Iterable接口,因此Collection所有的子集合都可以获取迭代器 
		//foreach内部就是使用迭代器
		for (String str : c) {
			System.out.print(str);
		}	
	}
}

4.List接口

List接口继承于Collection接口,因此它拥有Collection接口的所有方法。List接口是一个有序列表,它保留元素的添加顺序,并且允许将元素添加到集合中的指定位置。 List接口类似数组,只不过它是可以动态扩展。

List接口示意图:
在这里插入图片描述
当添加一个新的元素时,可以使用void add(E paramE)方法将元素添加到List集合的末尾。 也可以使用void add(int paramInt, E paramE)方法将元素添加到指定的位置。这样原来在此位置的元素和后续的元素都会向下移动。 也可以使用set和get方法来修改和获取指定位置的元素。 List接口的方法,未列全。

import java.util.Collection;
import java.util.ListIterator;

interface List<E> extends Collection<E>{
	E get(int paramInt);//获取指定位置的元素
	E set(int paramInt, E paramE);//替换指定位置的元素,返回旧元素
	void add(int paramInt, E paramE);//方法将元素添加到指定的位置
	E remove(int paramInt);//删除指定位置的元素
	int indexOf(Object paramObject);//获取指定元素的位置
	int lastIndexOf(Object paramObject);//获取指定元素的位置,从后向前
	ListIterator<E> listIterator();//返回一个迭代器
	List<E> subList(int paramInt1, int paramInt2);//返回子列表
}

List接口有两个实现类:ArrayList和LinkedList

4.1 ArrayList

4.1.1 ArrayList的使用

ArrayList实现了List接口,它保存元素的添加顺序。ArrayList的内部实现是一个数组。

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

public class Day1804 {
	public static void main(String[] args) {
		//创建了一个ArrayList集合,可以保存Integer类型的对象
		List<Integer> list = new ArrayList<Integer>();
		
		list.add(1);//自动装箱
		list.add(2);//自动装箱
		list.add(3);//自动装箱
		
		//List集合保留元素的添加顺序
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}	
	}	
}
4.1.2 ArrayList可以保存重复元素
import java.util.ArrayList;
import java.util.List;

public class Day1805 {
	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		//List允许重复元素
		list.add("张三");
		list.add("张三");
		
		System.out.println(list.size());//2
		
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}
		
		System.out.println(list.indexOf("张三"));//0
		
		list.add(0, "李四");
		
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}	
	}
}
4.1.3 set方法用于替换指定位置的元素
import java.util.ArrayList;
import java.util.List;

public class Day1806 {
	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		list.add("张三");
		list.add("李四");
		list.add("王五");
		
		list.set(1, "马六");
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}
	}
}
4.1.4 remove有两个重载的方法
import java.util.ArrayList;
import java.util.List;

public class Day1807 {
	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		list.add("张三");
		list.add("张三");
		list.add("李四");
		list.add("王五");
		
		list.remove(2);//删除李四
		list.remove("张三");//删除第一个张三,只删一个
		
		System.out.println(list.size());//2
		
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}	
	}
}
import java.util.ArrayList;
import java.util.List;

public class Day1808 {
	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		list.add("张三");
		list.add("张三");
		list.add("张三");
		list.add("张三");
		list.add("李四");
		
		//删除所有的张三
		for (int i = 0; i < list.size(); i++) {
			int index = list.indexOf("张三");
			if (index != -1) {
				list.remove(index);
				i--;
			}
		}
		
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}
	}
}
4.1.5 List的排序

Collections.sort()方法可以对List进行排序,前提是List中的元素实现了Comparable接口。

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

public class Day1809 {
	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		list.add("one");
		list.add("two");
		list.add("three");
		list.add("four");
		
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));//按添加元素顺序输出
		}
		
		System.out.println();
		
		//按照字母顺序排序
		Collections.sort(list);
		
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));//按字母顺序输出
		}
		
		System.out.println();
		
		List<Integer> list1 = new ArrayList<Integer>();
		list1.add(2);
		list1.add(1);
		list1.add(4);
		list1.add(3);
		
		for (int i = 0; i < list1.size(); i++) {
			System.out.println(list1.get(i));//按添加元素顺序输出
		}
		
		//对集合中的元素进行排序
		//按照从小到大的顺序排序
		Collections.sort(list1);
		
		System.out.println();
		
		for (int i = 0; i < list1.size(); i++) {
			System.out.println(list1.get(i));
		}
	}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

class Student implements Comparable<Student> {
	private String name;
	private int age;
	private int sno;
	
	public Student(String name, int age, int sno) {
		super();
		this.name = name;
		this.age = age;
		this.sno = sno;
	}

	@Override
	public String toString() {
		return "Student [name=" + name + "]";
	}

	//如果返回负数代表我在前,参数在后
	//如果返回正数代表我在后,参数在前
	@Override
	public int compareTo(Student o) {
		//按照年龄从小到大排序
//		return this.age - o.age;
		//按照学号从大到小排序
		return this.sno - o.sno;
	}
}

public class Day1810 {
	public static void main(String[] args) {
		List<Student> list = new ArrayList<Student>();
		
		list.add(new Student("张三", 18, 20191101));
		list.add(new Student("李四", 19, 20191102));
		list.add(new Student("王五", 20, 20191103));
		
		Collections.sort(list);
		
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}	
	}
}
4.1.6 使用比较器进行排序
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

class Person{
	private String name;
	private int age;
	
	public Person(String name, int age) {
		super();
		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 String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	
}

public class Day1811 {
	public static void main(String[] args) {
		List<Person> list = new ArrayList<Person>();
		
		list.add(new Person("张三", 18));
		list.add(new Person("李四", 19));
		list.add(new Person("王五", 20));
		
		//元素不实现Comparable接口,可以传递一个比较器
		Collections.sort(list, new Comparator<Person>() {

			public int compare(Person o1, Person o2) {
				//按照年龄从小到大排序
				return o1.getAge() - o2.getAge();
			}
		}
		
		);
		
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}	
		
	}
}
4.1.7 将List转化为数组
import java.util.ArrayList;
import java.util.List;

public class Day1812 {
	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		
		list.add("one");
		list.add("two");
		list.add("three");
		list.add("four");
		
		String[] arr = new String[list.size()];
		//将list转换为数组
		list.toArray(arr);
		
		for (int i = 0; i < arr.length; i++) {
			System.out.println(arr[i]);
		}	
	}
}
4.1.8 将数组转换为List
import java.util.Arrays;
import java.util.List;

public class Day1813 {
	public static void main(String[] args) {
		String[] arr = {"a", "b", "c", "d"};
		
		//将数组转换为list
		List<String> list = Arrays.asList(arr);
		
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}
	}
}

4.2 LinkedList

LinkedList实现了List接口,LinkedList和ArrayList拥有同样的方法,但是内部的实现却不同。ArrayList内部使用数组来实现,LinkedList内部使用链表来实现。

数组是一块连续的内存单元,链表不是连续的内存单元。

链表通过引用来使链表中的元素关联起来。

LinkedList示意图:
在这里插入图片描述

import java.util.LinkedList;
import java.util.List;

public class Day1814 {
	public static void main(String[] args) {
		List<String> list = new LinkedList<String>();
		
		list.add("one");
		list.add("two");
		list.add("three");
		list.add("four");
		
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}
	}
}

4.3LinkedList和ArrayList对比

ArrayList增删元素慢,因为需要拷贝整个数组。而LinkedList增删元素快,因为只需要修

改引用。但是,这是理论上的,实际并非如此。但是ArrayList的查询速度明显快于LinkedList。

5.Set接口

Set接口继承于Collection接口,因此它拥有Collection接口的所有方法。它并没有添加新的方法,只是约定不能添加重复的元素。

Set示意图:
在这里插入图片描述
Set接口API:

interface Set<E> extends Collection<E>{
    
}

5.1HashSet

HashSet实现了Set接口,不允许重复元素,依赖于元素重写了equals方法。Set是无序的集合,不保存添加元素的顺序,但是对Set进行迭代,每次的顺序都是一致的。

import java.util.HashSet;
import java.util.Set;

public class Day1815 {
	public static void main(String[] args) {
		Set<String> set = new HashSet<String>();
		set.add("张三");
		set.add("李四");
		set.add("王五");
		set.add("马六");
		
		System.out.println(set.add("张三"));//false, 没有添加成功
		
		//对set进行迭代,每次的顺序都是一致的
		for(String str : set) {
			System.out.println(str);
		}
	}
}
import java.util.HashSet;
import java.util.Set;

class Animal {
	private String name;
	private int age;
	
	public Animal(String name, int age) {
		super();
		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 String toString() {
		return "Animal [name=" + name + ", age=" + age + "]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Animal other = (Animal) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
}

public class Day1816{
	public static void main(String[] args) {
		Set<Animal> set = new HashSet<Animal>();
		set.add(new Animal("小狗", 1));
		set.add(new Animal("小猫", 2));
		set.add(new Animal("小狗", 1));
		
		for (Animal animal : set) {
			//重写了equals方法,则小狗1重复了
			System.out.println(animal);
		}
	}
}

6.作业

1,从键盘随机输入10个整数,保存到List中,并按照倒序排序,从大到小的顺序显示出来。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

十年之伴

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

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

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

打赏作者

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

抵扣说明:

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

余额充值