JAVA------集合


一,概述
    Map集合:该集合存储键值对,一对一对的往里存,而且要保证键的唯一性。形象的比喻:Collection存的都是单身汉,Map存的是一对夫妻。
二,Map分类
    1, Hashtable:底层是哈希表数据结构,不可以出现null作为键和null作为值得情况。从JDK1.0开始出现,该集合是线程同步的,效率低。
    2, HashMap:底层是哈希表数据结构,允许使用null作为键,null作为值的情况。从JDK2.0开始出现,该集合线程不同步,效率高。
    3, TreeMap:底层是二叉树数据结构,线程是不同步的,可以用于给Map集合中的键值进行排序。
二,Map的方法
   1,添加。
   V put(K key, V value) :添加元素时,如果该键不存在,返回null;出现添加相同键时,后添加的值会覆盖原有的键对应的值,put方法会返回被覆盖的值。
   void putAll(Map<? extends K,? extends V> m)  
   2,删除。
   void clear();
   V remove(Object key) ;
   3,判断。
   boolean containsKey(Object key);
   boolean containsValue(Object value); 
   boolean isEmpty();
   4,获取。
   V get(Object key);
   int size();
   Collection<V> values();
  下面这个例子是对上面一些方法的应用
    
    
import java.util.*;
public class MapFun1 {
public static void main(String args[])
{
Map<String,String> map=new HashMap<String,String>();
System.out.println(map.put("01","zhangsan"));//当键“01”不存在时,存入值之后返回空,如果"01"存在了,返回"01"对应的值,并将新的值赋给该键对应的值
System.out.println(map.put("01","zhouliu"));
map.put("02","lisi");
map.put("03","wangwu");
System.out.println("ContainsKey: "+map.containsKey("03"));
System.out.println("remove: "+map.remove("03"));
System.out.println("ContainsKey: "+map.containsKey("03"));
System.out.println("get: "+map.get("02"));//可以通过该方法判断是否包含某一键值,当没有时返回空
map.put(null,null);
System.out.println(map.containsKey(null));//可以存null进去
System.out.println(map);//无序的,hashcode
Collection<String> col=map.values();
System.out.println(col);
}
}
    5,Map集合的两种取出方式:
         Map集合的取出原理:将map集合转成set集合,再通过set集合的迭代器取出。  
        (1)Set<K> keySet() :将map中所有的键存入到Set集合,因为Set具备迭代器,所以可以迭代方式取出所有的键,再根据get方法获取每一个键对应的值。关系如下图
keySet取值过程.png
实现代码如下
    
    
public static void method_keySet()
{
Map<String,String> map=new HashMap<String,String>();
map.put("01","zhangsan");
map.put("04","zhouliu");
map.put("02","lisi");
map.put("03","wangwu");
//先获取Map集合的所有键的Set集合,keySet()
Set<String> keySet=map.keySet();
Iterator<String> it=keySet.iterator();
while(it.hasNext())
{
String key=it.next();
System.out.println("Key: "+key+" ,Value:"+map.get(key));
}
}
       (2)Set<Map.Entry<K,V>> entrySet():将Map集合中的映射关系存入到了Set集合中,而这个关系的数据类型就是:Map.Entry。关系如下图
entrySet方法图例.png
其实Entry也是一个接口,它是Map接口中的一个内部接口。代码结构如下
   
   
interface Map
public static interface Entry//必须是静态的
{
public abstract Object getKey();
public abstract Object getValue();
}
}
class HashMap implements Map
{
class Hash implements Map.Entry
{
public Object getKey(){return 0;}
public Object getValue(){return 0;}
}
}
  使用Set<Map.Entry<K,V>>  entrySet()方法遍历集合的使用方式如下
  
  
public static void method_entrySet()
{
Map<String,String> map=new HashMap<String,String>();
map.put("01","zhangsan");
map.put("04","zhouliu");
map.put("02","lisi");
map.put("03","wangwu");
//将Map集合中的映射关系取出,存入到Set集合中
Set<Map.Entry<String,String>> entrySet=map.entrySet();
Iterator<Map.Entry<String,String>> it=entrySet.iterator();
while(it.hasNext())
{
Map.Entry<String,String> value=it.next();
System.out.println("Key: "+value.getKey()+" || Value:"+value.getValue());
   
   
}
}
三,Map练习(HashMap和TreeMap)
1,每一个学生都有对应的归属地。(学生Student,地址String),学生属性:姓名,年龄;姓名和年龄相同的视为同一个学生。保证学生的唯一性。
分析:
      向Map中存入键值对时,必须要判断两个键是否相同,而该类用到了自定义类型的数据Student类,因此当定义Student类时要提供一个判断两个键值是否相同的方法。考虑复写hashCode和equals方法,同时实现了Comparable接口,复写compareTo方法,所以当使用HashMap时,学生类提供了比较两个对象的方法,同时,使用TreeSet时也提供compareTo方法比较两个对象。
思路:
      (1),描述学生;
      (2),定义Map容器,将学生作为键,地址作为值存入;
     (3,获取map集合中的元素。
下面代码分别使用HashMap和TreeMap实现需求
    
    
import java.util.*;
public class MapTest {
public static void main(String args[])
{
method_TreeMap();
}
//使用HashMap实现需求
public static void method_HashMap()
{
Map<Student,String> map=new HashMap<Student,String>();
map.put(new Student("zhangsan",23),"四川");
map.put(new Student("lisi",32),"辽宁");
map.put(new Student("zhangsan",23),"四川");
map.put(new Student("zhangsan",32),"北京");
show(map);
}
//使用TreeMap实现需求
public static void method_TreeMap()
{
Map<Student,String> map=new TreeMap<Student,String>(new Comp());//使用构造函数创建比较器
map.put(new Student("zhangsan",23),"四川");
map.put(new Student("lisi",32),"辽宁");
map.put(new Student("zhangsan",23),"四川");
map.put(new Student("zhangsan",32),"北京");
show(map);
Map<Student,String> map1=new TreeMap<Student,String>( );//使用元素自带的比较器
map1.put(new Student("zhangsan",23),"四川");
map1.put(new Student("lisi",32),"辽宁");
map1.put(new Student("zhangsan",23),"四川");
map1.put(new Student("zhangsan",32),"北京");
show(map);
}
//遍历Map中的元素
public static void show(Map<Student,String> map)
{
Set<Map.Entry<Student,String>> entry=map.entrySet();
Iterator<Map.Entry<Student,String>> it=entry.iterator();
while(it.hasNext())
{
Map.Entry<Student,String> me=it.next();
Student stu=me.getKey();
String add=me.getValue();
System.out.println("Student{<name>"+stu.getName()+"<age>"+stu.getAge()+"} --- Address{ "+add+" }");
}
}
}
//集合中标准的定义自定义数据类型的方法,必须实现Comparable接口,覆盖hashCode和equals方法
class Student implements Comparable<Object>
{
private String name;
private int age;
Student(String name,int age)
{
this.name=name;
this.age=age;
}
public int compareTo(Object obj)//是二叉树比较的时候会用的
{
if(!(obj instanceof Student))
throw new RuntimeException("传入的参数类型不对");
Student stu=(Student)obj;
int num=this.name.compareTo(stu.getName());
if(num==0)
return this.age-stu.getAge();
return num;
}
public int hashCode()//哈希表排序会用
{
return this.name.hashCode()+34*age;
}
public boolean equals(Object obj)//哈希表排序会用
{
if(!(obj instanceof Student))
throw new ClassCastException("类型不匹配");
Student stu=(Student)obj;
int num=this.name.compareTo(stu.getName());
if(num==0)
return (this.age-stu.getAge())==0;
return false;
}
public int getAge()
{
return age;
}
public String getName()
{
return name;
}
}
class Comp implements Comparator<Student>
{
public int compare(Student stu1,Student stu2)
{
int num=stu1.getName().compareTo(stu2.getName());
//System.out.println(stu1.getName()+","+stu1.getAge()+"----"+stu2.getName()+","+stu2.getAge());
if(num==0){
return new Integer(stu1.getAge()).compareTo(new Integer(stu2.getAge()));
}
return num;
}
}
2,输入一个字符串,输出字符串中每个字符出现的次数,输入:"abababab",输出:a(4),b(4)。
分析:从要求的输出结果可以看出,字符和次数存在一个映射关系,当发现两个数据之间存在映射关系时,应采用Map集合,因为Map集合中存放的就是映射关系。
思路:
      (1),将字符串转换成字符数组,因为要对每一个字母进行操作;
      (2),定义一个map集合,因为打印结果的字母有顺序,所以使用TreeMap集合;
      (3),遍历字符数组:将每一个字母作为键去查Map集合,如果返回为Null,将该字母和1存入到map集合中;如果返回不是null,说明该字母在map集合已经存在并有对应次数。 那么就获取该次数,并进行自增,然后将该字母和自增后的次数存入到map集合中,覆盖原来键所对应的值。
      (4),将Map集合中的数据变成指定的字符串形式返回。 
其实现的代码如下
     
     
import java.util.*;
public class TreeMapTest {
public static void main(String args[])
{
Map<Character,Integer> map=new TreeMap<Character,Integer>();
Scanner sc=new Scanner(System.in);
String str=sc.next();
int index=0,value;
Character key;
while(index<str.length()&&index!=-1)
{
value=0;
key=str.charAt(index);
if((key<='z'&&key>='a')||(key<='Z'&&key>='A'))
{
if(map.containsKey(key))
value=map.get(key);
map.put(key, value+1);
}
index++;
}
Set<Map.Entry<Character,Integer>> entry=map.entrySet();
Iterator<Map.Entry<Character,Integer>> it=entry.iterator();
while(it.hasNext())
{
Map.Entry<Character,Integer> me=it.next();
System.out.print(me.getKey()+"("+me.getValue()+"),");
}
}
}
3,Map知识扩展
需求:传智播客这个学校有两个班,一个预热版一个就业班,两个班分别有多名学生,可以输出一个班的所有学生信息,存入Map集合中的数据如下
      "yureban"  12  "lisi"        
      "yureban"   13  "zhangsan"
      "jiuyeban"  12  "wangwu"
      "jiuyeban"  13  "zhaoliu"
分析:上面存在多个映射关系,一个班有多名学生和一个学生对应一个编号,考虑两种方式来存储以上数据。第一种方式: HashMap<String,HashMap<String,String>>,先将一个班中,学生和编号映射关系存入HashMap中,再将班和学生映射关系存入集合 ;第二种方式:HashMap<String,ArrayList<Student>>,先将学生封装成类,将一个班的学生保存到一个ArrayList集合中,再将班和班名的映射关系存入HashMap中。实现的代码如下:
   
   
import java.util.*;
public class MapTest
{
public static void main(String args[])
{
method_2();
method_1();
}
public static void method_1()//不包装数据,直接建立Map集合
{
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>();
yure.put("01","zhangsan");
yure.put("02","lisi");
jiuye.put("01", "wangwu");
jiuye.put("02","zhaoliu");
czbk.put("yureban",yure);
czbk.put("jiuyeban",jiuye);
getStudentInfo(czbk,"yureban");
getStudentInfo(czbk,"jiuyeban");
}
public static void getStudentInfo(HashMap<String,HashMap<String,String>> hm,String room)//给一个学校和一个教室的名字,获取教室中的学生的信息
{
Iterator<String> it=hm.keySet().iterator();
while(it.hasNext())
{
String key=it.next();
//System.out.println(room+" "+key);
if(room.equals(key))
{
HashMap<String,String> cla=hm.get(key);
Iterator<String> itr=cla.keySet().iterator();
while(itr.hasNext())
{
String num=itr.next();
String name=cla.get(num);
System.out.println("Number:<"+num+">--Name:<"+name+">");
}
}
}
}
public static void method_2()//将学生打包成类,再将每个班的学生装到ArrayList集合中去
{
HashMap<String,ArrayList<Student>> czbk=new HashMap<String,ArrayList<Student>>();
ArrayList<Student> yure=new ArrayList<Student>();
yure.add(new Student("wangwu",12));
yure.add(new Student("lisi",23));
yure.add(new Student("liuliu",44));
ArrayList<Student> jiuye=new ArrayList<Student>();
jiuye.add(new Student("wangwuj",12));
jiuye.add(new Student("lisij",23));
jiuye.add(new Student("liuliuj",44));
czbk.put("yure",yure);
czbk.put("jiuye",jiuye);
getInfo(czbk,"yure");
getInfo(czbk,"jiuye");
}
public static void getInfo(HashMap<String,ArrayList<Student>> hm,String room)//给一个学校和一个教室的名字,获取教室中的学生的信息
{
Iterator<String> it=hm.keySet().iterator();
while(it.hasNext())
{
String key=it.next();
if(key.equals(room))
{
ArrayList<Student> arr=hm.get(key);
Iterator<Student> itr=arr.iterator();
while(itr.hasNext())
{
Student stu=itr.next();
System.out.println("Number:"+stu.getAge()+" || Name: "+stu.getName());
}
}
}
}
}
class Student
{
private String name;
private int age;
Student(String name,int age)
{
this.name=name;
this.age=age;
}
public int getAge()
{
return this.age;
}
public String getName()
{
return this.name;
}
}
四,Collections和Arrays
     Collections和Arrays都是工具类,内部都是一些静态方法,Collections用来对集合进行操作,如对集合进行排序,随机置换等等。Arrays用来对数组进行操作,如排序,将集合转换成数组等等。
1,Collections常用方法
binarySearch(List<? extends Comparable<? super T>> list, T key):二分查找
        fill(List<? super T> list, T obj) :将列表中的值全部替换成obj
max(Collection<? extends T> coll):获取集合中的最大值
reverse(List<?> list) :对元素进行反转
replaceAll(List<T> list, T oldVal, T newVal) :将列表中值为oldval的元素的值替换成newVal
Comparator<T>  reverseOrder() :返回一个逆转自然顺序排序的比较器
Comparator<T>  reverseOrder(Comparator<T> cmp) :返回一个比较器,它强行逆转指定比较器的顺序。
shuffle(List<?> list):随机置换集合内容
sort(List<T> list):对集合排序
sort(List<T> list, Comparator<? super T> c):按照指定的规则给集合排序 
swap(List<?> list, int i, int j) :交换列表中i和j位置的值
synchronizedCollection(Collection<T> c):给一个不同步的集合,返回一个同步的集合
排序(sort),获取集合最大值(max)的使用
   
   
public static void Sort_Max_Demo()
{
List<String> list=new ArrayList<String>();
list.add("abcd");
list.add("adjk");
list.add("kkkkk");
list.add("z");
list.add("z");
sop(list);//输出list
Collections.sort(list);//使用默认方法排序
String max=Collections.max(list);
sop("Max="+max);
Collections.shuffle(list);//随机交换位置,随机排放,扑克牌就可以这样玩
sop(list);
Collections.sort(list,new Comparator<String>()//通过创建比较器排序,按照字符串的长度排序
{
public int compare(String s1,String s2)
{
int num=s1.length()-s2.length();
if(num==0)
return s1.compareTo(s2);
return num;
}
});
sop(list);
}
二分查找(binarySearch)的使用
   
   
public static void BinarySearchDemo()//二分查找
{
List<String> list=new ArrayList<String>();
list.add("z");
list.add("abcd");
list.add("kkkkk");
list.add("adjk");
list.add("z");
Collections.sort(list);
int index1=Collections.binarySearch(list,"z");//当不存在时返回(-(插入点+1))的值,如果将该值插入到插入点能保证list任然是有序的
sop(index1);
int index2=Collections.binarySearch(list,"accd");
sop(index2);
list.add(-index2-1,"accd");
sop(list);
Collections.sort(list);
sop(list);
}
2,Arrays常用方法
       2.1  static <T> List<T>  asList(T... a) : 将数组转变成集合,但是转变之后所得的集合不能进行增删操作,因为数组的长度是固定的,如果进行增删操作会出现不支持操作异常,可以使用contains,get,indexOf,subList()等操作。
      PS:将数组转变成集合是因为集合操作更方便更简单。
      补充:Collection接口中提供了toArray方法将集合转变成为数组,目的是限制对数据的操作,防止用户进行增删等操作。       
      2.2  static String toString(Object[] a):将数组转换成为字符串。
五 ,知识补充
1,增强for循环 
    格式:for(数据类型    变量:被遍历的集合(Collection)或者数组),例如
   
   
ArrayList<String> arr=new ArrayList<String>();
arr.add("dannd");
arr.add("dwfnk");
arr.add("Ankndk");
arr.add("dad");
System.out.print("{");
for(String s:arr)//简化书写
{
System.out.print(s+",");
}
System.out.println("}");
2,可变参数
    JDK1.5以后出现的,可变参数其实就是上数组参数的简写形式,不用每一次都手动建立数组对象,只要将要操作的元素作为参数传递即可,隐式将这些参数封装成数组。  
    格式:例如,show(int  ...arr),可变参数一定要定义在参数列表的最后面
3,静态导入
    当一个类里面的成员都是静态的时,可以选择静态导入的方式,更节省代码,但对于重名的成员,必须指定具体使用的是哪个类中的,如toString方法。
    格式:例如,import   static   java.util.Arrays.*,这个导入的是该类里面的全部静态成员。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
电子图书资源服务系统是一款基于 Java Swing 的 C-S 应用,旨在提供电子图书资源一站式服务,可从系统提供的图书资源中直接检索资源并行下载。.zip优质项目,资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松copy复刻,拿到资料包后可轻松复现出一样的项目。 本人系统开发经验充足,有任何使用问题欢迎随时与我联系,我会及时为你解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(若有),项目具体内容可查看下方的资源详情。 【附带帮助】: 若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习步。 【本人专注计算机领域】: 有任何使用问题欢迎随时与我联系,我会及时解答,第一时间为你提供帮助,CSDN博客端可私信,为你解惑,欢迎交流。 【适合场景】: 相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可以基于此项目行扩展来开发出更多功能 【无积分此资源可联系获取】 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。积分/付费仅作为资源整理辛苦费用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值