• 从一道例题谈Arrays.toString()与其他String的转换方法


      阅读该篇文章前,请大家事先阅读一下:   java.toString(),(String),String.valueOf的区别

      

      有了上述基础后,我接下来谈谈从一道题目中获得的些许收获。

      今天在做题是发现了非常重要的一点。题目来源:http://www.lintcode.com/en/problem/anagrams/

      我们先来看一下两种不同的解法:

    解法一:

    /*
     use int[26] assuming it's all lowercase letters
     count each string char in a letter array int[], convert the array into string.
     HashMap carray string as key, and actualy string as value
     outupt all values
    */
    public class Solution {
        public List<String> anagrams(String[] strs) {   
            List<String> rst = new ArrayList<String>();
            
            if (strs == null || strs.length == 0) {
                return rst;
            }
            
            HashMap<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();
            
            for (int i = 0; i < strs.length; i++) {
                int[] arr = new int[26];
                for (int j = 0; j < strs[i].length(); j++) {
                    arr[strs[i].charAt(j) - 'a'] += 1;
                }
                
                String arrString =  Arrays.toString(arr);
                //    不能使用String.valueOf(arr);
                if (!map.containsKey(arrString)) {
                    map.put(arrString, new ArrayList<String>());
                }
                map.get(arrString).add(strs[i]);
            }
            
            //Output
            for (Map.Entry<String, ArrayList<String>> entry : map.entrySet()) {
                if (entry.getValue().size() >= 2) 
                    rst.addAll(entry.getValue());
            }
            
            return rst;
        }
    }

    解法二:

    /*
        Feels like put into a hashmap of each string's sorted version. <String, ArrayList<Sting>>
        compare each string. If match, add into it.
        reurn all that has >= 2 items
    */
    public class Solution {
        public List<String> anagrams(String[] strs) {
                List<String> rst = new ArrayList<String>();
                
                if (strs == null || strs.length == 0) {
                    return rst;
                }
                
                HashMap<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();
                
                for (int i = 0; i < strs.length; i++) {
                    char[] arr = strs[i].toCharArray(); 
                    Arrays.sort(arr);
                    String s = String.valueOf(arr);
                    //    不能使用arr.toString(), 但是可以用Arrays.toString(arr);
                    if (!map.containsKey(s)) {
                        ArrayList<String> list = new ArrayList<String>();
                        map.put(s, list);
                    }
                    map.get(s).add(strs[i]);
                } 
                //check instance occurs >= 2
                for (Map.Entry<String, ArrayList<String>> entry : map.entrySet()) {
                    if (entry.getValue().size() >= 2) {
                        rst.addAll(entry.getValue());
                    }
                }
                return rst;
        }
    }

         这边我们不讨论该题目的具体解法(解法思路我已经写在了注释中,若还有可以去我的GitHub下载,对应的程序:LintCode-Anagrams.java)。

      我们可以发现,在第一种解法中,我定义了一个int[]用来存储每个字符出现的个数。当我想要将它转换为String时,我第一次使用了String.valueOf(arr)这个方法

      但是这是错误的。根据上面的总结我们可以得知String.valueOf()这个方法实际上在toString()方法的基础上实现的。故我们来看看int[],我们发现它并没有重写toString方法,

    故默认情况下,它所返回的应该是该整形数组的内存地址。所以在这里,我们不管是调用String.valueOf(arr)还是arr.toString()方法结果都是一样的,并且都是错误的,它并不能

    够实现将整形数组转换为字符串。但是!Arrays.toString()不一样,Arrays是一个工具类。在java中类似的Collections,Arrays等是工具类,目的是为了方便开发人员们对其进行操作。

    API中Arrays的描述是:

    • This class contains various methods for manipulating arrays (such as sorting and searching). This class also contains a static factory that allows arrays to be viewed as lists. 
    该类中的所有方法为静态的,可以直接调用操作。所以,我们来看一下Arrays.toString(int[])方法的描述:
    • Returns a string representation of the contents of the specified array. The string representation consists of a list of the array's elements, enclosed in square brackets ("[]"). Adjacent elements are separated by the characters ", " (a comma followed by a space). Elements are converted to strings as by String.valueOf(int). Returns "null" if a is null

    并且我们可以发现该方法还对int[], short[], double[], char[]等这些数据都实现了重写。故我们可以放心地调用该方法为我们实现将一个数组转换为字符串。

    注:Arrays作为一个工具类还包含其他许多好用的方法,如:sort(),fill()...等

      在解法二中,我们定义了一个char[], 用来存储经过Arrays.sort()排序的字符数组。将它转换为字符串的时候,我们看到了它使用了String.valueOf(arr)这个方法。这时候我们不禁纳闷, 

    为什么第种解法中就能够使用该方法呢?原因在于,String.valueOf()方法实现了对char[]类型的重写,查阅API我们可以发现,存在方法:

      public static String valueOf(char[] data)   并且该方法的描述是:

    • Returns the string representation of the char array argument. The contents of the character array are copied; subsequent modification of the character array does not affect the newly created string.

    由此可以我们可以用过该方法将字符串数组转换成字符串,但是并不能够使用arr.toString()方法将其转换为字符串。因为char[]并没有重写该方法(若要实现目的,可以自己人为地重写该方法)。同时我们可以

    发现String.valueOf()方法仅实现了valueOf(int), valueOf(float)...等这些方法,并没有对int[], float[]这些类型进行实现。这个说明了在第一个解法中,我们是不能够调用String.value(arr)来实现我们的目的的。

      至此,对于该问题的分析已经结束了。总结如下:

    1. 将数组转换为一个字符串时最好利用Java提供的Arrays工具类来实现,该类中封装了许多高效的代码。多使用它们可以为开发工作带来不少便利,亦能够提高开发效率。
    2. 要熟悉Java的API,如String类中并没有实现valueOf(int [])方法,盲目调用并不能够达到我们想要的目的。
  • 相关阅读:
    jdbc框架 commons-dbutils的使用
    SpringBoot整合Quartz和H2的例子
    Microsoft VS 2008 过期解决方法
    数据库事务的隔离级别
    angularJS中ng-if的用法
    angularJS中ng-change的用法
    Hello,Akka
    Yum常用命令及Yum中文手册
    最大堆的插入/删除/调整/排序操作(图解+程序)(JAVA)
    别人要访问我的电脑上部署的tomcat,必须关闭防火墙吗?
  • 原文地址:https://www.cnblogs.com/cherryljr/p/7081585.html
Copyright © 2020-2023  润新知