zoukankan      html  css  js  c++  java
  • 编写高质量代码:改善Java程序的151个建议 --[65~78]

    编写高质量代码:改善Java程序的151个建议 --[65~78]

    原始类型数组不能作为asList的输入参数,否则会引起程序逻辑混乱。
    public class Client65 {
        public static void main(String[] args) {
            int data [] = {1,2,3,4,5};
            List list= Arrays.asList(data);
            System.out.println("元素类型是:"+list.get(0).getClass());
            System.out.println("前后是否相等:"+data.equals(list.get(0)));    
        }
    }
    

    输出的结果是: 元素类型是:class [I 前后是否相等:true
    如果要转换,建议转换为对应的包装类,再使用 List list= Arrays.asList(data)来转换

    asList方法产生的List的对象不可更改

    添加修改Arrays.asList后的list数据会产生如下错误

    在修改动作上,LinkedList比ArrayList慢很多,特别是要进行大量的修改时,两者完全不在一个数量级上。
    LinkedList删除和插入效率高;ArrayList修改元素效率高。

    判断集合是否相等时只须关注元素是否相等即可
    import java.util.ArrayList;
    import java.util.Vector;
    
    public class Client69 {
        public static void main(String[] args) {
            ArrayList<String> strs = new ArrayList<String>();
            strs.add("A");
    
            Vector<String> strs2 = new Vector<String>();
            strs2.add("A");
    
            System.out.println(strs.equals(strs2));
        }
    }
    

    AbstractList看下源码:

    public boolean equals(Object o) {
                if (o == this)
                    return true;
                //是否是列表,注意这里:只要实现List接口即可
                if (!(o instanceof List))
                    return false;
                //通过迭代器访问List的所有元素
                ListIterator<E> e1 = listIterator();
                ListIterator e2 = ((List) o).listIterator();
                //遍历两个List的元素
                while (e1.hasNext() && e2.hasNext()) {
                    E o1 = e1.next();
                    Object o2 = e2.next();
                    //只要存在着不相等就退出
                    if (!(o1==null ? o2==null : o1.equals(o2)))
                        return false;
                }
                //长度是否也相等
                return !(e1.hasNext() || e2.hasNext());
            }
    
    子列表只是原列表的一个视图

    SubList类也是AbstractList的子类,其所有的get、set、add、remove等都是在原始列表上的操作,它自身并没有生成一个新的数组或是链表,也就是子列表只是原列表的一个视图(View)而已。所有的修改动作都映射到了原列表上。

    实现了compareTo方法就应该覆写equals方法,确保两者同步

    indexOf依赖equals方法查找,binarySearch则依赖compareTo方法查找;
    equals是判断元素是否相等,compareTo是判断元素在排序中的位置是否相同。
    既然一个决定排序位置,一个是决定相等,那我们就应该保证当排序相同时,其equals也相同,否则就会产生逻辑混乱。

    集合运算时使用最优雅方式

    并集:

    public static void main(String[] args) {
            List<String> list1 = new ArrayList<String>();
            list1.add("A");
            list1.add("B");
            List<String> list2 = new ArrayList<String>();
            list2.add("C");
            // 并集
            list1.addAll(list2);
        }
    

    交集:

    //交集
    list1.retainAll(list2);
    

    差集:

    //差集
    list1.removeAll(list2);
    

    无重复的并集:

     	   //删除在list1中出现的元素
            list2.removeAll(list1);
            //把剩余的list2元素加到list1中
            list1.addAll(list2);
    
    使用shuffle打乱列表

    举个栗子:

    public static void main(String[] args) {
            int tagCloudNum = 10;
            List<String> tagClouds = new ArrayList<String>(tagCloudNum);
            // 初始化标签云,一般是从数据库读入,省略
            //打乱顺序
            Collections.shuffle(tagClouds);
        }
    

    shuffle使用场景:

    1. 可用在程序的 "伪装" 上:比如我们例子中的标签云,或者是游侠中的打怪、修行、群殴时宝物的分配策略。
    2. 可用在抽奖程序中:比如年会的抽奖程序,先使用shuffle把员工顺序打乱,每个员工的中奖几率相等,然后就可以抽出第一名、第二名。
    3. 可以用在安全传输方面:比如发送端发送一组数据,先随机打乱顺序,然后加密发送,接收端解密,然后进行排序,即可实现即使是相同的数据源,也会产生不同密文的效果,加强了数据的安全性。
  • 相关阅读:
    springboot项目搭建
    linux之scp
    docker文件拷贝
    vue数据绑定不刷新可能情况
    css弹框
    jqgrid跨站脚本漏洞解决
    springboot配置文件加载顺序
    git之在eclipse上玩(一)
    windows系统日志位置
    maven
  • 原文地址:https://www.cnblogs.com/androidsuperman/p/9450510.html
Copyright © 2011-2022 走看看