Java集合-1(List,Map,Set)

Java集合-1(List,Map,Set)

java集合和C++的STL容器类似,方便程序员管理数据,操作数据(以下有些内容借鉴了廖雪峰老师的博客:廖雪峰老师的网站,这里总结了常用的内容,完善了一些例程)
java集合主要有三类:
List:列表,包括线性表和链表,类似C++的vector和list
Map: 键值对集合
Set: 一种保证没有重复元素的集合

java的集合类都由java.util包提供

List集合

  1. List只是接口,其常用实现类有两个:ArrayList和LinkedList。前者是线性表,后者是链表。定义一个List对象:
List<String> list = new ArrayList<>();
  1. List提供的常用方法:
void add(E e);	//在List集合尾部添加元素
void add(int index, E e)	//在List指定位置添加元素
void remove(int index)	//删除指定位置元素
E get(int index)	//获取指定位置元素
int size()	//获取集合大小
boolean contains(E e)	//查看集合内是否有指定元素
  1. 在使用contains函数时,需要注意:当List集合中存放的元素时自定义类的对象时,需要在自定义类中实现equals()函数。
boolean equals(Object o)

其原因也比较好理解,contains函数在判断一个元素是否在集合中时,需要进行比较,比较时会调用equals函数,标准库中的String类,Integer类都实现了equals函数。下面是一个例子。

/**
* 首先定义Person类,放在Person.java文件中
**/
public class Person{
	public String name;
	public int age;
	
	public Person(String name,int age){
		this.name = name;
		this.age = age;
	}
	//实现equals函数
	public boolean equals(Object o) {
		System.out.println("equals function was used");
		if(o instanceof Person) {
			Person p = (Person)o;
			if(p.name == this.name && p.age == this.age) {
				return true;
			}
		}
		return false;
	}
}

********************************************************************************************
/**
* 主函数实现
**/
import java.util.*;

public class ListPractice{
	public static void main(String[] args) {	
		List<Person> persons = new ArrayList<>();
		persons.add(new Person("gong",20));
		persons.add(new Person("guan",19));
		//调用contains函数
		System.out.println(persons.contains(new Person("gong",20)));
	}
}

最后运行结果:
运行结果
程序运行结果中打印 了“equals function was used”,表示在Person类中的equals函数被调用了。

Map集合

  1. Map只是一个接口,其常用实现类有三个:HashMap,EnumMap,TreeMap。定义一个Map:
Map<String,int> m = new HashMap<>();
  1. Map提供的常用方法:
Value put(Key k, Value v);     //向Map中插入键值对
Value get(Key k);     //根据键,获取值,如果键不存在,则返回null
boolean containsKey(Key k);     //查看某个键是否在集合中

使用put方法向Map中插入键值对时,如果Key已存在,则新的键值对将覆盖旧的键值对,而旧键值对的值会作为返回值返回;否则put的返回值为null.

  1. Map对象有两个重要成员:keySet和entrySet。前者为所有键值的集合,后者为所有键值对的集合,可以用这两个成员来对Map进行遍历。例程如下:
import java.util.*;

public class MapPractice{
	public static void main(String[] args) {
		Map<String,Integer> m = new HashMap<>();
		m.put("gong",26);
		m.put("guan",25);
		
		//利用keySet遍历Map
		System.out.println("use keySet");
		for(String key : m.keySet()) {
			System.out.println(key + ":" + m.get(key));
		}
		//利用entrySet遍历Map
		System.out.println("use entrySet");
		for(Map.Entry<String, Integer> entry : m.entrySet()) {
			System.out.println(entry.getKey() + ":" + entry.getValue());
		}
	}
}
  1. 使用HashMap时需要注意,如果Key为自定义类,则需要在自定义类中实现以下两个方法:
boolean equals(Object o)	//判断两个键值是否匹配
int hashCode()	//定义hash值计算规则

java标准库中的String类,Integer类等,都实现了以上两个方法。例子如下:

/**
* ID.java
* 首先定义ID类,在该类中实现equals()方法和hashCode()方法
**/
public class ID{
	public int id;
	
	public ID(int id) {
		this.id = id;
	}
	//实现equals函数
	public boolean equals(Object o) {
		//equals函数被调用时打印
		System.out.println(this.id + " equals function has been used");
		if(o instanceof ID) {
			ID i = (ID)o;
			if(i.id == this.id) {
				return true;
			}
		}
		return false;
	}
	//实现hascode方法
	public int hashCode() {
		//hashCode()函数被调用时打印
		System.out.println(this.id + " hasCode function has been used");
		return this.id;
	}
}
****************************************************************************************
/**
* 主函数
**/
import java.util.*;

public class MapPractice{
	public static void main(String[] args) {
		//使用ID类作为键,String作为值
		Map<ID,String> m = new HashMap<>();	
		m.put(new ID(1),"gong");
		m.put(new ID(2),"huan");
		
		System.out.println("ID = 1 : " + m.get(new ID(1)));	
	}
}

程序运行结果如下:
在这里插入图片描述
从运行结果可以看出,在使用put()函数插入键值对时,会调用hashCode()函数来计算hash值。在使用get()函数时,会先调用hashCode计哈希值,然后调用equals函数匹配键值

EnumMap貌似用的不多,这里先省略,可以查看廖雪峰老师的介绍(EnumMap

  • TreeMap。HashMap中键值的存放时无序的,而TreeMap中键值的存放是有序的,原因是TreeMap底层用红黑树实现。使用TreeMap是,除了Map提供的常用方法外,还常用以下两个函数:
Object firstKey()	//获取第一个键值(即最小的键值)
Object lastKey()	//获取最后一个键值(即最大的键值)

如果使用TreeMap时,键为自定义类,则需要:

  • 自定义类继承Comparable接口(在java.lang包中)
  • 在自定义类中重写compare方法(不用实现equals方法和hashCode方法,当然实现了也没有问题)。
int compareTo(Object o)	//大于返回1;小于返回-1;相等返回0

使用自定义类作为键值的例子如下:

/**
* ID.java
* 定义ID类,继承Comparable接口,实现compareTo方法
**/
import java.util.*;
import java.lang.*;

public class ID implements Comparable{
	public int id;
	
	public ID(int id) {
		this.id = id;
	}
	public int compareTo(Object o) {
		System.out.println(this.id + " compareTo function has been used");
		if(o instanceof ID) {
			ID i = (ID)o;
			if(this.id > i.id) {
				return 1;
			}
			if(this.id < i.id) {
				return -1;
			}
		}
		return 0;
	}
}
*************************************************************************
/**
* 主函数
**/
import java.util.*;

public class MapPractice{
	public static void main(String[] args) {
		Map<ID,String> m = new TreeMap<>();
		m.put(new ID(1),"gong");
		m.put(new ID(2),"huan");
		
		System.out.println("ID = 1 : " + m.get(new ID(1)));	
	}
}

上述代码的运行结果如下:
在这里插入图片描述
可以看出,compareTo函数确实被调用了。

Set集合

  1. Set集合中的元素时不重复的。Set只是接口,其常用实现类有两个:HashSet和TreeSet。这HashMap,TreeMap类似,前者底层数据结构时哈希表,元素存放是无序的;后者底层数据结构时红黑树,元素存放是有序的。
  2. Set集合常用的方法:
boolean add(E e)	//向Set添加元素
boolean remove(E e)	//从Set中删除元素
boolean contains(E e)	//判断集合中是否包含指定元素
  1. 使用HashSet时,如果集合存放元素为自定义类,则需要实现equals()函数和hashCode()函数。(和HashMap中的Key很相似)
    例如:
/**
* Person.java
* 实现Person类,实现equals函数和hashCode函数
**/
import java.lang.*;

public class Person{
	public int id;
	
	public Person(int id) {
		this.id = id;
	}
	//实现equals方法
	public boolean equals(Object o) {
		System.out.println("equals function has been used");
		if(o instanceof Person) {
			Person p = (Person)o;
			if(p.id == this.id) {
				return true;
			}
		}
		return false;
	}
	//实现hashCode方法
	public int hashCode() {
		System.out.println("hashCode function has been used");
		return this.id;
	}
}
*********************************************************************************
/**
* 主函数
**/
import java.util.*;

public class SetPractice{
	public static void main(String[] args) {
		Set<Person> persons = new HashSet<>();
		persons.add(new Person(1));
		persons.add(new Person(1));
		persons.add(new Person(2));
		
		System.out.println("persons.size() = " + persons.size());
		for(Person p : persons) {
			System.out.println("Person id = " + p.id);
		}
	}
}

上面代码的运行结果如下:
在这里插入图片描述
可见,equals函数和hashCode函数确实被调用了,而且主函数向Set集合中添加了三个Person对象(其中两个Person对象的id相同),最后集合中只有两个id值不同的Person对象。

  1. 使用TreeMap时,如图集合中存放元素为自定义类,则该类需要继承Comparable接口,实现compareTo函数。(和TreeMap中的Key相同)
    例子如下:
/**
* Person.java
* 实现CompareTo函数
**/
import java.lang.*;

public class Person implements Comparable{
	public int id;
	
	public Person(int id) {
		this.id = id;
	}
	//实现compareTo函数
	public int compareTo(Object o) {
		System.out.println("compareTo function has been used");
		if(o instanceof Person) {
			Person p = (Person)o;
			if(this.id > p.id) {
				return 1;
			}
			if(this.id < p.id) {
				return -1;
			}
		}
		return 0;
	}
}
************************************************************************
/**
* 主函数
**/
import java.util.*;

public class SetPractice{
	public static void main(String[] args) {
		Set<Person> persons = new TreeSet<>();
		persons.add(new Person(1));
		persons.add(new Person(1));
		persons.add(new Person(2));
		
		System.out.println("persons.size() = " + persons.size());
		for(Person p : persons) {
			System.out.println("Person id = " + p.id);
		}
	}
}

上面代码的运行结果如下:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值