Java集合篇

在这里插入图片描述

1、什么是集合

集合是存放一组数据的容器,同时能够对数据进行存储,查询,操作等。
我们也听说过“数组”,同样的,“数组”也可以进行数据的存储,查询和操作。

集合与数组两者的区别就是

(1)数组长度不可改变,而集合的长度可以
随需求变动
(2)数组中可以存放基本类型数据和对象,
而集合只能存储对象

2、类图

只画出主要的类图,因为画太多就显得太乱了。

«interface» Collection «interface» List «interface» Set «interface» Iterator «interface» Listiterator LinkedList ArrayList TreeSet LinkedHashSet HashSet «interface» Map HashMap LinkedHashMap TreeMap

3、主要接口和实现类

(1)Collection接口

Collection接口是继承自Iterator接口的子接口,同时也是List和Set以及Queue(图中没画出来)的父接口。Collection接口定义了多种方法:

1)boolean add(Object ob) 将对象ob添加进集合
2)int size() 返回元素的数量


import java.util.Collection;

public class CollectionTest {
	public static void main(String args[]){
	Collection c1=	new  ArrayList();
	Collection c2=new  ArrayList();
	//为c2添加数据
	c2.add("JavaJL");
	c2.add(new Boolean(true));
	c2.add(2);//在这里用到了自动装箱,向集合添加的2不是int类型,而是int的包装类Integer类型
	//返回元素的数量
	System.out.println("c2中共有:"+c2.size()+"个元素");
	System.out.println(c2);
	}
}
	
c2中共有:3个元素
原始的c2集合:[JavaJL, true, 2]

3)boolean remove(Object ob) 将对象ob从集合中删除

import java.util.ArrayList;
import java.util.Collection;

public class CollectionTest {
	public static void main(String args[]){
	Collection c2=new  ArrayList();
	//为c2添加数据
	c2.add("JavaJL");
	c2.add(new Boolean(true));
	c2.add(2);//在这里用到了自动装箱,向集合添加的2不是int类型,而是int的包装类Integer类型
	//返回元素的数量
	System.out.println("c2中共有:"+c2.size()+"个元素");
	System.out.println("原始的c2集合:"+c2);
	c2.remove(true);
	
	System.out.println("删除true元素后的c2集合:"+c2);
	}
}

c2中共有:3个元素
原始的c2集合:[JavaJL, true, 2]
删除true元素后的c2集合:[JavaJL, 2]

4)boolean addAll(Collection c)将集合c中所有元素添加到该集合
5)void removeAll(Collection c) 从集合中删除集合c中的所有元素
6)void retainAll(Collection c)从集合中删除集合c中没有的元素

import java.util.ArrayList;
import java.util.Collection;

public class CollectionTest {
	public static void main(String args[]){
	Collection c1=	new  ArrayList();
	Collection c2=new  ArrayList();
	c2.add("JavaJL");
	c2.add(new Boolean(true));
	c2.add(2);
//	将集合c2中所有元素添加到该集合c1
	c1.addAll(c2);
	c1.add("one");
	c2.add("two");
	System.out.println("c1集合的元素:"+c1);
	System.out.println("c2集合的元素:"+c2);
	
//	从集合c1中删除集合c2中的所有元素
	c1.removeAll(c2);

	System.out.println("从集合中删除集合c2中的所有元素");
	System.out.println("c1集合的元素:"+c1);
	System.out.println("c2集合的元素:"+c2);
	
//	从c2中删除没有在c1中的元素
	c1.add("JavaJL");
	c2.retainAll(c1);
	System.out.println("从集合c2中删除集合c1中没有的元素");
	System.out.println("c1集合的元素:"+c1);
	System.out.println("c2集合的元素:"+c2);
	}
}

结果为:

c1集合的元素:[JavaJL, true, 2, one]
c2集合的元素:[JavaJL, true, 2, two]
从集合中删除集合c2中的所有元素
c1集合的元素:[one]
c2集合的元素:[JavaJL, true, 2, two]
从集合c2中删除集合c1中没有的元素
c1集合的元素:[one, JavaJL]
c2集合的元素:[JavaJL]

7)boolean isEmpty() 判断集合是否为空
import java.util.ArrayList;
import java.util.Collection;
public class CollectionTest {
	public static void main(String args[]){
	Collection c1=new  ArrayList();
	c1.add("JavaJL");
	c1.add(new Boolean(true));
	c1.add(2);
	System.out.println(c1.isEmpty());
	}
}

结果为:false

8)Iterator iterator()返回迭代器

在Iterator接口介绍

(2)Iterator接口

Iterator中定义的方法:

1)boolean hasNext():判断是否还有元素,有就返回True,否则返回False
2)Object next():返回下一个元素并将指针指向下一个元素
3) void remove()删除指针指向的元素

使用Collection中的iterator()方法可以获得Iterator对象,iterator()方法能以迭代方式逐个访问集合中的元素。如果集合中的元素没有排序,则iterator()方法遍历元素的顺序是随机的,并不一定能和加入集合的顺序一样。

import java.util.*;
public class IteratorTest{
public static void main(String args[]){
Collection c=new ArrayList();
c.add(23);
c.add(false);
c.add("JavaJL");
//获取迭代器
Iterator it=c.iterator();
//使用迭代器遍历集合
while(it.hasNext()){
System.out.print(it.next()+" ");
		}
	}
}

结果为:

23 false JavaJL 

1)解析hasNext和next方法

先看一段代码和结果

import java.util.*;
public class IteratorTest{
public static void main(String args[]){
Collection c=new ArrayList();
c.add(23);
c.add(false);
c.add("JavaJL");

Iterator it=c.iterator();
while(it.hasNext()){
System.out.println(c);
System.out.println(it.next()+" ");
it.remove();
		}
	}
}

结果为:

[23, false, JavaJL]
23 
[false, JavaJL]
false 
[JavaJL]
JavaJL 

可以想象使用迭代器的集合的最前方有一个指针p,他指向集合的第一个元素的前一个元素
在这里插入图片描述

当调用迭代器的hasNext()方法时,它会去查看p所指向元素的下一个元素是否存在,若存在,则返回true,否则,返回false。
当调用迭代器的next()方法时,指针p会向下移动,并指向下一个元素。此时,当调用迭代器的remove()方法时,会删除掉p指针所指向的元素。

在这里插入图片描述

(3)Set接口

Set集合是一种最简单的集合,存放于集合中的对象不安特定的方式排序,只是简单的将对象加入到集合。对集合中存放对象的访问和操作是通过对象的引用进行的,所以Set集合中的元素不可重复。
Set接口有3个实现类分别是HashSetLinkedHashSetTreeSet

1)HashSet

HashSet按哈希算法来存储集合中的元素,具有很好的存取性能。当HashSet向集合中加入一个元素时,会调用对象的hashCode()方法获取Hash码,后根据Hash码来计算出对象在集合中的位置。

tpis:HashSet不能保证迭代的顺序和插入的顺序保持一致

import java.util.*;
public class IteratorTest{
public static void main(String args[]){
Set set=new HashSet();
set.add("one");
set.add(23);
set.add(true);
set.add("two");
Iterator it=set.iterator();
while(it.hasNext()){
System.out.println(it.next()+" ");
it.remove();
		}
	}
}

结果为:

one 
23 
two 
true 

2)LinkedHashSet

与HashSet相比LinkedHashSet可以按照插入的顺序进行迭代。LinkedHashSet删除元素后会去掉那个位置,新增的数据将添加在集合末尾。

import java.util.*;
public class IteratorTest{
public static void main(String args[]){
Set set=new LinkedHashSet();
set.add("one");
set.add(23);
set.add(true);
set.add("two");
Iterator it=set.iterator();
while(it.hasNext()){
System.out.print(it.next()+" ");
it.remove();
		}
	}
}

结果为

one 23 true two 

3)TreeSet

TreeSet可以对集合中的对象进行排序。成员一般为同一种类型。有两种排序方法,分别是自然排序和自定义排序

a、自然排序
import java.util.*;
public class IteratorTest{
public static void main(String args[]){
Set set=new TreeSet();
for(int i=1;i<=10;i++){
set.add(i);
}
Iterator it=set.iterator();
while(it.hasNext()){
System.out.print(it.next()+" ");
it.remove();
		}
	}

结果为

1 2 3 4 5 6 7 8 9 10 
b、自定义排序

问题:按照学生姓名name进行降序排序
先定义student类

import java.util.*;
class student{
	private String name;
	private int 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 "student [name=" + name + ", age=" + age + "]";
	}
	
}

定义一个类MyComparator并实现Comparator接口
compareTo方法的使用:对于a.compareTo(b),如果a和b相等,则返回0。如果a大于b,则返回大于0的数。如果a小于b,则返回小于0的数。

static class MyComparator implements Comparator<Student>{
		@Override
		public int compare(Student s1, Student s2) {
			return s1.getName().compareTo(s2.getName()) * -1;
		}
	}

进行测试

	public static void main(String[] args) {
		Set<Student> set =new TreeSet<Student>(new MyComparator());
		Student s1 = new Student("Tom", 24);
		Student s2 = new Student("Marry", 20);
		Student s3 = new Student("Jerry", 23);
		set.add(s1);
		set.add(s2);
		set.add(s3);
		Iterator<Student> iterator = set.iterator();
		while(iterator.hasNext()){
			Student next = iterator.next();
			System.out.println(next.getName()+","+next.getAge());

		}

结果为:

Tom,24
Marry,20
Jerry,23

(4)List接口

List继承至Collection接口,实现类有ArraysList类和LinkedList类,他的特点是可以保存重复的元素,可以通过索引来访问元素。

List接口的常用方法

1、void add(int index,Object o):将对象o插入到索引index处
2、addAll(int index ,Collection c):将c集合添加到index索引处,从index处开始存储
3、Object get(int index):获得索引处的对象
4、Object set(int index,Object o):将index位置上的对象替换为对象o
5、Object remove(int index):删除index位置上的对象

1)ArraysList

ArrayList底层是数组。对元素的随机访问速度较快。

2)LinkedList

LinkedLis底层是链表。对元素的删除和插入的速度较快。


import java.util.*;

public class Test {
	
public static void main(String args[]){
	List list1=new ArrayList();
	List list2=new LinkedList();
	list1.add("Monday");
	list1.add("Tuesday");
	list1.add("Wednesday");
	list1.add("Thursday");
	list1.add("Friday");
	System.out.println("list1中的元素:"+list1);
	System.out.println("list1中索引值为1的元素:"+list1.get(1));
	
	//在索引为0的位置插入一个元素“weekend”
	list1.add(0, "weekend");
	System.out.println("在索引为0的位置添加一个元素weekend"+list1);
	
	//删除索引为0位置上的元素
	list1.remove(0);
	System.out.println("删除索引为0位置上的元素"+list1);
	
	//将索引为1的位置设置为"星期一"
	list1.set(1, "星期一");
	System.out.println("将索引为1的位置设置为\"星期一\""+list1);
	
	
	list2.addAll(list1);
	//获得索引为2的位置上的元素
	Object object = list2.get(2);
	System.out.println("删除索引为2位置上的元素"+object);
}
}

(5)Map接口

Map映射集合保存的是键值对对象,类似字典,当查找元素时,只要知道就能查到,他有三个实现类分别是HashMapTreeMapLinkedHashMap

Map接口中常用的方法

1、Object put(Object key,Object value)将键值对key-value添加到map
2、Object remove(Object key)将map中以key为键的键值对删除
3、Object putAll(Map mapping):将mapping添加到当前Map
4、void clear():清空当前Map
5、boolean containsKey(Object key):判断是否存在key键
6、boolean containsValue(Object value):判断是否存在value值
7、int size():返回键值对个数
8、boolean isEmpty():判断当前Map是否为空


import java.util.HashMap;
import java.util.Map;

public class MapTest {
	public static void main(String args[]){
		Map m1=new HashMap();
		Map m2=new HashMap();
		//将键值对key-value添加到map
		m1.put("one", "Monday");
		m1.put("two", "Tuesday");
		m1.put("three", "Wednesday");
		m1.put("four", "Thursday");
		m1.put("five", "Friday");
		System.out.println(m1);
		//将m1中以"one"为键的键值对删除
		m1.remove("one");
		System.out.println("将map中以key为键的键值对删除"+m1);
//		将m1添加到当前m2
		m2.putAll(m1);
		System.out.println("将m1添加到当前m2"+m2);
//		清空m1
		m1.clear();
		System.out.println("清空m1"+m1);
//		判断是否存在"two"键
		System.out.println("判断是否存在key键"+m2.containsKey("two"));
//		判断是否存在value值
		System.out.println("判断是否存在key键"+m2.containsValue("Friday"));
//		返回键值对个数
		System.out.println("返回键值对个数"+m2.size());
//		判断当前Map是否为空
		System.out.println("判断当前Map是否为空"+m2.isEmpty());
	}
}

结果为:

{four=Thursday, one=Monday, two=Tuesday, three=Wednesday, five=Friday}
将map中以key为键的键值对删除{four=Thursday, two=Tuesday, three=Wednesday, five=Friday}
将m1添加到当前m2{two=Tuesday, three=Wednesday, five=Friday, four=Thursday}
清空m1{}
判断是否存在key键true
判断是否存在key键true
返回键值对个数4
判断当前Map是否为空false

介绍两个常用的Map

1)HashMap

HashMap实现了Map接口,中文叫散列表。元素的排列顺序不固定,在遍历HashMap时,得到的映射关系是无序的。

import java.util.HashMap;
import java.util.Map;

public class MapTest {
	public static void main(String args[]){
		Map m1=new HashMap();
		//将键值对key-value添加到map
		m1.put("one", "Monday");
		m1.put("two", "Tuesday");
		m1.put("three", "Wednesday");
		m1.put("four", "Thursday");
		m1.put("five", "Friday");
		System.out.println(m1);
	}
}

结果为:

{four=Thursday, one=Monday, two=Tuesday, three=Wednesday, five=Friday}

可以看到,HashMap的存入顺序和输出顺序无关

2)LinkedHashMap

保留键的插入顺序,用equals方法检查键和值的相等性,成员可为任意的对象,若覆盖了equals方法,那么必须要修改hashCode方法

LinkedHashMap关注点结论
是否允许空Key和Value都允许空
是否允许重复数据Key重复会覆盖、Value允许重复
是否有序有序
是否线程安全非线程安全

LinkedHashMap保留键值对的存入顺序


import java.util.LinkedHashMap;
import java.util.Map;
public class MapTest {
	
	public static void main(String args[]){
		
		Map m1=new LinkedHashMap();
		m1.put("1", "星期一");
		m1.put("2", "星期三");
		m1.put("5", "星期五");
		m1.put("3", "星期二");
		m1.put("4", "星期四");
		System.out.println(m1);
	}
}
{1=星期一, 2=星期三, 3=星期二, 4=星期四, 5=星期五}

3)TreeMap

支持对键有序的遍历,实现了SortedMap接口,键成员要求实现Comparable接口,或者使用Comparator构造,TreeMap成员一般为同一类型。

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
public class MapTest {
	
	public static void main(String args[]){
		
		Map m1=new TreeMap();
		m1.put("1", "星期一");
		m1.put("2", "星期三");
		m1.put("5", "星期五");
		m1.put("3", "星期二");
		m1.put("4", "星期四");
		System.out.println(m1);
	}
}
{1=星期一, 2=星期三, 3=星期二, 4=星期四, 5=星期五}

tip:Integer、Double、String等已经实现了Comparable接口,所以上面的例子会实现自动排序哦~

在这里插入图片描述

创作不易,欢迎三连呀

评论 32
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Java精灵儿

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

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

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

打赏作者

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

抵扣说明:

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

余额充值