当前位置: 移动技术网 > IT编程>开发语言>Java > 荐 JAVA13——容器(Map接口、Equals和hashcode、Set接口、容器存储数据练习、Iterator接口)

荐 JAVA13——容器(Map接口、Equals和hashcode、Set接口、容器存储数据练习、Iterator接口)

2020年07月17日  | 移动技术网IT编程  | 我要评论

目录

Map接口

主要方法

实现Map

第一种方式(不完美)

第二种方式

Equals和hashcode

Set接口

实现Set

容器存储数据练习

Iterator接口

迭代Map的两种遍历方式


Map接口

  • 实现Map接口的类用来存储键(key)—值(value)对
  • Map接口的实现类有HashMap和TreeMap等
  • Map类中存储的键—值对通过键来标识,所以键值不能重复

主要方法

  • 添加/改变一个键值对:Object put(Object key, Object value)
  • 获取指定键对应的值:Object get(Object key)
  • 删除某个键值对:Object remove(Object key)
  • 删除指定索引的元素:int remove(int index)
  • 判断有没有指定key的对象:boolean containsKey(Object key)
  • 判断有没有指定value的对象:boolean containsValue(Object value)
  • 判断Map是否为空:boolean isEmpty()
  • 将一个Map的所有键值对加入到另一个Map中:void putAll(Map t)
  • 清空Map:void clear()
  • 获取Map大小:int size()

实现Map

第一种方式(不完美)

不完美的地方:每次查询和增加键值对都要遍历一次,效率低

public class MyMap01 {

	MyEntry[] arr = new MyEntry[990];
	int size;
	
	public void put(Object key, Object value){
		MyEntry e = new MyEntry(key, value);
		
		for(int i=0;i<size;i++){
			if(arr[i].key.equals(key)){
				arr[i].value = value;
				return;
			}
		}
		
		arr[size++] = e;
	}
	
	public Object get(Object key){
		for(int i=0;i<size;i++){
			if(arr[i].key.equals(key)){
				return arr[i].value;
			}
		}
		return null;
	}
	
	public boolean containsKey(Object key){
		for(int i=0;i<size;i++){
			if(arr[i].key.equals(key)){
				return true;
			}
		}
		return false;
	}
	
	public static void main(String[] args) {
		MyMap01 map = new MyMap01();
		map.put("张三", new Wife("李四"));
		map.put("张三", new Wife("李m"));
		
		Wife w = (Wife) map.get("张三");
		
		System.out.println(w.name);
		System.out.println(map.size);
	}
	
}

class MyEntry{
	Object key;
	Object value;
	
	public MyEntry(Object key, Object value){
		super();
		this.key = key;
		this.value = value;
	}
}

第二种方式

利用hashCode()方法

Map底层实现:数组+链表

import java.util.LinkedList;

public class MyMap02 {
	LinkedList[] arr = new LinkedList[999];
	int size;
	
	public void put(Object key, Object value){
		MyEntry e = new MyEntry(key, value);
		
		int hash = key.hashCode();
		hash = hash<0?-hash:hash;
		
		int a = key.hashCode()%arr.length;
		if(arr[a]==null){
			LinkedList list = new LinkedList();
			arr[a] = list;
			list.add(e);
		}else{
			LinkedList list = arr[a];
			for(int i=0;i<list.size();i++){
				MyEntry e2 = (MyEntry) list.get(i);
				if(e2.key.equals(key)){
					e2.value = value; //键值重复直接覆盖
				}
			}
			arr[a].add(e);
		}
	}
	
	public Object get(Object key){
		int a = key.hashCode()%arr.length;
		if(arr[a]!=null){
			LinkedList list = arr[a];
			for(int i=0;i<list.size();i++){
				MyEntry e = (MyEntry) list.get(i);
				if(e.key.equals(key)){
					return e.value;
				}
			}
		}
		return null;
	}
	
	
	public static void main(String[] args) {
		MyMap01 map = new MyMap01();
		map.put("张三", new Wife("李四"));
		map.put("张三", new Wife("李m"));
		
		Wife w = (Wife) map.get("张三");
		
		System.out.println(w.name);
	}
	
}

Equals和hashcode

  • Collection类对象在调用remove、 contains等方法时需要比较对象是否相等,这会涉及到对象类型的equals方法和hashCode方法;对于自定义的类型,需要重写equals和hashCode方法以实现自定义的对象相等规则
    • Java中规定,两个内容相同的对象应该具有相等的hash codes

重写Equals和hashcode eg:
source—Generate hashCode() and Equals()
重写id的Equals和hashcode方法:

public class Student {
	private int id;
	private String name;
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)	//判断地址是否一样
			return true;
		if (obj == null)	//判断传入的参数是否为空值
			return false;
		if (getClass() != obj.getClass())	//判断所在类是否一样
			return false;
		Student other = (Student) obj;	
		if (id != other.id)		//判断id值是否一样
			return false;
		return true;
	}
}

eg2:

public class TestEquals {
	
	public static void main(String[] args) {
		Map map = new HashMap();
		
		String s1 = new String("aaa");
		String s2 = new String("aaa");
		
		map.put(s1,"AAA");
		map.put(s2,"BBB");
		System.out.println(map.get("aaa"));
		
		Integer s3 = new Integer(123);
		Integer s4 = new Integer(123);
		
		map.put(s3,"AAA");
		map.put(s4,"BBB");
		
		System.out.println(map.get(123));
		
		Date s5 = new Date(123);
		Date s6 = new Date(123);
		
		map.put(s5,"AAA");
		map.put(s6,"BBB");
	
		System.out.println(map.get(s5));
	}
	
}

Set接口

  • Set接口是 Collection接口的子接口,Set接口没有提供额外的方法,Set接口的特性是容器类中的元素是没有顺序的,而且不可以重复
  • Set容器可以与数学中“集合”的概念相对应
  • J2SDK API中所提供的Set容器类有HashSet、TreeSet等

实现Set

import java.util.HashMap;

public class MyHashSet {
	
	HashMap map;
	int size;
	private static final Object PRESENT = new Object();
	
	public MyHashSet(){
		map = new HashMap();
	}
	
	public int size(){
		return map.size();
	}
	
	public void add(Object o){
		map.put(o, PRESENT);	//set的不可重复是利用了map里键对象的不可重复
	}
	
	public static void main(String[] args) {
		MyHashSet s = new MyHashSet();
		s.add("aaa");
		s.add(new String("aaa"));
		System.out.println(s.size());
	}
	
}

容器存储数据练习

存储如下表格中的数据:

ID 姓名 薪水 单位 入职时间
0301 AA 3000 项目部 2019-12
0302 BB 6000 教学部 2020-01
0303 CC 2000 教学部 2020-05

步骤:

一、创建Employee实体类

1.一个表对应一个类,创建类Employee,定义属性:

private int id;
private String name;
private int salary;
private String department;
private Date hireDate;

2.生成所有属性的Set和Get方法,生成构造器

修改构造器代码如下:

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public Employee(int id, String name, int salary, String department,
		String hireDate) {
	super();
	this.id = id;
	this.name = name;
	this.salary = salary;
	this.department = department;
	
	DateFormat format = new SimpleDateFormat("yyyy-MM");
	try {
		this.hireDate = format.parse(hireDate);
	} catch (ParseException e) {
		e.printStackTrace();
	}
}

Employee类属于Javabean,即实体类

二、填入数据

第一种方法:

1.新建类Test01,创建对象并赋初值

一个对象对应了一行记录

public class Test01 {
	
	public static void main(String[] args) {
		Employee e = new Employee(0301, "AA", 3000, "项目部", "2019-12");
		Employee e2 = new Employee(0302, "BB", 6000, "教学部", "2020-01");
		Employee e3 = new Employee(0303, "CC", 2000, "教学部", "2020-05");
	}
	
}

创建ArrayList,将创建的对象存储到列表中

List<Employee> list = new ArrayList<Employee>();	//<Employee>代表该list只能存放Employee类
		
list.add(e);
list.add(e2);
list.add(e3);

3.创建获取所有对象name属性的函数,在main函数中调用

public static void printEmpName(List<Employee> list){	//只能传入存储Employee对象的列表
    for(int i=0;i<list.size();i++){
		System.out.println(list.get(i).getName());
	}
}
printEmpName(list);

第二种方法:

1.新建类Test02,创建对象并赋初值

一个map对应了一行记录

public class Test02 {
	
	public static void main(String[] args) {
		Map map = new HashMap();
		map.put("id", 0301);
		map.put("name", "AA");
		map.put("salary", 3000);
		map.put("department", "项目部");
		map.put("hireDate", "2019-12");
		
		Map map2 = new HashMap();
		map2.put("id", 0302);
		map2.put("name", "BB");
		map2.put("salary", 6000);
		map2.put("department", "教学部");
		map2.put("hireDate", "2020-01");
		
		Map map3 = new HashMap();
		map3.put("id", 0303);
		map3.put("name", "CC");
		map3.put("salary", 2000);
		map3.put("department", "教学部");
		map3.put("hireDate", "2020-05");
	}
	
}

2.创建ArrayList,将创建的map存储到列表中

List<Map> list = new ArrayList<Map>();	
		
list.add(map);
list.add(map2);
list.add(map3);

3.创建获取所有对象name属性的函数,在main函数中调用

public static void printEmpName(List<Map> list){	
	for(int i=0;i<list.size();i++){
		Map tempMap = list.get(i);
		System.out.println(tempMap.get("name"));
	}
}
printEmpName(list);

Iterator接口

  • 所有实现了Collection接口的容器类都有—个 iterator方法用以返回一个实现了Iterator接口的对象
  • Iterator对象称作迭代器,用以方便的实现对容器内元素的遍历操作
  • Iterator接口定义了如下方法:
    • 判断是否有元素没有被遍历:boolean hasNext()
    • 返回游标当前位置的元素并将游标移动到下一个位置:Object next()
    • 删除游标左面的元素,在执行完next之后该操作只能执行一次:void remove()

eg:

public class Test01 {
	
	public static void main(String[] args) {
		List list = new ArrayList();
		list.add("aaa");
		list.add("bbb");
		list.add("ccc");
		
		//通过索引遍历list
		for(int i=0;i<list.size();i++){
			System.out.println(list.get(i));
		}
		
		//通过迭代器遍历list
		for(Iterator iter=list.iterator();iter.hasNext();){
			String str = (String) iter.next();
			System.out.println(str);
		}
		
		Set set = new HashSet();
		set.add("高1");
		set.add("高2");
		set.add("高3");
		
		//while循环
		Iterator iter2 = set.iterator();
		while(iter2.hasNext()){
			String str = (String) iter2.next();
			System.out.println(str);
		}
		
		//for循环
		for(Iterator iter3=set.iterator();iter3.hasNext();){
			String str = (String) iter3.next();
			System.out.println(str);
		}
	}
	
}

迭代Map的两种遍历方式

public class Test02 {
	
	public static void main(String[] args) {
		Map map = new HashMap();
		map.put("AA", "www");
		map.put("BB", "ddd");
		map.put("CC", "yyy");
		
		//迭代key,通过key获取value
		Set keys = map.keySet();
		for(Iterator iter = keys.iterator();iter.hasNext();){
			String keyStr = (String) iter.next();
			System.out.println(keyStr+"——"+map.get(keyStr));
		}
		
		//获取到所有的键值存到Set集合中,再迭代这个集合
		Set<Map.Entry<String,String>> entry = map.entrySet();
		Iterator<Map.Entry<String,String>>  ite = entry.iterator();
		while(ite.hasNext())
		{
			Map.Entry<String,String> en = ite.next();
			String key = en.getKey();
			String value = en.getValue();
			System.out.println(key+"=="+value);
		}
	}
	
}

 

本文地址:https://blog.csdn.net/qiao39gs/article/details/107361908

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网