map

来源:互联网 发布:淘宝魔兽带团本 编辑:程序博客网 时间:2024/06/06 02:26
1.集合
1.1.Map
什么是Map?
Map 是映射接口,Map中存储的内容是键值对(key-value)。
Map映射中不能包含重复的键;每个键最多只能映射到一个值。值允许重复。
Map接口提供三种查看方式,允许以键集、值集或键-值映射关系集的形式查看某个映射的内容。
Map 映射顺序。TreeMap有序,HashMap无序。
什么是键值对?(key-value)
键:就是你存的值的编号
值:就是你要存放的数据
1.2.HashMap的API
HashMap的常见用法:可举例(学号加姓名)
/**
 * hashMap的常见用法 
 * 键不能重复,值可以重复
 * 无序
 * @author Administrator
 *
 */
public class TestMap01 {
public static void main(String[] args) {
// Map map = new HashMap();
HashMap<Integer,String> map = new HashMap<Integer,String>();
//键-值
map.put(101, "jack");
map.put(102, "tom");
map.put(103, "bob");
map.put(104, "jack");
map.put(103, "kate");
//判断是否包含某个键
System.out.println("是否包含键‘103’:"+map.containsKey(103));
//判断是否包含某个值
System.out.println("是否包含值‘jack':"+map.containsValue("jack"));
//查看集合的元素个数
System.out.println("集合中的元素个数:"+map.size());
//根据键取值
System.out.println("‘103’这个键对应的值为:"+map.get(103));
System.out.println("------遍历1根据键获取值-----");
searchKeys(map);
System.out.println("------遍历2键-值集获取的对应的键-值对的集合-----");
searchEntry(map);
System.out.println("------遍历3直接获取值集----");
searchValues(map);
}
1.3.HashMap遍历的三种方式
1.直接获取键值对
2.根据键取值
3.直接得到值的集合
/**
* 方式1 根据键-获取值 ,最常用的
*/
public static void searchKeys(HashMap<Integer,String> map){
//获取所有的键对应的集合
Set<Integer> keys = map.keySet();
//遍历键集,根据键获取值
//获取迭代器对象
Iterator<Integer> it = keys.iterator();
while(it.hasNext()){
//获取的键
Integer key = it.next();
//根据键获取值
String value = map.get(key);
System.out.println("[键:"+key+",值:"+value+"]");
}
}
/**
* 方式2 :获取的就是键-值对对应的集合最好
* @param map
*/
public static void searchEntry(HashMap<Integer,String> map){
//Map.Entry(键,值) 接口 看成是一种类型,该类型带了2个参数,set集合中的每一个元素都是实现了Map.Entry()接口的这种类型的元素 ,元素格式  "键=值"
Set<Map.Entry<Integer, String>> set = map.entrySet();
//获取迭代器
Iterator<Map.Entry<Integer, String>> it = set.iterator();
while(it.hasNext()){
Map.Entry<Integer,String> en = it.next();
// System.out.println("****"+en);
//获取键
Integer key = en.getKey();
//获取值
String value = en.getValue();
System.out.println("[键:"+key+",值:"+value+"]");
}
}

/**
* 方式3:直接获取值集
* @param map
*/
public static void searchValues(HashMap<Integer,String>map){
//Collection
Collection<String> col = map.values();
//获取迭代器对象
Iterator<String> it = col.iterator();
while(it.hasNext()){
String value = it.next();
System.out.println("值:"+value);
}
}
1.4.泛型
什么是泛型?
JDK5引入泛型。
目的一是解决集合使用过程中的运行时类型错误,约束自己的编码。在代码中定义的List<Integer>和List<String>等类型,在编译之后都会变成List。JVM看到的只是List,而由泛型附加的类型信息对JVM来说是不可见的。这个过程就称为类型擦除。
目的二是对类型系统的扩展,支持创建可以按类型进行参数化的类。
泛型的作用?
Map m = new HashMap();
m.put("S001", "小明");
String s = (String) m.get("S001");
System.out.println(s);
因为 Map.get() 被定义为返回 Object,所以一般必须将 Map.get() 的结果强制类型转换为想要的类型如String,如将 get() 的结果强制类型转换为 String,并且希望结果真的是一个 String。但是有可能在该映射中保存了不是 String 的东西,这样的话,上面的代码将会抛出 ClassCastException。
我们想要
如果能规定里面储存的对象类型,防止将错误类型的键或值保存在集合中,就不会存在潜在的异常风险。
泛型的好处:方便、安全
举例子:用泛型,不用泛型
Map m = new HashMap();
m.put("S001", "小明");
m.put("s102", "张三");
m.put("S003", new Dog("旺财","吉娃娃"));
// String s = (String) m.get("S001");
//java.lang.ClassCastException S003该键对应的值是1个Dog对象,而我们把它强转成1个String对象
String s =(String)m.get("S003");
System.out.println(s);
练习
Map m = new HashMap();
m.put("S001", "小明");
String s = (String) m.get("S001");
System.out.println(s);
该代码改为泛型,确保put只能添加String而不能添加Book类,输出时不用做强制转换。
1.5.开发自己的泛型类
观察JDK中Map接口如何定义
public interface Map<K, V> {
public void put(K key, V value);
public V get(K key);
}
注意该接口在类的声明中使用了K和V,表示在声明一个 Map 类型的变量时指定的类型的占位符。在 get()、put() 和其他方法的方法声明中使用的 K 和 V。所以我们才可以这样用:
Map<String, String> m = new HashMap<String, String>();
m.put("S001", "小明");
String s = m.get("S001");
命名类型参数
K —— 键,比如映射的键。 
V —— 值,比如 List 和 Set 的内容,或者 Map 中的值。 
E —— 异常类。 
T —— 泛型。
模仿Map接口开发自己的泛型类
(1)存放个人信息(性别表述方式变化)
分析: String  sex  ,“男”,”女” ,char  字符类型 ‘男’,’女’, int  整数类型  1:男   0:女 
public class Person<T> {
private String name;
private T sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public T getSex() {
return sex;
}
public void setSex(T sex) {
this.sex = sex;
}
public Person(String name, T sex) {
super();
this.name = name;
this.sex = sex;
}
public Person() {

}
@Override
public String toString() {
return "姓名:"+this.name+",性别:"+this.sex;
}
}
public class TestPerson {
public static void main(String[] args) {
//性别String 
Person<String> p1 = new Person<String>();
p1.setName("张三");
p1.setSex("男");
System.out.println(p1.toString());
//char字符
Person<Character> p2 = new Person<Character>();
p2.setName("李四");
p2.setSex('男');
System.out.println(p2.toString());
//int类型
Person<Integer> p3 = new Person<Integer>();
p3.setName("王五");
p3.setSex(1);
System.out.println(p3.toString());
}
}
(2)存放商品信息(商品价格从int变为double)
分析: 商品 2个属性   商品名  ,商品价格 Goods<T>
(3)设置点的坐标(x,y)(可以为整型,可以为浮点型,可以为String)
分析: int,double,String  类 Point<K,T>  
1.6.类型通配符
public static void main(String args[]) {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
printList(list);
}
public static void printList(List list) {
for (Object o : list)
System.out.println(o);
}
如果试图用 List<Integer> 调用printList,会得到警告。
如果改为List<Object>还是会出错
解决方案是使用通配符
上面代码中的问号是一个类型通配符。List<?> 是任何泛型 List 的父类型,所以可以将 List<Object>、List<Integer>传递给 printList()。
例题:
public class TestArrayList02 {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(30);
printList(list);
System.out.println("-------------------------");
List<String> list2 = new ArrayList<String>();
list2.add("tom");
list2.add("jack");
list2.add("bob");
printList(list2);
System.out.println("-------------------------");
List<Double> list3 = new ArrayList<Double>();
list3.add(12.33);
list3.add(21.33);
printList(list3);
}
/**
* 遍历List集合
* @param list
*/
public static void printList(List<?> list) {
for (Object o : list)
System.out.println(o);
}
}
1.7.类型系统的两个维度
引入泛型之后的类型系统增加了两个维度:一个是类型参数自身的继承体系结构,另外一个是泛型类或接口自身的继承体系结构。
当泛型类的类型声明中使用了通配符的时候, 其子类型可以在两个维度上分别展开:
在List维度展开
List<String> list;
ArrayList<String>;
在类型维度展开
List<String> list;
List<?> list2;
1.8.Properties使用
什么是配置文件?
配置文件中很多变量经常改变,如果配置经常改变,而不希望修改代码,可以把配置保存在单独的文件中,让用户能够脱离程序去修改相关的配置。
Properties的作用?
读取Java的配置文件
步骤:1.在src下创建XXX.proterties ( 选中src,右击 ---new---file--输入文件名 XXX.properties)
2.新建Properties对象 ,通过load(),将配置文件信息加载进内存,读取保存到p变量中
3.配置文件的信息已经读取保存在p变量里了,要获取对应的迭代器对象 ,遍历,读出内容
/**
 * 将src下的配置文件config.properties中的内容读取出来,输出在控制台
 * load(InputStream ins)
 * @author Administrator
 *
 */
public class TestProperties {
public static void main(String[] args) {
//2.新建properties对象,通过p.load()方法,加载进内存
Properties p = new Properties();
try {
//先获取类对象,然后拿到类加载器,加载配置文件
p.load(TestProperties.class.getClassLoader().getResourceAsStream("config.properties"));
/*//获取类对象
Class cla = TestProperties.class;
//获取输入流对象
InputStream ins = cla.getClassLoader().getResourceAsStream("config.properties");
//加载输入流对象
p.load(ins);*/
//3.配置文件的信息已经读取保存在p变量里了,要获取对应的迭代器对象 ,遍历,读出内容
Enumeration<String> en = (Enumeration<String>)p.propertyNames();
while(en.hasMoreElements()){
// System.out.println(en.nextElement());
//获取键
String key = en.nextElement();
//获取值
String value = p.getProperty(key);
System.out.println("键="+key+",值="+value);
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("加载配置文件出错,出错信息:"+e.getMessage());
}catch (NullPointerException e) {
e.printStackTrace();
System.out.println("出错信息:"+e.getMessage());
}
}
}
3.1.比较接口,比较器
学号  姓名 分数
1“张三” 89
2“李四” 78
3 “tom” 98
4 “bob”  45
5 “helen” 78
6  “李四” 78
需求1: 先按分数升序排列,如果分数相同,按学号升序排列 
需求2:先按分数降序排列,如果分数相同,按姓名升序排列,如果姓名相同,按学号降序排列
需求3:先按姓名降序排列,姓名相同,按学号升序
新闻标题类 NewsItem   新闻编号int  Id  ,新闻标题String title   ,新闻的出版时间java.util.Date, publishDate   
需求: 先按出版时间升序排列,如果出版时间相同,按标题的降序排列,如果标题相同,按新闻编号的升序排列  
编号   标题    出版时间 
101   财经    ‘2014-5-6’
103   体育     ‘2012-5-6’
109   娱乐     ‘2016-7-8’
105   篮球      ‘2015-6-7’
108    足球      ‘2017-3-2’
分析: 1条数据 看成1个Student对象 ,Student类 ,3个属性 学号  stuNo int  ,姓名name String,分数 score int
6个对象 ,存储到哪里呢? 思路1 存储到集合中(方便)  List<Student> list = new ArrayList<Student>();  思路2: 存储到对象数组中 Student[] stuArr = new Student[10];
方式1:  1. 要排序的类Student类 实现比较接口   implements Comparable接口 ,重写 compareTo比较方法 (比较的规则要和需求一致)  
2.测试类中,集合中添加数据 ,对集合对象List排序 ,借助工具类Collections.sort(list)   ,测试类中,对象数组中添加数据,对对象数组排序  ,借助工具类 Arrays.sort(stuArr)  
package com.njwb.compareabletest;
public class Student implements Comparable<Student> {
private int stuNo; //学号
private String name; //姓名
private int score; //成绩
public Student() {

}
public Student(int stuNo, String name, int score) {
super();
this.stuNo = stuNo;
this.name = name;
this.score = score;
}


public String getName() {
return name;
}
public int getScore() {
return score;
}
public int getStuNo() {
return stuNo;
}
public void setName(String name) {
this.name = name;
}
public void setScore(int score) {
this.score = score;
}
public void setStuNo(int stuNo) {
this.stuNo = stuNo;
}


/**
* 需求1: 先按分数升序排列,如果分数相同,按学号升序排列 
*/
/*@Override
public int compareTo(Student o) {
int result = this.score-o.score; //分数的升序 
if(result==0){ //分数相同
result = this.stuNo-o.stuNo; //学号的升序
}
return result;
}*/
/**
* 需求2:先按分数降序排列,如果分数相同,按姓名升序排列,如果姓名相同,按学号降序排列
*/
/*@Override
public int compareTo(Student o) {
int result = -(this.score-o.score); //分数的降序 
if(result==0){ //分数相同
result = this.name.compareTo(o.name); //姓名的升序
if(result==0){ //姓名相同
result= -(this.stuNo-o.stuNo);
}
}
return result;
}*/

/**
* 需求3:先按姓名降序排列,姓名相同,按学号升序
*/
@Override
public int compareTo(Student o) {
int result =-this.name.compareTo(o.name); //姓名的降序
if(result==0){ //姓名相同
result = this.stuNo-o.stuNo;  //学号升序
}
return result;
}

@Override
public String toString() {
return this.getStuNo()+"\t"+this.getName()+"\t"+this.getScore();
}
}
package com.njwb.compareabletest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TestStudent01 {
public static void main(String[] args) {
List<Student> list = new ArrayList<Student>();
list.add(new Student(6,"李四",78));
list.add(new Student(1,"张三",89));
list.add(new Student(2,"李四",78));
list.add(new Student(3,"tom",98));
list.add(new Student(4,"bob",45));
list.add(new Student(5,"helen",78));
System.out.println("排序前:");
for(Student s:list){
System.out.println(s);
}
//调用排序
Collections.sort(list);
System.out.println("排序后:");
for(Student s:list){
System.out.println(s);
}
}
}
package com.njwb.compareabletest;
import java.util.Arrays;
public class TestStudent02 {
public static void main(String[] args) {
Student[] stuArr = new Student[6];
stuArr[0] = new Student(6,"李四",78);
stuArr[1] = new Student(1,"张三",89);
stuArr[2] = new Student(2,"李四",78);
stuArr[3] = new Student(3,"tom",98);
stuArr[4] = new Student(4,"bob",45);
stuArr[5] = new Student(5,"helen",78);
System.out.println("排序前:");
for(Student s:stuArr){
System.out.println(s);
}
//调用排序
Arrays.sort(stuArr);
System.out.println("排序后:");
for(Student s:stuArr){
System.out.println(s);
}
}
}
package com.njwb.compareabletest;


import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
 * binarySearch(集合对象,要查找的元素对象)  该方法必须排序后才有效,如果在排序前调用,结果可能不正确
 * max 一般是排序后的末尾元素
 * min  一般是排序后的首个元素
 * reverse 反转  ,排序后集合元素反转
 * @author Administrator
 *
 */
public class TestStudent03 {
public static void main(String[] args) {
List<Student> list = new ArrayList<Student>();

Student stu1 = new Student(6,"李四",78);
Student stu2 = new Student(1,"张三",89);
Student stu3 = new Student(2,"李四",78);
Student stu4 = new Student(3,"tom",98);
Student stu5 = new Student(4,"bob",45);
Student stu6 = new Student(5,"helen",78);

list.add(stu1);
list.add(stu2);
list.add(stu3);
list.add(stu4);
list.add(stu5);
list.add(stu6);

System.out.println("排序前:");
for(Student s:list){
System.out.println(s);
}
//判断某一个元素的索引位置  ,比方说stu1 李四所在的索引位置  结果是-4,为什么不是0,因为该方法必须在排序后才有效
System.out.println("排序前stu1所在的索引位置:"+Collections.binarySearch(list, stu1));
//调用排序
Collections.sort(list);
System.out.println("排序后:");
for(Student s:list){
System.out.println(s);
}
//集合中的最大值 默认是排序后的最后一个元素
System.out.println("最大值:\n"+Collections.max(list));
//集合中的最小值 默认是排序后的第一个元素
System.out.println("最小值:\n"+Collections.min(list));

//判断某一个元素的索引位置  ,比方说stu4 tom所在的索引位置
System.out.println("排序后stu4所在的索引位置:"+Collections.binarySearch(list, stu4));
//集合元素的反转  
Collections.reverse(list);
System.out.println("反转后:");
for(Student s:list){
System.out.println(s);
}
}
}
方式2: 
1.新建Student类  2.新建比较器类 StudentComparator ,比较器类实现Comparator接口(java.util.Comparator),重写比较方法int compare(Student o1, Student o2) 
2.测试类和之前的相同  新建集合对象 ,存储数据 ,通过Collections工具类调用比较方法 
public class Student {
private int stuNo; //学号
private String name; //姓名
private int score; //成绩
public Student() {

}

public Student(int stuNo, String name, int score) {
super();
this.stuNo = stuNo;
this.name = name;
this.score = score;
}


public String getName() {
return name;
}
public int getScore() {
return score;
}
public int getStuNo() {
return stuNo;
}
public void setName(String name) {
this.name = name;
}
public void setScore(int score) {
this.score = score;
}
public void setStuNo(int stuNo) {
this.stuNo = stuNo;
}


@Override
public String toString() {
return this.getStuNo()+"\t"+this.getName()+"\t"+this.getScore();
}
}
package com.njwb.comparatoruse;
import java.util.Comparator;
public class StudentComparator implements Comparator<Student> {
/**
* 需求1: 先按分数升序排列,如果分数相同,按学号升序排列 
*/
/*@Override
public int compare(Student o1, Student o2) {
int result = o1.getScore()-o2.getScore(); //分数升序
if(result==0){ //分数相同
result=o1.getStuNo()-o2.getStuNo(); //学号升序
}
return result;
}*/

/**
* 需求2:先按分数降序排列,如果分数相同,按姓名升序排列,如果姓名相同,按学号降序排列
*/
/*@Override
public int compare(Student o1, Student o2) {
int result = -(o1.getScore()-o2.getScore()); //分数降序
if(result==0){ //分数相同
result = o1.getName().compareTo(o2.getName()); //姓名的升序
if(result==0){ //姓名相同
result = -(o1.getStuNo()-o2.getStuNo()); //学号降序
}
}
return result;
}*/

/**
* 需求3:先按姓名降序排列,姓名相同,按学号升序
*/
@Override
public int compare(Student o1, Student o2) {
int result = -o1.getName().compareTo(o2.getName()); //姓名降序
if(result==0){ //姓名相同
result = o1.getStuNo()-o2.getStuNo(); //学号升序
}
return result;

}
/**
* 需求3:先按姓名降序排列,姓名相同,按学号升序
*/
/*@Override
public int compare(Student o1, Student o2) {
if(o1.getName().compareTo(o2.getName())>0){
return -1;      //降序
}else if(o1.getName().compareTo(o2.getName())<0){
return 1;
}else{
if(o1.getStuNo()-o2.getStuNo()>0){
return 1; //学号升序
}else if(o1.getStuNo()-o2.getStuNo()<0){
return -1;
}else{
return 0;
}
}
}*/
}
package com.njwb.comparatoruse;


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


public class TestStudent01 {
public static void main(String[] args) {
List<Student> list = new ArrayList<Student>();
list.add(new Student(6,"李四",78));
list.add(new Student(1,"张三",89));
list.add(new Student(2,"李四",78));
list.add(new Student(3,"tom",98));
list.add(new Student(4,"bob",45));
list.add(new Student(5,"helen",78));


System.out.println("排序前:");
for(Student s:list){
System.out.println(s);
}
//调用排序
Collections.sort(list, new StudentComparator());
System.out.println("排序后:");
for(Student s:list){
System.out.println(s);
}
}
}
3.2.Vector使用 (Vector 类可以实现可增长的对象数组)
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;
/**
 * Vector用法和ArrayList基本相同 有序
 * @author Administrator
 *
 */
public class TestVector01 {
public static void main(String[] args) {
//新建集合对象
Vector<String> vec = new Vector<String>();
vec.add("jack");
vec.add("tom");
vec.add("bob");
vec.add("kate");
System.out.println("--------for遍历--------------");
for(int i=0;i<vec.size();i++){
System.out.println(vec.get(i));
}
System.out.println("--------foreach遍历--------------");
for(String s:vec){
System.out.println(s);
}
System.out.println("--------Iterator迭代器遍历--------------");
//获取迭代器对象
Iterator<String> it = vec.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
System.out.println("--------Enumeration迭代器遍历--------------");
//Enumaration 和Iterator类似的,比较古老的迭代器 ,hasMoreElement()判断是否有值
//nextElement()获取值
//获取迭代器对象
Enumeration<String> en = vec.elements();
while(en.hasMoreElements()){
System.out.println(en.nextElement());
}
}
}
原创粉丝点击