Map集合和泛型

1.定义

Map集合是一个双列集合,以键值对的形式存在,将键和值捆绑到一起存放(Map.Entry(Entry中是Map类中的一个内部类))如果出现相同的键,会用新的值覆盖老的值,每个键最多只能映射到一个值
什么是键值对?

键值对就是有key-value组成的数据,一个key对应一个value,就像一个身份证号对应一个人一样,可以通过key寻value,所以map中存放的key只能是唯一。另外键值对称为entry 

2.map的基本操作

package day23;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Example1 {
   public static void main(String[] args) {
	   //1.添加数据
	   Map map=new HashMap();
	   Object put2=map.put(1001L, "xiaoming");
	   System.out.println(put2);
	   map.put(1002L,"xiohong");
	   System.out.println(map);
	   //如果key重复了,那么返回值是被覆盖的,旧的value
	   Object put=map.put("1001L","xiaowang");
	   System.out.println(map);
	   System.out.println(put);
	   //2.查询数据
	   //2.1根据键来获取的值
	   Object value=map.get(1001L);
	   System.err.println(value);
	   //2.1设置某个键的值
	   map.put(1001L, "xiaoli");
	   //2.2可以获得map中所有的键值对
	   Set entrySet=map.entrySet();
	   //2.2遍历Map中所有的entry==遍历Map中所有的key和value
}
}

上写代码中尽管添加数据和设置某个键的值的角度不同,但是操作相同 

map和set集合具有相同之处,例如:hashset,hashset中含有map集合,hash

set对数据的操作实际上操作的是map中key的值,value则赋值为默认值。调用entrySet实际上,将map中entry中的地址赋值给Set集合,Set集合通过地址找到map中的entry

package day23;

import java.text.CollationElementIterator;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.swing.plaf.synth.SynthOptionPaneUI;
//map的删除操作
public class Example5 {
   public static void main(String[] args) {
	   //添加数据
		Map map=new HashMap();
		map.put(1001L, "小明");
		map.put(1002L, "小红");
		map.put(1003L, "小李");
		map.put(1004L, "小王");
		Object remove=map.remove(1004L);
		System.out.println(remove);
		System.out.println(map);
}
}

3.map集合的遍历

package day23;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
//Map集合的遍历==very重要
public class Example2 {
   public static void main(String[] args) {
	 //添加数据
	Map map=new HashMap();
	map.put(1001L, "小明");
	map.put(1002L, "小红");
	map.put(1003L, "小李");
	map.put(1004L, "小王");
	//遍历map
	//entrySet中存放的entry是Map集合中的内部类
	Set entrySet=map.entrySet();
	for(Object obj:entrySet) {
		 if(obj instanceof Map.Entry) {
			 Map.Entry entry=(Map.Entry)obj;
			 //获得entry中的键
			 Object key=entry.getKey();
			 //获得entry
			 Object value=entry.getValue();
			 System.out.println(key+"="+value);
		 }
	}
}
}
package day23;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class Example3 {
   public static void main(String[] args) {
	   //添加数据
		Map map=new HashMap();
		map.put(1001L, "小明");
		map.put(1002L, "小红");
		map.put(1003L, "小李");
		map.put(1004L, "小王");
		//遍历map,遍历所有的key,遍历过程中根据key来获取值,实现遍历map
		Set keyset=map.keySet();
		Iterator iterator=keyset.iterator();
		while(iterator.hasNext()) {
			 Object key=iterator.next();
			 Object value=map.get(key);
			 System.out.println(key+"="+value);
		}
}
}

通过调用map集合中的KeySet方法。可以将map中所有键的地址赋值给Set,再通过这些地址,找到key。找到key值后。再通过key值找到value

package day23;

import java.text.CollationElementIterator;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.swing.plaf.synth.SynthOptionPaneUI;
//方法三:collection value=map.values()
//直接获得Map中所有的value
public class Example4 {
   public static void main(String[] args) {
	   //添加数据
		Map map=new HashMap();
		map.put(1001L, "小明");
		map.put(1002L, "小红");
		map.put(1003L, "小李");
		map.put(1004L, "小王");
		//遍历map,
		Collection values=map.values();
		for(Object object:values) {
			System.out.println(object);
		}
}
}

 4.hashmap的介绍

底层使用的是数组
HashMap就是通过我们存入的key获取到一个hash值,经过计算之后,获取到一个数组角标,然后将key和value封装到一个Entry里面,然后存入数组 
当数组容量不够的时候,会自动扩容一倍
 

 

 

 

当链表的长度大于8时,为提高效率,会将链表转换为红黑树 

 5.hashmap的带参数的构造器

HashMap(int inttalCapacity)

构造一个带有指定初始容量和默认加载因子(0.75)的空HashMap

6.使用HashCode方法的注意事项

package day23;

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

//HasMap怎么保持唯一
public class Example6 {
  public static void main(String[] args) {
	  Map map=new HashMap();
	  Animal a1=new Animal();
	  a1.setName("小王");
	  a1.setAge(2);
	  Animal a2=new Animal();
	  a2.setName("小王");
	  a2.setAge(1);
	  map.put(a1, "动物1");
	  map.put(a1, "动物2");
//细节:调用HashMap的put方法时,会默认调用a1的HashMap方法,计算出在数据中的下标,两次都添加了
//a1,所以下标一样,则调用a1对象的equals方法,判断是否key一样
	  System.out.println(map);
//让属性完全相同的对象。被map视为是同一个对象,那么就需要重写HashCode
//目的就是让这样的对象,在一个链表。属性完全相同的两个对象的Hash
//Code值完全一样,同时,还需要重写equals方法,,再同一个链表中比较对象是否相同的依据是属性值
//是否一样
}
}
class Animal{
	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() {
		// TODO Auto-generated method stub
		return "Animal [name="+name+",age="+age+"]";
	}
	
}

7.treeMap

存放在map集合中的元素可以被排序,所以在存储元素时,一定要告知treemap元素的排序方式

package day23;

import java.util.Comparator;
import java.util.TreeMap;
//要把数据存放到TreeMap,前提实现两种比较方法:
//-要么在构造器中创建一个比较器对象
//要么key的类实现Comparable
public class Example8 {
        public static void main(String[] args) {
        	TreeMap map=new TreeMap(new Comparator() {

				@Override
				public int compare(Object o1, Object o2) {
					// TODO Auto-generated method stub
					Worker w1=(Worker)o1;
					Worker w2=(Worker)o2;
					return (int)(w1.getId()-w2.getId());
				}
        		
			});
        	Worker w1=new Worker(1001L, "laowang", 20);
        	Worker w2=new Worker(1001L, "laoli", 30);
        	map.put(w1, w1.getName());
        	map.put(w2, w2.getName());
		}
}
class Worker{
	private Long id;
	private String name;
	private int age;
	public Worker(Long id, String name, int age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	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 "Worker [id=" + id + ", name=" + name + ", age=" + age + "]";
	}
	
}
package day23;

import java.util.Comparator;
import java.util.TreeMap;
//要把数据存放到TreeMap,前提实现两种比较方法:
//-要么在构造器中创建一个比较器对象
//要么key的类实现Comparable
public class Example9 {
        public static void main(String[] args) {
        	TreeMap map=new TreeMap();

        	Worker w1=new Worker(1001L, "laowang", 20);
        	Worker w2=new Worker(1001L, "laoli", 30);
        	map.put(w1, w1.getName());
        	map.put(w2, w2.getName());
		}
}
class Worker implements Comparable{
	private Long id;
	private String name;
	private int age;
	public Worker(Long id, String name, int age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	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 "Worker [id=" + id + ", name=" + name + ", age=" + age + "]";
	}
	@Override
	public int compareTo(Object o) {
		// TODO Auto-generated method stub
		Worker w1=(Worker)o;
		return (int)(this.id-w1.id);
		//小的在前大的在后
	}
	
}

7.泛型

  7.1为什么要使用泛型

package generic;

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

//为什么使用泛型
//集合的特点是弥补了数组中的某个一个不足:数组中元素的数据类型必须是一致
//在开发中,更倾向于让集合只存一种数据类型。单一职原则
//通过使用泛型,约束集合中元素的数据类型。此时防止数据类型的多样化导致程序错误
public class Example1 {
       public static void main(String[] args) {
		List <Integer>list=new ArrayList<Integer>();
		list.add(98);
		list.add(99);
		list.add(100);
	//报错	list.add("良好");
		
	}
}

7.2泛型的使用 

package generic;

import java.util.ArrayList;
import java.util.List;
/**
 * 泛型如何使用
 * 只用在设计了泛型的类中,才能使用泛型
 * 类要用泛型来解决什么样的问题
 * 类中的泛型,相当于是占位符,在设计类是时没有指明某个类的属性的类型,但在使用类时,通过指明泛型类型,
 * 于是类中占位符都变成了指定类型
 * 在使用类时,如果不指明泛型类型,那么类中的占位符都变成了Object
 * 如何声明和创建泛型类对象
 * 声明时必须要指明泛型,且泛型只能是引用数据类型,不能使用基本数据类型,基本数据类型必须使用包装类
 * 创建时也建议带上<>,jdk7以后,允许声明时指明了泛型,创建时,不指明泛型
 * 类中设计多个泛型
 * 如果要指明泛型,需要把类中设计的所有泛型都指明 有些不明确的类型可以使用Object。
 * 或者都不指明
 * 继承或实现有泛型类型的抽象类或接口该注意
 * ——不指明父类的泛型类型,父类的泛型类型就是Object
   class JavaStudent extends Student{}
 * ——子类在继承父类时可以直接指明父类的泛型类型
 * class JavaStudent extends Student<Integer>
 * ——子类自己可以声明泛型类型来作为父类的泛型类型,把泛型确定的时机留给子类创建对象时
 * class EnglishStudent<T> extends Student<T>{}子类中的T和父类中的T一样。
	泛型方法,方法的返回值类型由方法的实参类型决定
  泛型是编译时的约束,在运行是泛型起不到作用
 * 
 * @author yu
 *
 */
public class Example2 {
   public static void main(String[] args) {
	 List list=new ArrayList();
	 Student<Object> stu1=new Student<>(); 
	 Student<Object>stu2=new Student<>();
	 Teacher t1=new Teacher<>();
	 Teacher <String ,Integer> t2=new Teacher<>();
	 EnglishStudent<Object>  stu3=new EnglishStudent<>();
	 String object=A.getObject("hello");
}
}
class A{
	public static <T> T getObject(T t) {
		return t;
	}
}
//   
class EnglishStudent<T> extends Student<T>{
	
}
class JavaStudent extends Student<Integer>{
	
}
//在这个类中所有出现T的地方换成相应的类型 
class Teacher<E,T>{
	private T t;
	private E e;
	
}

class Student<T>{
	 private String name;
	 private int age;
	//运动特长
    private T sport;
	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;
	}
	public T getSport() {
		return sport;
	}
	public void setSport(T sport) {
		this.sport = sport;
	}
		 
	
}

7.3泛型在集合中的使用  

package generic;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;

public class Example3 {
    public static void main(String[] args) {
    	TreeMap<Animal,String> t1=new TreeMap<Animal, String>();
		Map<Long,String> map=new HashMap<>();
		map.put(1001L, "xiaoming");
		map.put(1002L, "xiaohong");
		map.put(1003L, "xiaoli");
		//遍历集合
		Set<Entry<Long,String>> entrySet= map.entrySet();
//		Iterator迭代的是Entry
		Iterator<Entry<Long, String>> iterator=entrySet.iterator();
		while(iterator.hasNext()) {
			 Entry<Long, String> entry=iterator.next();
			 Long key=entry.getKey();
			 String value=entry.getValue();
			 System.out.println(key+"="+value);
		}
	}
}
//comparable提供了一个比较依据<T>,与谁比较
class Animal implements Comparable<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 int compareTo(Animal o) {
		// TODO Auto-generated method stub
		return 0;
	}
	
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值