前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >12:集合map、工具类

12:集合map、工具类

作者头像
六月的雨
发布2018-05-14 10:38:36
9520
发布2018-05-14 10:38:36
举报
文章被收录于专栏:Android开发指南

一、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)     --->   返回一个比较器,强行逆转了指定比较器的顺序

演示方法:

代码语言:javascript
复制
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

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

代码语言:javascript
复制
//	 Collections.sort(list); 自然排序[abc, bbce, cbcef, dbcefg, ebcefgh]//	 mySort(list);//	 mySort(list,new ComparatorByLength());  Collections.sort(list,new ComparatorByLength()); 指定排序(简单)  System.out.println(list); }
代码语言:javascript
复制
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())的排序原理

代码语言:javascript
复制
 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)的排序原理

代码语言:javascript
复制
 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);
代码语言:javascript
复制
//	 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); }

逆序:

代码语言:javascript
复制
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);  }

替换

代码语言:javascript
复制
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"); 这是俩步,一样

新的没有枚举,转成老的

代码语言:javascript
复制
  Collections.shuffle(list); (洗牌)//	 Collections.fill(list, "cc");  System.out.println(list); }

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

加锁原理

代码语言:javascript
复制
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:操作集合的工具

代码语言:javascript
复制
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(", ");        } }
代码语言:javascript
复制
 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; }

现在:

代码语言:javascript
复制
  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方法。

   *

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

代码语言:javascript
复制
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"的字符串元素,请问下面的实现正确么?如有问题,

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

代码语言:javascript
复制
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); }} 
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015-10-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档