——- android培训、java培训、期待与您交流! ———-
泛型
泛型: JDK1.5 版本一会出现的新特性。用于解决安全问题,是一个类型安全机制。
好处:
1,运行时期出现问题ClassCastException,转移到了编译时期。
方便于程序员解决问题。也让运行时期问题减少。
2,避免了强制转换的麻烦。
泛型格式: 通过<>来定义要操作的引用数据类型。
在使用java提供的对象时,什么时候写泛型呢?
通常在集合框架中很常见。
只要见到<>就要定义泛型。
其实<>就是用来接收类型的。
如:ArrayList al = new ArrayList();
当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可
代码示例:
/*
泛型的使用
*/
import java.util.*;
public class Demo {
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();//明确集合的类型是String
al.add("java01");
al.add("java");
al.add("java03sdf");
// al.add(4);//此处不能执行,在编译时会出现异常,而不是在运行时才出现异常。将运行时异常转移到编译时异常
Iterator<String> it = al.iterator();//明确迭代器的类型是String
while(it.hasNext()){
String s = it.next();//此处省略了强制转换,因为迭代器已经明确了类型是String
print(s+" : "+s.length());
/*
结果:
java01 : 6
java : 4
java03sdf : 9
*/
}
}
public static void print(Object obj) {
System.out.println(obj);
}
}
/*
需求:
将字符串长度由小到大排序,并且使用泛型的方式
*/
import java.util.*;
public class Demo {
public static void main(String[] args) {
TreeSet<String> al = new TreeSet<String>(new MyComparator());
//此方式是错的,ArrayList构造方法不能接收MyComparator对象
//ArrayList<String> al = new ArrayList<String>(new MyComparator());
al.add("sfdgsdfsfgg");
al.add("fgsdfgfg");
al.add("asfga");
al.add("asfkk");
Iterator<String> it = al.iterator();
while(it.hasNext()){
print(it.next());
/*
结果:
asfga
asfkk
fgsdfgfg
sfdgsdfsfgg
*/
}
}
public static void print(Object obj) {
System.out.println(obj);
}
}
class MyComparator implements Comparator<String>{//Comparator也是泛型
public int compare(String o1, String o2) {//注意,此处不是public int compare(Object o1, Object o2)
int num = new Integer(o1.length()).compareTo(new Integer(o2.length()));
if(num == 0)
return o1.compareTo(o2);
return num;
}
}
泛型类
代码示例:
/*
泛型类。
什么时候使用泛型类?
当类中要操作的引用数据类型不确定的时候。
在早期定义Object来操作不确定的引用数据类型完成扩展。
现在定义泛型来完成扩展。
在类中的方法操作的都是同一种类型时,那么可以将类定义为泛型类。如ArrayList集合中的方法,操作的都是同一种类型
*/
import java.util.*;
class Student{
}
class Worker{
}
//将此类定义为泛型类
class Tool<T>{
private T t;
public void setObject(T t){
this.t = t;
}
public Object getObject(){
System.out.println("获取到了");
return t;
}
}
public class Demo {
public static void main(String[] args) {
Tool<Student> t = new Tool<Student>();
t.setObject(new Student());
// t.setObject(new Worker());//此方法编译时异常,因为Tool类型Student,当传入Worker类型时编译会出现异常
Student s = (Student) t.getObject();
}
}
泛型类的局限性
代码示例:
/*
* 演示泛型类的局限性
*
* 泛型类定义的泛型,在整个类中有效。如果泛型类的对象明确要操作的具体类型后,
* 所有要操作的类型就已经固定了。
*/
import java.util.*;
class Person<T>{
public void function(T t){
System.out.println("function:"+t);
}
public void method(T t){
System.out.println("method:"+t);
}
}
public class Demo {
public static void main(String[] args) {
Person<String> p1 = new Person<String>();//定义泛型为String,那么方法中的参数,都已经固定为String了
p1.function("haha");
// p1.method(4);//此处编译失败,因为p1这个对象指定的类型为String,则里边的方法接收的参数也为String。如: p1这个对象中的方法为 public void function(String t){},这是局限性
Person<Integer> p2 = new Person<Integer>();
p2.method(4);
// p2.function("haha");//编译失败,因为p2指定的类型为Integer,里边的方法接收的参数为Integer. 如:public void method(Integer t){},这是局限性
}
}
泛型方法
代码示例:
/*
* 为了让不同方法可以操作不同类型,而且类型还不确定。
* 那么可以将泛型定义在方法上。
*/
import java.util.*;
class Person{
public <T> void function(T t){
System.out.println("function:"+t);
}
public <T> void method(T t){
System.out.println("method:"+t);
}
}
public class Demo {
public static void main(String[] args) {
Person p = new Person();
p.function("haha");//不会编译错误。因为此方法为泛型方法。
//相当于public void function(String t){}
p.method(5);//不会编译错误。因为此方法为泛型方法。
//相当于public void method(Integer t){}
}
}
静态泛型方法代码示例:
/*
* 特殊之处:
* 静态方法不可以访问类上定义的泛型。
* 如果静态方法操作的应用数据类型不确定,可以将泛型定义在静态方法上
*
* 注意:泛型只能接受对象。如:
* public <T> void method(T t){
* System.out.println("method:"+t);
* }
* 当传入一个正数5时,系统则执行自动装箱,泛型 T 的类型为Integer而不是int
*/
import java.util.*;
class Person<T>{
public void function(T t){
System.out.println("function:"+t);
}
public <T> void method(T t){
System.out.println("method:"+t);
}
// public static void print(T t){//此方法不能执行,静态方法不可以访问类上的泛型,因为类上的泛型是随着对象的创建而加载的,而静态方法随着类加载,静态方法加载的比对象快
// }
public static <W> void print(W w){//此方法可以执行,因为是静态泛型方法
System.out.println("print:"+w);
}
}
public class Demo {
public static void main(String[] args) {
Person<String> p = new Person<String>();
p.function("haha");
//p.function(4);//编译失败,因为此方法为public void function(String t){}
p.method("hehe");//此方法没有错误,因为是泛型类。public void method(String t){}
p.method(6);//此方法没有错误,因为是泛型类。public void method(Integer t){}
Person.print("haha");
Person.print(5);
}
}
泛型接口
代码示例:
/*
* 泛型接口
*
* 开发中一般不多见
*/
import java.util.*;
interface Inter<T>{
void show(T t);
}
class Person<T> implements Inter<T>{//此处定义了泛型T,那么Person也要定义为泛型T,同时实现Inter的方法参数也为T
public void show(T t) {
System.out.println("Person show:"+t);
}
}
class Student implements Inter<String>{//若此处定义了泛型类型为String类型,则Student类不用定义为泛型,同时实现Inter的方法参数为String。
public void show(String t) {//因为接口泛型定义为String,那么此方法要能接收String类型的参数
System.out.println("Student show"+t);
}
}
public class Demo {
public static void main(String[] args) {
Person<Integer> p = new Person<Integer>();
p.show(4);
// p.show("haha");//编译失败,因为Person指定为Integer
Student s = new Student();
s.show("haha");
}
}
通配符 ?(占位符)的使用
代码示例:
/*
通配符的使用方式
*/
import java.util.*;
public class Demo {
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
al.add("java01");
al.add("java02");
al.add("java03");
print(al);
ArrayList<Integer> al1 = new ArrayList<Integer>();
al1.add(4);
al1.add(5);
al1.add(6);
print(al1);
}
public static void print(ArrayList<?> al){//ArrayList<?> al = new ArrayList<Integer>();,此处可以接收多种类型的ArrayList。
//如:ArrayList<?> al = new ArrayList<String>();此类型也可以接收
Iterator<?> it = al.iterator();
while(it.hasNext()){
System.out.println(it.next());
//System.out.println(it.next().length());//此方法不可以使用,因为接收的类型不确定,length()是针对于字符串类型使用的
/*
结果:
java01
java02
java03
4
5
6
*/
}
}
}
泛型限定
泛型的限定。
? extends E:可以接收E类型或者E的子类型。 上限限定。
? super E:可以接收E类型或者E的父类型。 下限限定。
注意:
ArrayList<String> al = new ArrayList<Integer>();
这种方式是不允许的,因为泛型必须要保证左边等于右边。如:ArrayList<String> al = new ArrayList<String>();
代码示例:
/*
泛型的上限演示: ? extends E
*/
import java.util.*;
class Person{
private String name;
public Person(String name){
this.name = name;
}
public String getName(){
return name;
}
}
class Student extends Person{
public Student(String name) {
super(name);
}
}
public class Demo {
public static void main(String[] args) {
ArrayList<Person> al = new ArrayList<Person>();
al.add(new Person("java01"));
al.add(new Person("java02"));
al.add(new Person("java03"));
print(al);
ArrayList<Student> al1 = new ArrayList<Student>();
al1.add(new Student("java001"));
al1.add(new Student("java002"));
al1.add(new Student("java003"));
//print(al1);//此处编译失败。相当于ArrayList<Person> al = new ArrayList<Student>()。
//必须保证左右两边相等才行,如ArrayList<Student> al = new ArrayList<Student>();
}
public static void print(ArrayList<Person> al){//该方法的参数ArrayList<Person> al 只能接收Person类型
Iterator<Person> it = al.iterator();
while(it.hasNext()){
System.out.println(it.next().getName());
/*
结果:
java01
java02
java03
*/
}
}
}
将以上代码修改为通用的代码如下:
/*
泛型的上限演示: ? extends E
*/
import java.util.*;
class Person{
private String name;
public Person(String name){
this.name = name;
}
public String getName(){
return name;
}
}
class Student extends Person{
public Student(String name) {
super(name);
}
}
public class Demo {
public static void main(String[] args) {
ArrayList<Person> al = new ArrayList<Person>();
al.add(new Person("java01"));
al.add(new Person("java02"));
al.add(new Person("java03"));
print(al);
ArrayList<Student> al1 = new ArrayList<Student>();
al1.add(new Student("java001"));
al1.add(new Student("java002"));
al1.add(new Student("java003"));
print(al1);
}
public static void print(ArrayList<? extends Person> al){//该方法的参数ArrayList<? extends Person> al 代表可以接收Person或者Person的子类型
Iterator<? extends Person> it = al.iterator();
while(it.hasNext()){
System.out.println(it.next().getName());//调用了父类中的getName方法。如果集合接受的是子类,子类也可以调用此方法
/*
结果:
java01
java02
java03
java001
java002
java003
*/
}
}
}
/*
泛型的下限演示: ? super E
*/
import java.util.*;
class Person {//定义一个人
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
class Student extends Person {//学生继承了人
public Student(String name) {
super(name);
}
}
class Worker extends Person {//工人也继承人
public Worker(String name) {
super(name);
}
}
class WorkerComp implements Comparator<Worker>{//定义一个 专门比较工人 的比较器,将工人进行排序
public int compare(Worker o1, Worker o2) {
return o2.getName().compareTo(o1.getName());//倒序排序
}
}
class StuComp implements Comparator<Student>{//定义一个 专门比较学生 的比较器,将学生进行排序
public int compare(Student o1,Student o2){
return o2.getName().compareTo(o1.getName());//倒序排序
}
}
public class Demo {
public static void main(String[] args) {
TreeSet<Worker> ts = new TreeSet<Worker>(new WorkerComp());//将工人比较器传入工人集合的构造方法
//TreeSet<Worker> t = new TreeSet<Worker>(new StuComp());//此方法不能执行,构造方法为:new TreeSet<Worker>(Comparator<? super Werker>),该构造方法只能接受Werker或者Werker的父类
ts.add(new Worker("worker01"));
ts.add(new Worker("worker02"));
ts.add(new Worker("worker03"));
Iterator<Worker> it = ts.iterator();
while(it.hasNext())
System.out.println(it.next().getName());
/*
结果:
worker03
worker02
worker01
*/
TreeSet<Student> ts1 = new TreeSet<Student>(new StuComp());//将学生比较器传入学生集合的构造方法
//TreeSet<Student> t1 = new TreeSet<Student>(new WorkerComp());//此方法不能执行,构造方法为:new TreeSet<Student>(Comparator<? super Student>),该构造方法只能接受Student或者Student的父类
ts1.add(new Student("student01"));
ts1.add(new Student("student02"));
ts1.add(new Student("student03"));
Iterator<Student> it1 = ts1.iterator();
while(it1.hasNext()){
System.out.println(it1.next().getName());
/*
结果:
student03
student02
student01
*/
}
}
}
修改上边的代码,新的代码如下
/*
泛型的下限演示: ? super E
*/
import java.util.*;
class Person {//人
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
class Student extends Person {//学生继承人
public Student(String name) {
super(name);
}
}
class Worker extends Person {//工人继承人
public Worker(String name) {
super(name);
}
}
class Comp implements Comparator<Person>{//此处可以接收Person的子类
public int compare(Person o1, Person o2) {
return o2.getName().compareTo(o1.getName());//倒序排序
}
}
public class Demo {
public static void main(String[] args) {
TreeSet<Worker> ts = new TreeSet<Worker>(new Comp());//将 人 的比较器传入 工人 的构造方法。 new TreeSet<Worker>(Comparator<? super Worker>),可以接收Worker或者Worker的父类型
ts.add(new Worker("worker01"));
ts.add(new Worker("worker02"));
ts.add(new Worker("worker03"));
Iterator<Worker> it = ts.iterator();
while(it.hasNext())
System.out.println(it.next().getName());
/*
结果:
worker03
worker02
worker01
*/
TreeSet<Student> ts1 = new TreeSet<Student>(new Comp());//将 人 的比较器传入 学生 的构造方法。 new TreeSet<Student>(Comparator<? super Student>),可以接收Student或者Student的父类型
ts1.add(new Student("student01"));
ts1.add(new Student("student02"));
ts1.add(new Student("student03"));
Iterator<Student> it1 = ts1.iterator();
while(it1.hasNext()){
System.out.println(it1.next().getName());
/*
结果:
student03
student02
student01
*/
}
}
}
Map集合
Map集合: 该集合存储键值对。一对一对往里存。而且要保证键的唯一性。
1,添加
<V> value = map.put(K key,V value); 返回被覆盖的value值,如果没有被覆盖,返回null
putAll(Map<? extends K,? extends V> m);
2,删除
clear(); 清空集合
<V> value = map.remove(Object key); 删除某个键
3,判断
boolean b = map.containsValue(Object value); 判断map集合是否包含值
boolean b = map.containsKey(Object key); 判断map集合是否包含键
boolean b = map.isEmpty(); 判断集合是否为空
4,获取
<V> value = map.get(Object key); 获取某个键中的值
int l = map.size(); 获取集合中元素个数
Collection<V> coll = map.values(); 获取集合中所有的值
Set<Map.Entry<K,V>> entrySet = map.entrySet(); 获取Map集合中的映射关系,存入到Set集合中
Set<K> keySet = map.keySet(); 获取键,将键存入Set集合中
|--Map
|--Hashtable:底层是哈希表数据结构,不可以存入null键和null值。
JDK1.0版本出现,效率低。该集合是线程同步的
|--HashMap:底层是哈希表数据结构,允许使用null值和null键。将Hashable代替。
JDK1.2版本出现,效率高,该集合是不同步的
|--TrreMap:底层是二叉树数据结构。可以用于给map集合中的键进行排序。线程不同步
Map和Set集合很像,其实,Set底层就是使用了Map集合
代码示例:
/*
Map集合中的方法演示
*/
import java.util.*;
public class Demo {
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>();
//添加。如果添加时,出现相同的键。那么后添加的值会覆盖原有键对应的值。
//并且put方法会返回被覆盖的值。
print(map.put("01", "zhangsan1"));//结果:null
print(map.put("01", "lisi"));//结果:zhangsan1。因为键相同,
//后添加的值覆盖原有的值,put方法返回被覆盖的值
map.put("02", "zhangsan2");
map.put("03", "zhangsan3");
map.put("04", "zhangsan4");
map.put("05", null);// HashMap支持null键和null值
print(map);//结果:{04=zhangsan4, 05=null, 01=lisi, 02=zhangsan2, 03=zhangsan3},输出结果是无序的,因为HashMap底层数据结构是哈希表
//删除
map.remove("02");
print(map);//结果:{04=zhangsan4, 05=null, 01=lisi, 03=zhangsan3}
//判断
print(map.containsKey("03"));//结果:true。可以判断集合map中是否包含键03
//获取
print(map.get("02"));//结果:null。可以用get方法判断集合中是否包含元素,如果返回值为null,则不包含
//print(map.get("03"));//结果:zhangsan3。可以用get方法判断集合中是否包含元素,如果返回值为null,则不包含
Collection<String> coll = map.values();
print(coll);//结果:[zhangsan4, null, lisi, zhangsan3]
}
public static void print(Object obj){
System.out.println(obj);
}
}
Map集合的第一种取出方式(KeySet方法)
代码示例:
/*
keySet方法的使用
Set<K> KeySet:将map中所有的键存入到Set集合。因为Set集合具备迭代器。
所以可以用迭代器的方式取出所有的键,再根据get方法,获取每一个键对应的值
Map集合取出原理:将Map集合转成Set集合,再通过迭代器取出。
*/
import java.util.*;
public class Demo {
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>();
map.put("01", "zhangsan1");
map.put("02", "zhangsan2");
map.put("03", "zhangsan3");
map.put("04", "zhangsan4");
Set<String> keySet = map.keySet();//先获取map集合中所有键的Set集合
Iterator<String> it = keySet.iterator();//有了Set集合。就可以获取其迭代器
while(it.hasNext()){
String key = it.next();//迭代器中的类型属于String
String value = map.get(key);//有了键,就可以通过Map集合的get方法获取其对应的值
print("key:"+key+" value:"+value);
/*
结果:
key:04 value:zhangsan4
key:01 value:zhangsan1
key:02 value:zhangsan2
key:03 value:zhangsan3
*/
}
}
public static void print(Object obj){
System.out.println(obj);
}
}
Map集合的第二种取出方式(entrySet方法)
代码示例:
/*
entrySet方法的使用
Set<Map.Entry<K,V> entrySet: 将map集合中的映射关系存入到集合中,
而这个关系的数据类型就是:Map.Entry
*/
import java.util.*;
public class Demo {
public static void main(String[] args) {
Map<String,String> map = new HashMap<String, String>();
map.put("01", "zs1");
map.put("02", "zs2");
map.put("03", "zs3");
map.put("04", "zs4");
//将Map集合中的映射关系取出,存入到Set集合中
Set<Map.Entry<String, String>> entrySet = map.entrySet();
//有了Set集合。就可以获取其迭代器
Iterator<Map.Entry<String, String>> it = entrySet.iterator();
while(it.hasNext()){
Map.Entry<String, String> me = it.next();//迭代器中的类型属于Map.Entry<String, String>
String key = me.getKey();//Map.Entry<String, String>中的key类型属于String
String value = me.getValue();//Map.Entry<String, String>中的key类型属于String
print(key+".."+value);
}
}
public static void print(Object obj){
System.out.println(obj);
}
}
Map集合的练习
/*
* 每一个学生都有对应的归属地。
* 学生Student,地址String.
* 学生属性:姓名,年龄。
* 注意:姓名和年龄相同视为同一个学生。
* 保证学生的唯一性。
*
* 1,描述学生。
* 2,定义map容器。将学生作为键,地址作为值。存入。
* 3,获取map集合中的元素。
*/
import java.util.*;
class Student implements Comparable<Student>{
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public int hashCode() {//覆盖hashCode方法,为了保证唯一性
return name.hashCode() + age*15;
}
public boolean equals(Object obj) {//覆盖equals方法,为了保证唯一性
if (!(obj instanceof Student))
throw new ClassCastException("类型不匹配");
Student stu = (Student) obj;
return this.name.equals(stu.getName()) && this.age==stu.getAge();
}
public int compareTo(Student s) {//实现compareTo方法,使数据按照姓名排序
int num = this.name.compareTo(s.getName());
if(num == 0){
return new Integer(this.age).compareTo(new Integer(s.getAge()));
}
return num;
}
}
public class Demo {
public static void main(String[] args) {
HashMap<Student, String> hs = new HashMap<Student, String>();
hs.put(new Student("zhangsan", 20), "北京");
hs.put(new Student("zhangsan", 20), "北京");
hs.put(new Student("lisi", 25), "北京");
hs.put(new Student("wangwu", 30), "天津");
//第一种获取方式
Set<Student> keySet = hs.keySet();//先获取map集合中所有键的Set集合
Iterator<Student> it = keySet.iterator();//有了Set集合。就可以获取其迭代器
while(it.hasNext()){
Student key = it.next();//获取键
String value = hs.get(key);//获取键的值
print("name=" + key.getName() + "...age=" + key.getAge() + "...地址="+ value);
/*
结果:
name=lisi...age=25...地址=北京
name=zhangsan...age=20...地址=北京
name=wangwu...age=30...地址=天津
*/
}
//第二种获取方式
Set<Map.Entry<Student, String>> entrySet = hs.entrySet();//将Map集合中的映射关系取出,存入到Set集合中
Iterator<Map.Entry<Student, String>> it1 = entrySet.iterator();//有了Set集合。就可以获取其迭代器
while (it1.hasNext()) {
Map.Entry<Student, String> me = it1.next();//迭代器中的类型属于Map.Entry<String, String>
Student stu = me.getKey();//获取键
String s = me.getValue();//获取值
print("name=" + stu.getName() + "........age=" + stu.getAge() + "........地址="+ s);
/*
结果:
name=lisi........age=25........地址=北京
name=zhangsan........age=20........地址=北京
name=wangwu........age=30........地址=天津
*/
}
}
public static void print(Object obj) {
System.out.println(obj);
}
}
/*
* 每一个学生都有对应的归属地。
* 学生Student,地址String.
* 学生属性:姓名,年龄。
* 注意:姓名和年龄相同视为同一个学生。
* 保证学生的唯一性。
*
*
* 需求:对学生对象的 年龄 进行升序排序。
*
* 因为数据是以键值对形式存在的。
* 所以要使用可以排序的Map集合。TreeMap
*/
import java.util.*;
class Student implements Comparable<Student>{
private String name;
private int age;
public Student(String name,int age){
this.name = name;
this.age = age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public int hashCode(){//覆盖hashCode方法,为了保证唯一性
return name.hashCode() + age*18;
}
public boolean equals(Object obj){//覆盖equals方法,为了保证唯一性
if(!(obj instanceof Student))
throw new ClassCastException("类型转换异常");
Student stu = (Student)obj;
return this.name.equals(stu.getName()) && this.age == stu.getAge();
}
public int compareTo(Student stu){//实现compareTo方法,使数据按照姓名排序
int num = name.compareTo(stu.getName());
if(num == 0)
return new Integer(age).compareTo(new Integer(stu.getAge()));
return num;
}
}
//定义一个比较器,使学生按照年龄排序
class StuAgeComparator implements Comparator<Student>{
public int compare(Student s1,Student s2){
int num = new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
if(num == 0)
return s1.getName().compareTo(s2.getName());
return num;
}
}
public class Demo {
public static void main(String[] args) {
TreeMap<Student, String> tm = new TreeMap<Student,String>(new StuAgeComparator());
tm.put(new Student("zhangsan", 20), "天津");
tm.put(new Student("zhangsan", 20), "北京");
tm.put(new Student("lisi", 25), "北京");
tm.put(new Student("wangwu", 30), "天津");
Set<Map.Entry<Student, String>> entrySet = tm.entrySet();
Iterator<Map.Entry<Student, String>> it = entrySet.iterator();
while(it.hasNext()){
Map.Entry<Student, String> me = it.next();
Student stu = me.getKey();
String s = me.getValue();
print("name:"+stu.getName()+"...age:"+stu.getAge()+"...name:"+s);
/*
结果:
name:zhangsan...age:20...name:北京
name:lisi...age:25...name:北京
name:wangwu...age:30...name:天津
*/
}
}
public static void print(Object obj) {
System.out.println(obj);
}
}
/*
* 练习:
* "abcdeabcab"获取字符串中的字符出现次数。
*
* 希望打印结果:a(3)b(3)c(2)....
*
* 通过结果发现,每一个字母都有对应的次数,
* 说明字符和次数之间都有映射关系。
*
* 注意:当发现有映射关系时,可以选择Map集合。因为Map集合中存放的就是映射关系。
*
* 说明时候使用Map集合呢?
* 当数据之间存在映射关系时,就要现象Map集合。
*
* 思路:
* 1,将字符串转换成字符数组。因为要对每一个字母进行操作。
* 2,定义一个Map集合,因为打印结果有序,所以使用TreeMap集合。
* 3,遍历字符数组。
* 将每一个字母作为键去查Map集合。
* 如果返回null,将该字母和1存入到Map集合中。
* 如果返回不为null,说明该字符在集合中已经存在,并有对应的次数。
* 那么就获取该次数并进行自增,然后将该字母和自增后的次数存入到Map集合中,并覆盖掉原来键所对应的值 。
* 4,将Map集合中的数据变成指定的字符串返回。
*/
import java.util.*;
public class Demo {
public static void main(String[] args) {
String s = charCount("abcdeabcab");
System.out.println(s);//结果:a(3)b(3)c(2)d(1)e(1)
}
public static String charCount(String s) {
StringBuilder sb = new StringBuilder();
char[] chs = s.toCharArray();
TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();//创建一个TreeMap集合
for(int i=0;i<chs.length;i++){
Integer value = tm.get(chs[i]);//获取键值
if(value == null){
tm.put(chs[i], 1);
}
else{
value = value+1;
tm.put(chs[i], value);
}
}
Set<Map.Entry<Character,Integer>> entrySet = tm.entrySet();//将TreeMap的映射存入到Set集合中
Iterator<Map.Entry<Character,Integer>> it = entrySet.iterator();//有了Set集合。就可以获取其迭代器
while(it.hasNext()){
Map.Entry<Character,Integer> me = it.next();//迭代器中的类型属于Map.Entry<String, String>
sb.append(me.getKey()+"("+me.getValue()+")");
}
return sb.toString();
}
}
Map集合的扩展知识
/*
* Map扩展知识。
*
* Map集合被使用时因为具备映射关系。
*
* "yureban" "01" "zhangsan";
* "yuerban" "02" "lisi";
* "jiuyeban" "01" "wangwu";
* "jiuyeban" "02" "zhaoliu";
*
* 一个学校有 名字和多个教室,每个教室都有 学号和学生。
* 如:一个学校名字为czbk,并且有yureban和jiuyeban。yureban中有
* 多个学号和姓 名。jiuyeban中有 多个学号和姓名
*/
import java.util.*;
public class Demo {
public static void main(String[] args) {
//创建一个学校,学校中可以存放 教室名和教室中的内容
HashMap<String, HashMap<String, String>> czbk = new HashMap<String, HashMap<String,String>>();
//创建预热班教室,教室中可以存放 学号和姓名
HashMap<String,String> yure = new HashMap<String, String>();
//创建就业班教室,教室中可以存放 学号和姓名
HashMap<String,String> jiuye = new HashMap<String, String>();
czbk.put("yureban", yure);
czbk.put("jiuyeban", jiuye);
yure.put("01", "zhangsan");
yure.put("02", "lisi");
jiuye.put("01", "wangwu");
jiuye.put("02", "zhaoliu");
//遍历czbk集合。获取所有教室
Iterator<String> it = czbk.keySet().iterator();
while(it.hasNext()){
String key = it.next();
HashMap<String, String> value = czbk.get(key);
print(key);
printHashMap(value);
}
}
public static void printHashMap(HashMap<String, String> hm){
Set<Map.Entry<String, String>> entrySet = hm.entrySet();
Iterator<Map.Entry<String, String>> it = entrySet.iterator();
while(it.hasNext()){
Map.Entry<String, String> me = it.next();
String key = me.getKey();
String value = me.getValue();
print("xuehao:"+key+"....name:"+value);
/*
结果:
jiuyeban
xuehao:01....name:wangwu
xuehao:02....name:zhaoliu
yureban
xuehao:01....name:zhangsan
xuehao:02....name:lisi
*/
}
}
public static void print(Object obj){
System.out.println(obj);
}
}
/*
* Map扩展知识。
*
* Map集合被使用时因为具备映射关系。
*
* "yureban" Student("01" "zhangsan");
* "yuerban" Student("02" "lisi");
* "jiuyeban" Student("01" "wangwu");
* "jiuyeban" Student("02" "zhaoliu");
*
* 一个学校有多个教室,每个教室都有学号和姓名,把每个教室中的学号和姓名封装成对象。
* 这种映射关系使用HashMap<String, ArrayList<Student>>
* 在开发中这种用法比较常见
*/
import java.util.*;
import java.util.Map.Entry;
class Student{
String name;
int age;
public Student(String name,int age){
this.name = name;
this.age = age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public String toString(){
return name + "....." + age;
}
}
public class Demo {
public static void main(String[] args) {
//创建一个学校,学校中可以存放 教室名和学生对象。
HashMap<String, List<Student>> czbk = new HashMap<String, List<Student>>();
//创建一个 预热班 的学生集合
ArrayList<Student> yure = new ArrayList<Student>();
//创建一个 就业班 的学生集合
ArrayList<Student> jiuye = new ArrayList<Student>();
//将 预热班 学生的集合添加到 预热班 中
czbk.put("yureban", yure);
//将 就业班 学生的集合添加到 就业班 中
czbk.put("jiuyeban", jiuye);
yure.add(new Student("zhangsan01",20));//在预热班中添加一个学生对象
yure.add(new Student("zhangsan02",30));//在预热班中添加一个学生对象
jiuye.add(new Student("lisi01",20));//在就业班中添加一个学生对象
jiuye.add(new Student("lisi02",30));//在就业班中添加一个学生对象
Iterator<Map.Entry<String, List<Student>>> it = czbk.entrySet().iterator();
while(it.hasNext()){
Map.Entry<String, List<Student>> me = it.next();
String key = me.getKey();
List<Student> value = me.getValue();
print(key);
printArrayList(value);
/*
结果:
jiuyeban
lisi01.....20
lisi02.....30
yureban
zhangsan01.....20
zhangsan02.....30
*/
}
}
public static void printArrayList(List<Student> al){
Iterator<Student> it = al.iterator();
while(it.hasNext()){
Student stu = it.next();
print(stu); //相当于print(stu.toString());
}
}
public static void print(Object obj){
System.out.println(obj);
}
}