12:集合map、工具类

一、map集合 Map:一次添加一对元素。Collection 一次添加一个元素。 Map也称为双列集合,Collection集合称为单列集合。 其实map集合中存储的就是键值对(结婚证书), map集合中必须保证键的唯一性。 方法简介: 1、添加 put(K key, V value) 以键值对的形式往里存 putAll(Map<? extends K,? extends V> m) 把一个map里的内容作为值存入进map中。 2、删除 clear() 清空集合 remove(Object key) 清楚其中的一条 3、判断 containsValue(Object value) 判断map中是否包含某个值 containsKey(Object key) 判断map中是否包含某个值 isEmpty()判空 4、获取 get(Object key) 根据key获取值 size() 获取map集合的大小

  • values() 获取map中所有的值,并存放在Collection中        
  • entrySet()    Set<Map.Entry<K,V>>返回键值对关系,并存放在Set集合中
  • keySet() 获取map集合中所有的键并存放在Set集合中

: a、也可以通过get()方法的返回值来判断一个键是否存在,通过返回null来判断。 b、其中put方法:如果出现添加相同的键,那么后添加的值会覆盖原有键对应的值,并且该方法返回被覆盖的值即原值。 class MapDemo { public static void main(String[] args) { Map<String,String> map = new HashMap<String,String>(); //添加元素,添加元素,如果出现添加时,相同的键,那么后添加的值会覆盖原有键对应值,并返回以前的值,以前没值就放回null System.out.println("put:"+map.put("01","zhangsan1")); System.out.println("put:"+map.put("01","wnagwu")); map.put("02","zhangsan2"); map.put("03","zhangsan3"); System.out.println("containsKey:"+map.containsKey("022")); 判断 //System.out.println("remove:"+map.remove("02"));删除 System.out.println("get:"+map.get("023")); map.put("04",null); System.out.println("get:"+map.get("04")); //可以通过get方法的返回值来判断一个键是否存在。通过返回null来判断。 //获取map集合中所有的值。 Collection<String> coll = map.values(); System.out.println(coll); System.out.println(map); } 两种获取集合元素的方法: 1、keySet()方法获取元素 原理:将Map集合中的所有键存入到Set集合中,因为Set集合具备迭代器,所以可以用迭代方式取出所有的键,再根据get方法获取每一个键对应的值。简单说就是:Map集合---->Set集合 ---->迭代器取出

class MapDemo2 { public static void main(String[] args) { Map<String,String> map = new HashMap<String,String>(); // Map<Integer,String> map = new HashMap<Integer,String>(); // map.put(8,"zhaoliu"); map.put("02","zhangsan2"); map.put("03","zhangsan3"); map.put("01","zhangsan1"); map.put("04","zhangsan4"); //先获取map集合的所有键的Set集合,keySet(); Set<String> keySet (故意起的,有意义)= map.keySet(); //有了Set集合。就可以获取其迭代器。 Iterator<String> it = keySet.iterator(); while(it.hasNext()) { String key = it.next(); //有了键可以通过map集合的get方法获取其对应的值。 String value = map.get(key); System.out.println("key:"+key+",value:"+value); } } } 2、entrySet()方法获取元素: 原理:将Map集合中的映射关系存入到了Set集合中,而这个映射关系的数据类型是Map.Entry(结婚证),在通过迭代器将映射关系存入到Map.Entry集合中,并通过其中的getKey()和getValue()放取出键值。

class MapDemo2 { public static void main(String[] args) { Map<String,String> map = new HashMap<String,String>(); map.put("02","zhangsan2"); map.put("03","zhangsan3"); map.put("01","zhangsan1"); map.put("04","zhangsan4"); //将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> me = it.next(); String key = me.getKey(); String value = me.getValue(); System.out.println(key+":"+value); } } } 补充:关于<Map.Entry<String,String>> Map是一个接口,其实,Entry也是一个接口,它是Map的子接口中的一个内部接口,就相当于是类中有内部类一样。为何要定义在其内部呢? 原因: a.Map集合中存的是映射关系这样的两个数据,是先有Map这个集合,才可有映射关系的存在,而且此类关系是集合的内部事务。 b.并且这个映射关系可以直接访问Map集合中的内部成员,所以定义在内部。

3、只获取姓名,可以用下面得的,当然可以用上面的:

Map常用的子类:  |--Hashtable :内部结构是哈希表,是同步的。不允许null作为键,null作为值。 //最先出来   |--Properties:用来存储键值对型的配置文件的信息,可以和IO技术相结合。  |--HashMap : 内部结构是哈希表,不是同步的。允许null作为键,null作为值。  |--TreeMap : 内部结构是二叉树,不是同步的。可以对Map集合中的键进行排序。 :Set底层就是使用了Map集合。  演示1: public class HashMapDemo { public static void main(String[] args) { /* * 将学生对象和学生的归属地通过键与值存储到map集合中 */ HashMap<Student,String> hm = new HashMap<Student,String>(); hm.put(new Student("lisi",38),"北京"); hm.put(new Student("zhaoliu",24),"上海"); hm.put(new Student("xiaoqiang",31),"沈阳"); hm.put(new Student("wangcai",28),"大连"); hm.put(new Student("zhaoliu",24),"铁岭"); //覆盖了,需要在person类中重写hashcode和equals方法 // Set<Student> keySet = hm.keySet();// Iterator<Student> it = keySet.iterator(); 简写: Iterator<Student> it = hm.keySet().iterator(); while(it.hasNext()){ Student key = it.next(); String value = hm.get(key); System.out.println(key.getName()+":"+key.getAge()+"---"+value); } } }   演示2:排序 class ComparatorByName implements Comparator<Perosn> { public int compare(Person o1,Person o2){ int temp=o1.getName().comparaTo.(o2.getName); return temp==0? o1.getAge-o2.getAge:temp; } } public class TreeMapDemo { public static void main(String[] args) { TreeMap<Student,String> tm = new TreeMap<Student,String>(new ComparatorByName()); tm.put(new Student("lisi",38),"北京"); tm.put(new Student("zhaoliu",24),"上海"); tm.put(new Student("xiaoqiang",31),"沈阳"); tm.put(new Student("wangcai",28),"大连"); tm.put(new Student("zhaoliu",24),"铁岭"); Iterator<Map.Entry<Student, String>> it = tm.entrySet().iterator(); while(it.hasNext()){ Map.Entry<Student,String> me = it.next(); Student key = me.getKey(); String value = me.getValue(); System.out.println(key.getName()+":"+key.getAge()+"---"+value); } } } 演示3:LinkedHashMap(有序),和LinkedHashSet使用一样 public class LinkedHashMapDemo { public static void main(String[] args) { HashMap<Integer,String> hm = new LinkedHashMap<Integer,String>(); hm.put(7, "zhouqi"); hm.put(3, "zhangsan"); hm.put(1, "qianyi"); hm.put(5, "wangwu"); Iterator<Map.Entry<Integer,String>> it = hm.entrySet().iterator(); while(it.hasNext()){ Map.Entry<Integer,String> me = it.next(); Integer key = me.getKey(); String value = me.getValue(); System.out.println(key+":"+value); } }}  练习: 1  * "fdgavcbsacdfs" 获取该字符串中,每一个字母出现的次数。  * 要求打印结果是:a(2)b(1)...;  * 思路:  * 对于结果的分析发现,字母和次数之间存在着映射的关系。而且这种关系很多。  * 很多就需要存储,能存储映射关系的容器有数组和Map集合。  * 关系一方式有序编号吗?没有!  * 那就是使用Map集合。 又发现可以保证唯一性的一方具备着顺序如 a b c ...  * 所以可以使用TreeMap集合。  *  * 这个集合最终应该存储的是字母和次数的对应关系。  *  * 1,因为操作的是字符串中的字母,所以先将字符串变成字符数组。  * 2,遍历字符数组,用每一个字母作为键去查Map集合这个表。  * 如果该字母键不存在,就将该字母作为键 1作为值存储到map集合中。  * 如果该字母键存在,就将该字母键对应值取出并+1,在将该字母和+1后的值存储到map集合中,  * 键相同值会覆盖。这样就记录住了该字母的次数.  * 3,遍历结束,map集合就记录所有字母的出现的次数。 class MapTest1 { public static void main(String[] args) { String s= charCount("ak+abAf1c,dCkaAbc-defa"); //返回一个新的字符串结果 System.out.println(s); } public static String charCount(String str) { //将字符串变成字符数组 char[] chs = str.toCharArray(); //定义map集合表。 Map<Character,Integer> tm = new TreeMap<Character,Integer>(); //因为只存取,不需要TreeMap的特有方法,将他提升为map就可以 for(int x=0; x<chs.length; x++) { if(!(chs[x]>='a' && chs[x]<='z' || chs[x]>='A' && chs[x]<='Z')) continue; //将数组中的字母作为键去查map表。 Integer value = tm.get(chs[x]); //直接作为键去查表 int count = 1; //计数器 //判断值是否为null. if(value!=null){ count = value+1; //用个变量记录下 }// count++; map.put(chs[i], count); /* //这种比较麻烦 if(value==null){ map.put(chs[i], 1); }else{ map.put(chs[i], value+1); //直接往集合中存储字符和数字,为什么可以,因为自动装箱 } */ } } //System.out.println(tm); // 上边已经解决,转换它的那种结果a(2)b(1). return mapToString(map); } private static String mapToString(Map<Character, Integer> map) { StringBuilder sb = new StringBuilder(); Iterator<Character> it = map.keySet().iterator(); while(it.hasNext()){ Character key = it.next(); Integer value = map.get(key); sb.append(key+"("+value+")"); } return sb.toString(); }} 练习2: map什么时候用, Map在有映射关系时,可以优先考虑。在查表法中的应用较为多见。 public class MapTest2 { public static void main(String[] args) { String week = getWeek(1); //查表 System.out.println(week); System.out.println(getWeekByMap(week)); } public static String getWeekByMap(String week){ Map<String,String> map = new HashMap<String,String>(); map.put("星期一","Mon"); map.put("星期二","Tus"); map.put("星期三","Wes"); map.put("星期日","Sun"); map.put("星期天","Sun"); return map.get(week); } public static String getWeek(int week){ if(week<1 || week>7) throw new RuntimeException("没有对应的星期,请您重新输入"); String[] weeks = {"","星期一","星期二"}; return weeks[week]; }}

第二:Collections工具类

Collections和Collection有什么区别?

  • Collection是集合框架中的一个顶层接口,它里面定义了单列集合的共性方法。它有两个常用的子接口

List:对元素都有定义索引。有序的。可以重复元素。 Set:不可以重复元素。无序。

  • Collections是集合框架中的一个工具类。该类中的方法都是静态的

提供的方法中有可以对list集合进行排序,二分查找等方法。 通常常用的集合都是线程不安全的。因为要提高效率。 如果多线程操作这些集合时,可以通过该工具类中的同步方法,将线程不安全的集合,转换成安全的

工具类的Collections和Arrays中的方法全是静态的,下面主要总结几个比较重要的方法。

一、Collections工具类:在Collections工具类中很多方法是用于对集合进行操作的,如比较,查找,随机排序等等

1、查找:

T max(Collection<? extends T> coll)    --->    根据集合的自然顺序,获取coll集合中的最大元素

T max(Collection<? extends T> coll,Comparator<? super T> comp)    --->   根据指定比较器comp的顺序,获取coll集合中的最大元素

int binarySearch(Lsit<? extends Comparable<? super T>> list,Tkey)    --->   二分法搜索list集合中的指定对象

2、替换:

void fill(List<? super T> list, T obj)        --->   将list集合中的全部元素替换成指定对象obj

boolean replaceAll(List<T> lsit,T oldVal,T newVal)     --->   使用newVal替换list集合中的oldVal值

3、排序:

      void shuffle(List<?> list)     --->   使用默认随机源对list集合中的元素进行随机排序

      void sort(Lsit<T> list)          --->   根据自然顺序对list集合中的元素进行排序

      void sort(List<T> lsit,Comparator<? super T> c)     --->   根据指定比较器c的排序方式对list集合进行排序

4、反转

      reverse(List<?> list)     --->   反转list集合中元素的顺序

      Comparator reverseOrder()     --->   返回一个比较器,强行逆转了实现Comparable接口的对象的自然顺序

      Comparator reverseOrder(Comparator<T> cmp)     --->   返回一个比较器,强行逆转了指定比较器的顺序

演示方法:

public class CollectionsDemo { public static void main(String[] args) {  demo_1(); }public static void demo_1(){ //排序  List<String> list = new ArrayList<String>();   list.add("abcde");  list.add("cba");  list.add("aa");  list.add("zzz");  list.add("cba");  list.add("nbaa");  System.out.println(list);//输出[abc, cbcef, ebcefgh, dbcefg, bbce],取出的时候用迭代器

对list集合重复元素进行指定顺序的排序。 有重复元素而且要指定顺序排序,就需要Collections

自然排序, 指定排序俩种比较方式,凡事设计比较的无外乎就是这俩种

//	 Collections.sort(list); 自然排序[abc, bbce, cbcef, dbcefg, ebcefgh]//	 mySort(list);//	 mySort(list,new ComparatorByLength());  Collections.sort(list,new ComparatorByLength()); 指定排序(简单)  System.out.println(list); }
class ComparatorByLength implements Comparator<String> {//要新建这个类,写成内部类不行	@Override	public int compare(String o1, String o2) {		int temp = o1.length() - o2.length();		return temp == 0 ? o1.compareTo(o2) : temp;	}}

源码: Collections.sort(list,new ComparatorByLength())的排序原理

 public static <T> void mySort(List<T> list,Comparator<? super T> comp){  for (int i = 0; i < list.size()-1; i++) {   for (int j = i+1; j < list.size(); j++) {    if(comp.compare(list.get(i), list.get(j))>0){//	 T temp = list.get(i);//	 list.set(i, list.get(j));//	 list.set(j, temp);     Collections.swap(list, i, j);   }    }  }

源码: Collections.sort(list)的排序原理

 public static <T extends Comparable<? super T>> void mySort(List<T> list){ 长度比较//<T extends Comparable<? super T>>需要限定,继承Comparable的才能比较,然后superT,T的子类和T都可以  for (int i = 0; i < list.size()-1; i++) {   for (int j = i+1; j < list.size(); j++) {    if(list.get(i).compareTo(list.get(j))>0){       Collections.swap(list, i, j); public static void demo_2(){二分查找、最值  List<String> list = new ArrayList<String>();  list.add("abcde");  list.add("cba");  list.add("aa");  list.add("zzz");  list.add("cba");  list.add("nbaa");//	 Collections.sort(list); 没顺序不能折半,先排序  System.out.println(list);
//	 int index = Collections.binarySearch(list, "cba");//	 System.out.println("index="+index);  //获取最大值。  String max = Collections.max(list,new ComparatorByLength());//list,new ComparatorByLength()自然排序/排序器(名字长度)最值 demo_1  System.out.println("max="+max); }

逆序:

public static void demo_3() {  /*用比较器逆序  TreeSet<String> ts = new TreeSet<String>(new Comparator<String>(){   public int compare(String o1, String o2) {    int temp = o2.compareTo(o1);    return temp;   }     });  */  TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder(new ComparatorByLength()));	   ts.add("abc");  ts.add("hahaha");  ts.add("zzz");  ts.add("aa");  ts.add("cba");  System.out.println(ts);  }

替换

public static void demo_4() {  List<String> list = new ArrayList<String>();   list.add("abcde");  list.add("cba");  list.add("zhangsan");  list.add("zhaoliu");  list.add("xiaoqiang");

  System.out.println(list);

// Collections.replaceAll(list, "cba", "nba"); // set(indexOf("cba"),"nba"); 这是俩步,一样

新的没有枚举,转成老的

  Collections.shuffle(list); (洗牌)//	 Collections.fill(list, "cc");  System.out.println(list); }

将非同步集合转成同步集合

加锁原理

List list = new ArrayList();//非同步的。list = MyCollections.synList(list);//返回一个同步的list. 给非同步的集合加锁。class MyCollections{ public static  List synList(List list){  return new MyList(list); } private class MyList implements List{ private List list; private static final Object lock = new Object(); MyList(List list){  this.list = list; }在加元素的同时,删除元素 public boolean add(Object obj){  synchronized(lock)  {   return list.add(obj);  } } public boolean remove(Object obj){  synchronized(lock)  {   return list.remove(obj);  } }} 

 第三:Arrays工具类

Arrays:操作数组的工具

Collections:操作集合的工具

public class ArraysDemo {tic void main(String[] args) {   /*   * Arrays:集合框架的工具类。里面的方法都是静态的。   *   *///	 int[] arr = {3,1,5,6,3,6};//	 System.out.println(Arrays.toString(arr)); 输出为[3,1,5,6,3,6] }//toString的经典实现。 public static String myToString(int[] a){  int iMax = a.length - 1;  if (iMax == -1)             return "[]";        StringBuilder b = new StringBuilder();        b.append('[');        for (int i = 0;  ; i++) {//中间省略条件判断,提高了效率。            b.append(a[i]);     if (i == iMax)      return b.append(']').toString();           b.append(", ");        } }
 public static void demo_1() {  /*   * 重点:List asList(数组)将数组转成集合。   *   * 好处:其实可以使用集合的方法操作数组中的元素。   * 注意:数组的长度是固定的,所以对于集合的增删方法是不可以使用的    * 否则会发生UnsupportedOperationException   *      */  String[] arr = {"abc","haha","xixi"}; 以前:比较麻烦  boolean b = myContains(arr, "xixi");  System.out.println("contains:"+b); public static boolean myContains(String[] arr,String key){  for (int i = 0; i < arr.length; i++) {   if(arr[i].equals(key))    return true;  }  return false; }

现在:

  List<String> list = Arrays.asList(arr);  boolean b1 = list.contains("xixi");  System.out.println("list contaisn:="+b1);//	 list.add("hiahia");//UnsupportedOperationException   System.out.println(list); }  public static void demo_2() {  /*   * 如果数组中的元素是对象,那么转成集合时,直接将数组中的元素作为集合中的元素进行集合存储。    *   * 如果数组中的元素是基本类型数值,那么会将该数组作为集合中的元素进行存储。   *   */  int(写成integer是对象)[] arr = {31,11,51,61};  List<int[]> list = Arrays.asList(arr);  System.out.println(list); 这里的集合中只有一个元素 }

   * 集合转成数组

   *

   * 使用的就是Collection接口中的toArray方法。

   *

   * 集合转成数组:可以对集合中的元素操作的方法进行限定。不允许对其进行增删。 变成数组就不能增删了,只能查阅

public class ToArray { public static void main(String[] args) {  List<String> list = new ArrayList<String>();  list.add("abc1");  list.add("abc2");  list.add("abc3");  /*   * toArray方法需要传入一个指定类型的数组。   * 长度该如何定义呢?   * 如果长度小于集合的size,那么该方法会创建一个同类型并和集合相同size的数组。   * 如果长度大于集合的size,那么该方法就会使用指定的数组,存储集合中的元素,其他位置默认为null。    *   * 所以建议,最后长度就指定为,集合的size。   */  String[] arr = list.toArray(new String[list.size()]); //字符串数组  System.out.println(Arrays.toString(arr)); }}

一个ArrayList对象alist中存有若干个字符串元素,现欲遍历该ArrayList对象,

删除其中所有值为"abc"的字符串元素,请问下面的实现正确么?如有问题,

会出现什么问题?如何更正

int size = alist.size();for(int i = 0; i < size; i++) { if("abc".equals(alist.get(i))) {   alist.remove(i); }}*/public class Test13 { public static void main(String[] args) {  ArrayList<String> al = new ArrayList<String>();   al.add("haha");  al.add("abc");  al.add("abc");  al.add("abc");//	 int size = al.size();  for(int x=0; x<al.size(); x++){   if("abc".equals(al.get(x))){    al.remove(x);    x--;   }  }  System.out.println(al); }} 

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java帮帮-微信公众号-技术文章全总结

16(02)总结泛型

2:泛型(掌握) (1)泛型概述 是一种把明确类型的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型。 (2)格式: <数据类型> 注意:该数...

3407
来自专栏IT可乐

Java 集合详解

一、集合的由来   通常,我们的程序需要根据程序运行时才知道创建多少个对象。但若非程序运行,程序开发阶段,我们根本不知道到底需要多少个数量的对象,甚至不知道它的...

2849
来自专栏海说

16、Collection接口及其子接口Set和List(常用类LinkedList,ArrayList,Vector和Stack)

16、Collection接口 Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(...

2260
来自专栏陈树义

Java集合常见面试题集锦

1、介绍Collection框架的结构 集合是Java中的一个非常重要的一个知识点,主要分为List、Set、Map、Queue三大数据结构。它们在Java中的...

4215
来自专栏Java大联盟

Java面试手册:集合框架

2453
来自专栏一“技”之长

Swift讲解专题五——集合类型 原

        Swift中提供了3种集合类型,Array数据类型,Set集合类型,Dictionary字典类型。Array用于存放一组有序的数据,数据角标从0...

823
来自专栏章鱼的慢慢技术路

顺序表示的线性表——顺序表

2264
来自专栏黑泽君的专栏

java基础学习_集合类02_List的子类、泛型、增强for循环、静态导入、可变参数_day16总结

============================================================================= ==...

691
来自专栏Python爱好者

Java基础笔记18

1017
来自专栏AILearning

Map集合

Collection |--List:元素是有序的,元素可以重复,因为该集合体系有索引 |--ArrayList:底层的数据结构使用的是数据结构。特点:查询...

2386

扫码关注云+社区

领取腾讯云代金券