荐 JAVA13——容器(Map接口、Equals和hashcode、Set接口、容器存储数据练习、Iterator接口)
程序员文章站
2022-05-04 19:10:01
目录Map接口主要方法实现Map第一种方式(不完美)第二种方式Equals和hashcodeSet接口实现Set容器存储数据练习Iterator接口迭代Map的两种遍历方式Map接口实现Map接口的类用来存储键(key)—值(value)对Map接口的实现类有HashMap和TreeMap等Map类中存储的键—值对通过键来标识,所以键值不能重复主要方法添加/改变一个键值对:Object put(Object key, Object value...
目录
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
上一篇: 【JavaSE】多线程Part1(11)