Java程序员的日常—— 基于类的策略模式、List<?>与List、泛型编译警告、同比和环比

简介:

早晨起得太早,昨晚睡得太晚,一天都迷迷糊糊的。中午虽然睡了半个小时,可是依然没有缓过来。整个下午都在混沌中....不过今天下载了一款手游——《剑侠情缘》,感觉不错,喜欢这种类型的游戏。

今天主要的工作还是做业务需求,不过下午状态不好,看了下《Effective java》,正好重构了下代码。

effective java 通过函数来作为策略

通过函数作为策略有两个要注意的地方:

  • 使用接口作为策略传入
  • 如果长期调用,应该设置为静态内部类,避免频繁创建过多的匿名对象

下面举个简单的例子,针对Engineer类提供不同的策略做排序,比如按照年龄或者按照员工级别:

class Engineer{
    private String name;
    private int age;
    private int level;
    public Engineer(String name,int age,int level) {
        this.name = name;
        this.age = age;
        this.level = level;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public int getLevel() {
        return level;
    }
    public void setLevel(int level) {
        this.level = level;
    }
}
public class Strategy {
    public static final Comparator<Engineer> AGE_ORDER = new AgeComparator();
    public static final Comparator<Engineer> LEVEL_ORDER = new LevelComparator();
    private static class AgeComparator implements Comparator<Engineer>{
        @Override
        public int compare(Engineer e1, Engineer e2) {
            return e1.getAge()-e2.getAge();
        }
    }
    private static class LevelComparator implements Comparator<Engineer>{
        @Override
        public int compare(Engineer e1, Engineer e2) {
            return e1.getLevel()-e2.getLevel();
        }
    }
    public static void main(String[] args) {
        List<Engineer> el = new ArrayList<>();
        el.add(new Engineer("zhangsan", 26, 3));
        el.add(new Engineer("lisi", 30, 2));
        el.add(new Engineer("wangwu", 28, 1));
        Collections.sort(el,AGE_ORDER);
        System.out.println(JSON.toJSON(el));
        Collections.sort(el,LEVEL_ORDER);
        System.out.println(JSON.toJSON(el));
    }
}

在上面的例子中,采用静态成员变量声明,可以在多次使用的时候节省创建对象的成本。而且静态成员在堆内存的分配上也更简单,不会每次都创建新的对象。

在真实的场景中,是在某个请求方法里面,返回一个List对象,需要对它按照日期排序。如果是普通的Collections.sort(list,new Comparator<xx>{})这种方式,会在每次返回结果的时候,都创建一个匿名类,很显然会浪费不少内存空间,增加垃圾回收的压力。使用静态成员变量的方式,可以减少这种不必要的浪费。

List<?>与List

由于在1.5之前的版本,java是没有泛型概念的。因此在引入泛型后,需要考虑到以前代码的移植。

没有泛型的时候,如果使用List,可以往里面插入任意类型的值。但是在取得时候,如果类型不对就有问题了:

List list = new ArrayList();
list.add(1);

String list0 = list.get(0);//出错

为了避免这种问题,1.5引入泛型,这样一套代码可以适用于多种类型;还能在编译器就检查类型是否一致。

除了这种List<E> xxx标准的泛型,java还提供了无限制性的泛型:

<?>意思是未知类型,就是不设上下限
<? extend Object>意思是继承于Object的未知类型
<? super Object>意思是Object的祖先类型

所以,尽量使用标准的格式,在某些情况下已知的一些通配限制,还可以使用<?>号加以限制。

记得最开始自己写代码的时候,满满的都是黄色标记,师兄就纠正我的做法,让我把这些警告全都去掉。其实随时保证没有警告的代码,才是最负责的做法。不管是自己屏蔽掉,还是做相应的解决,都好过编译的时候爆出一大堆警告好。

编译器警告

Java是一门编译型的语言,需要经过编译,变成class字节码才能执行。但是在编写泛型相关的代码时,总是会遇到一些警告。比如参数仅仅声明为Map,没有声明具体内部的内容等等。

在Eclipse中可以通过加入@SuppressWarning注解来忽略警告,但是不推荐这种做法。除非你对自己的代码非常自信,保证不会出现其他的类型,而导致ClassCastException。所以尽量在写代码的时候不要产生警告,如果想要忽略,尽量考虑清楚入口出口是否不会出现意外。

常用的就是unckecked和rawtypes,一个是不检查内部变量,一个是不检查参数类型。

all to suppress all warnings
boxing to suppress warnings relative to boxing/unboxing operations
cast to suppress warnings relative to cast operations
dep-ann to suppress warnings relative to deprecated annotation
deprecation to suppress warnings relative to deprecation
fallthrough to suppress warnings relative to missing breaks in switch statements
finally to suppress warnings relative to finally block that don’t return
hiding to suppress warnings relative to locals that hide variable
incomplete-switch to suppress warnings relative to missing entries in a switch statement (enum case)
nls to suppress warnings relative to non-nls string literals
null to suppress warnings relative to null analysis
rawtypes to suppress warnings relative to un-specific types when using generics on class params
restriction to suppress warnings relative to usage of discouraged or forbidden references
serial to suppress warnings relative to missing serialVersionUID field for a serializable class
static-access to suppress warnings relative to incorrect static access
synthetic-access to suppress warnings relative to unoptimized access from inner classes
unchecked to suppress warnings relative to unchecked operations
unqualified-field-access to suppress warnings relative to field access unqualified
unused to suppress warnings relative to unused code

什么是同比和环比

做业务需求,还是需要了解些业务知识才行。无论是电商环境,还是传统企业,环比和同比是最常见的数据分析手段,可以通过对比明显的看到当前业务的变化趋势,有利于管理层即使做出调整,那么什么是环比,什么是同比呢?

  • 环比就是现在的统计周期和上一个统计周期比较。
  • 同比是与历史时期作比较。

举个例子:

  • 2016年4月和2016年的3月相比,就是环比
  • 2016年的10月和2015年的10月相比,就是同比

太业务化的东西,就不说了,免得设计到什么尴尬的信息。

睡觉时间到,养好精神,才能专注...

本文转自博客园xingoo的博客,原文链接:Java程序员的日常—— 基于类的策略模式、List<?>与List、泛型编译警告、同比和环比,如需转载请自行联系原博主。
相关文章
|
30天前
|
设计模式 算法 搜索推荐
Java 设计模式之策略模式:灵活切换算法的艺术
策略模式通过封装不同算法并实现灵活切换,将算法与使用解耦。以支付为例,微信、支付宝等支付方式作为独立策略,购物车根据选择调用对应支付逻辑,提升代码可维护性与扩展性,避免冗长条件判断,符合开闭原则。
255 35
|
1月前
|
存储 Java 索引
用Java语言实现一个自定义的ArrayList类
自定义MyArrayList类模拟Java ArrayList核心功能,支持泛型、动态扩容(1.5倍)、增删改查及越界检查,底层用Object数组实现,适合学习动态数组原理。
85 4
|
1月前
|
IDE JavaScript Java
在Java 11中,如何处理被弃用的类或接口?
在Java 11中,如何处理被弃用的类或接口?
148 5
|
1月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
135 1
|
1月前
|
Java Go 开发工具
【Java】(8)正则表达式的使用与常用类分享
正则表达式定义了字符串的模式。正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。
202 1
|
1月前
|
存储 Java 程序员
【Java】(6)全方面带你了解Java里的日期与时间内容,介绍 Calendar、GregorianCalendar、Date类
java.util 包提供了 Date 类来封装当前的日期和时间。Date 类提供两个构造函数来实例化 Date 对象。第一个构造函数使用当前日期和时间来初始化对象。Date( )第二个构造函数接收一个参数,该参数是从1970年1月1日起的毫秒数。
142 1
|
安全 Java
java线程之List集合并发安全问题及解决方案
java线程之List集合并发安全问题及解决方案
1341 1
|
运维 关系型数据库 Java
PolarDB产品使用问题之使用List或Range分区表时,Java代码是否需要进行改动
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
Java API Apache
怎么在在 Java 中对List进行分区
本文介绍了如何将列表拆分为给定大小的子列表。尽管标准Java集合API未直接支持此功能,但Guava和Apache Commons Collections提供了相关API。
385 1
|
存储 安全 Java
详解Java中集合的List接口实现的ArrayList方法 | Set接口实现的HashSet方法
详解Java中集合的List接口实现的ArrayList方法 | Set接口实现的HashSet方法
279 3