黑马程序员----Java集合框架学习笔记2 Map-工具类-泛型

时间:2022-03-26 19:21:36

------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------


1.Map

Map 储存键值对,必须保证键的唯一性。

Collection 区别:Map位双列集合,Collection为单列集合。

黑马程序员----Java集合框架学习笔记2 Map-工具类-泛型

常用方法:

增:.put(key,value)

删:.clear();

判断:containsKey(key)containsValue(value) isEmpty()

获取 .get(key) .size();


1.1 HashMap

与HashTable相比,线程不同步,速度快,可以允许有null键和值。

与HashSet一样,

示例:用HashMap储存Strudent 类与学生的地址。

学生类如下,重写了hashCode()与equals()方法

public class Student implements Comparable<Student>{
private String name;
private int age;
public String getName(){
return this.name;
}
public void setName(String name){
this.name=name;
}
public int getAge(){
return this.age;
}
public void setAge(int age){
this.age=age;
}
//构造函数
public Student(){

}
public Student(String name,int age){
this.name=name;
this.age=age;
}
//为了存hashSet重写hashCode与equals
public int hashCode(){
return this.name.hashCode()+this.age*33;
}
public boolean equals(Object b){
if(!(b instanceof Student))
throw new ClassCastException("类型错误");
Student t=(Student)b;
return this.name==t.getName()&&this.age==t.getAge();

}
//为了存二叉树treeSet要写compareTo,此处按年龄比较
public int compareTo(Student st) {
int num=new Integer(this.age).compareTo(st.getAge());
if(num==0){
return this.name.compareTo(st.getName());
}
else return num;
}
@Override
public String toString() {
// TODO 自动生成的方法存根
return "姓名"+this.name+",年龄"+this.age+"@@@@@@@@";
}

}

主函数

import java.util.*;
import java.util.Map.Entry;

public class MapTest {

public static void main(String[] args) {
Map<Student,String> hm=new HashMap<Student,String>();
hm.put(new Student("asdf",33), "Beijing");
hm.put(new Student("asdf",33), "nanjing");
hm.put(new Student("asdf1",33), "Shanghai");
hm.put(new Student("asdf1",34), "TIanjian");
//用keySet调用
System.out.println("=========用keySet取出元素========");
Set <Student>st=hm.keySet();
Iterator<Student>it=st.iterator();
while(it.hasNext()){
Student temp=it.next();
System.out.println(temp.toString()+hm.get(temp));
}
System.out.println("=========用entrySet取出元素========");
//用entrySet取出
Set <Map.Entry<Student, String>>st1=hm.entrySet();
Iterator<Map.Entry<Student, String>>it1=st1.iterator();
while(it1.hasNext()){
Map.Entry<Student, String> temp=it1.next();
System.out.println(temp.getKey().toString()+temp.getValue());
}
}

}


1.2 TreeMap

与TreeSet一样,采用二叉树作为底层数据结构,通过比较器以及对象(实现Coparable接口)内的compaTo()方法实现排序存储。

package com.collection;
<pre name="code" class="java">
import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
class nameComp implements Comparator<Student>{//Student类中是按年龄比较,此处构造一个比较器按姓名比较
public int compare(Student a, Student b) {
int num=a.getName().compareTo(b.getName());
if(num==0){
return new Integer(a.getAge()).compareTo(b.getAge());
}
return num;
}

}



public class TreeMapDemo {
public static void main(String[] args) {
Map<Student,String> mp=new TreeMap<Student,String>(new nameComp());//初始化时把比较器放入
mp.put(new Student("asdf",33), "Beijing");
mp.put(new Student("asdf",33), "nanjing");
mp.put(new Student("bsdf1",33), "Shanghai");
mp.put(new Student("csdf1",34), "TIanjian");
Set<Map.Entry<Student, String>> st=mp.entrySet();
Iterator<Map.Entry<Student, String>> it =st.iterator();
while(it.hasNext()){
Map.Entry<Student, String> temp=it.next();
System.out.println(temp.getKey().toString()+temp.getValue());
}
}

}

利用TreeMap计算字符串中各字符的数目

package com.collection;

import java.util.*;
/*
* 要求:计算一个字符串中各个字符的个数
* 思路:把字符串转成字符数组后遍历,把每个字符往treeMap里存,存之前先get一下treeMap里的这个字符(as key),如果返回的是Null,数目就是1,else就++再存。
*/
public class TreeSortStringDemo {

public static void main(String[] args) {
String s="asdfag biowwelxx";//给的字符串
char [] ch=s.toCharArray();//数组
TreeMap<Character,Integer> tm=new TreeMap<Character,Integer>();//初始化一个treeMap
for(int i=0;i<ch.length;i++){//遍历字符数组
char tmpCh=ch[i];
Integer val=tm.get(tmpCh);//因为下一句要比较是否为空,所以用Int的包装类
if(val==null){tm.put(tmpCh, 1);}//treeMap里没有,所以存的是1
else tm.put(tmpCh, ++val);//treeMap里有,++后再存
}
StringBuilder sb=new StringBuilder();//输出结果
Set<Map.Entry<Character, Integer>> st=tm.entrySet();
Iterator<Map.Entry<Character, Integer>> it=st.iterator();
while(it.hasNext()){
Map.Entry<Character, Integer> tmp=it.next();
sb.append(tmp.getKey()+"("+tmp.getValue()+")");
}
System.out.println(sb.toString());
}

}


1.3 LinkedHashMap

因为采用Hash值作为其储存的依据,与HashSet一样,HashMap也不能保证其键值对的顺序。这时可以采用LinkedHashMap来解决这个问题,避免了采用TreeMap时产生的浪费。

import java.util.*;
public class LinkedHashDemo {
public static void main(String[] args) {
Map<Integer,String> mp=new LinkedHashMap<Integer,String>();
mp.put(2, "basdf");
mp.put(8, "zxcvsdf");
mp.put(3, "husdf");
mp.put(5, "assasdf");
System.out.println("LinkedHashMap:"+mp);
//=======HashMap存储===========
Map<Integer,String> mp1=new HashMap<Integer,String>();
mp1.put(2, "basdf");
mp1.put(8, "zxcvsdf");
mp1.put(3, "husdf");
mp1.put(5, "assasdf");
System.out.println("HashMap:"+mp1);
}
}

2.工具类

其他的方法比较常见,不再赘述,主要要注意的是.sort(List ,Comparator)中第二个参数可以传一个比较器

package com.cn.reviev;
import java.util.*;

/**
* 对List<String>进行长度排序
*/
public class CollectionSort {
public static void main(String[] args) {
List<String> al=new ArrayList<String>();
al.add("asdfvzewe");
al.add("cbvstr");
al.add(" drte");
al.add("bve");
al.add("vzre");
al.add("cvee");
Collections.sort(al, new myCmp());//sort 第二个参数可以跟一个比较器
System.out.println(al);
}

}
class myCmp implements Comparator<String>{//根据字符串长度进行排序的比较器
public int compare(String s1,String s2){
int num=s1.length()-s2.length();
return num==0?s1.compareTo(s2):num;

}
}


 

3 泛型

作用:泛型通常使用在集合中。因为集合作为对象的容器,有一个缺点:当把对象丢进集合后,集合就会忘记对象的类型而当成Object处理。当程序从集合中取出对象后,就要进行强制类型转换,这种转换不仅使得代码臃肿,而且容易引起ClassCastException

在引入泛型后,能将这种运行时出现的ClassCastException转移到编译中来。

泛型类与方法的写法:

泛型类中定义的泛型,在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。

为了让方法可以操作不同的类型(且在编写时还不确定的类型),那么可以将泛型定义在方法上。


package com.cn.reviev;
import java.util.*;
class Foo{}
//泛型类
class UtilGen<Foo>{
private Foo foo;
public void show(Foo foo){} //泛型作为参数
public Foo get(){return foo;}//泛型作为返回值
public <T> void foo1(T t){//泛型方法(与类上定义的泛型无关)

}
public static <T> void foo2(T t){//静态泛型方法,不可以访问类上的泛型,只能将泛型定义在方法上

}
}

public class Generics {
public static void main(String[] args) {
List<String> lstr=new ArrayList<String>();
List<Integer> lint=new ArrayList<Integer>();
lstr.add("asdf");
lint.add(1000);
show(lstr);
show(lint);
}
//泛型限定: ? extends/super XX
static void show(List<?> lt){//或者写成 static <T> void show(List<T> lt)
Iterator<?>it=lt.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}

}