当前位置: 首页 > 编程日记 > 正文

(原创)JAVA注解应用——实现属性的自动检测

一、什么是注解

Annotation(注解)是JDK5.0及以后版本引入的新特性。它可以用于创建文档,跟踪代码中的依赖性,甚至执行基本编译时检查。注解是以‘@注解名’在代码中存在的,根据注解参数的个数,我们可以将注解分为:标记注解、单值注解、完整注解三类。它们都不会直接影响到程序的语义,只是作为注解(标识)存在,我们可以通过反射机制编程实现对这些元数据(用来描述数据的数据)的访问。

二、注解能做什么

Annotation提供了一种安全的类似注释的机制,为我们在代码中添加信息提供了一种形式化得方法,使我们可以在稍后某个时刻方便的使用这些数据(通过解析注解来使用这些数据),用来将任何的信息或者元数据与程序元素(类、方法、成员变量等)进行关联。其实就是更加直观更加明了的说明,这些说明信息与程序业务逻辑没有关系,并且是供指定的工具或框架使用的。Annotation像一种修饰符一样,应用于包、类型、构造方法、方法、成员变量、参数及本地变量的申明语句中。

Annotation其实是一种接口。通过java的反射机制相关的API来访问Annotation信息。相关类(框架或工具中的类)根据这些信息来决定如何使用该程序元素或改变它们的行为。Java语言解释器在工作时会忽略这些Annotation,因此在JVM中这些Annotation是“不起作用”的,只能通过配套的工具才能对这些Annotation类型的信息进行访问和处理。

三、使用注解实现JAVABEAN中属性的自动检测

我们要接下来实现的功能很简单,假设有这么一个场景:外部需要调用某系统接口实现某一功能,其中接口参数是用JavaBean进行传递,JavaBean中定义了几个属性,系统中对这几个属性有着严格的限制,比如:非空、长度限制、参数取值限制等等。

按照传统的方法,我们可能需要针对每个javabean中的每个属性都要写对应的逻辑的判断,设想一下,如果这个系统的接口有1000个,是不是我们应该事先1000个逻辑?NONONO,不需要,java注解功能可以很好的事先这个问题。

1.要实现上面的三个监测,我们需要定义三个不同的注解,代码如下:

 1 package com.maomq.testannotation.annotation;
 2 
 3 import java.lang.annotation.Documented;
 4 import java.lang.annotation.ElementType;
 5 import java.lang.annotation.Retention;
 6 import java.lang.annotation.RetentionPolicy;
 7 import java.lang.annotation.Target;
 8 
 9 /**
10  * 必填项注解
11  * @author maomq
12  * @since 2013-08-29
13  */
14 @Retention(RetentionPolicy.RUNTIME)
15 @Target({ElementType.FIELD})
16 @Documented
17 public @interface Required {
18 
19 }
非空注解
 1 package com.maomq.testannotation.annotation;
 2 
 3 import java.lang.annotation.Documented;
 4 import java.lang.annotation.ElementType;
 5 import java.lang.annotation.Retention;
 6 import java.lang.annotation.RetentionPolicy;
 7 import java.lang.annotation.Target;
 8 
 9 /**
10  * 元素长度范围注解
11  * @author maomq
12  * @since 2013-08-29
13  */
14 @Retention(RetentionPolicy.RUNTIME)
15 @Target({ElementType.FIELD})
16 @Documented
17 public @interface LengthLimitRange {
18 
19     static final int MIN_VALUE = 0;
20     
21     static final int MAX_VALUE = 255;
22     
23     public int minValue() default MIN_VALUE;
24     
25     public int maxValue() default MAX_VALUE;    
26 }
长度限制注解
 1 package com.maomq.testannotation.annotation;
 2 
 3 import java.lang.annotation.Documented;
 4 import java.lang.annotation.ElementType;
 5 import java.lang.annotation.Retention;
 6 import java.lang.annotation.RetentionPolicy;
 7 import java.lang.annotation.Target;
 8 
 9 /**
10  * 字符串范围注解
11  * @author maomq
12  * @since 2013-08-29
13  */
14 @Retention(RetentionPolicy.RUNTIME)
15 @Target({ElementType.FIELD})
16 @Documented
17 public @interface ArrayStringRange {
18     public String[] valueArray();
19 }
字符串取值范围注解

2.注解定义好了,下一步应该定义注解的判断逻辑,这里我们引入一个接口,它将定义所有的监测规则

 1 package com.maomq.testannotation.checker;
 2 
 3 import java.lang.reflect.Field;
 4 
 5 /**
 6  * 注解检测实现接口类
 7  * 
 8  * @author maomq
 9  * @since 2013-08-29
10  */
11 public interface FieldAnnotationChecker {
12 
13     /**
14      * 返回check结果
15      * 
16      * @param value
17      * @param field
18      * @return boolean
19      */
20     public boolean check(Object value, Field field);
21 }
 1 package com.maomq.testannotation.checker;
 2 
 3 import java.lang.reflect.Field;
 4 import java.util.Collection;
 5 import java.util.Map;
 6 
 7 /**
 8  * 注解检测实现类
 9  * @author maomq
10  * @since 2013-08-29
11  */
12 public class RequiredAnnotationChecker implements FieldAnnotationChecker {
13 
14     @Override
15     public boolean check(Object value, Field field) {
16         if (null == value)
17         {
18             System.out.println("The required value is null!");
19             return false;
20         }
21         
22         if (value instanceof String)
23         {
24             String strValue = (String) value;
25             if(strValue.isEmpty())
26             {
27                 System.out.println("The required value is null!");
28                 return false;
29             }
30         }
31         else if (value instanceof Collection<?>)
32         {
33             Collection<?> collValue = (Collection<?>) value;
34             if(collValue.isEmpty())
35             {
36                 System.out.println("The required value is null!");
37                 return false;
38             }
39         }
40         else if (value instanceof Map<?, ?>)
41         {
42              Map<?, ?> mapValue = ( Map<?, ?>) value;
43             if(mapValue.isEmpty())
44             {
45                 System.out.println("The required value is null!");
46                 return false;
47             }
48         }
49         return true;
50     }
51 
52 }
必填项监测实现类
 1 package com.maomq.testannotation.checker;
 2 
 3 import java.lang.reflect.Field;
 4 import java.util.Collection;
 5 import java.util.Map;
 6 
 7 import com.maomq.testannotation.annotation.LengthLimitRange;
 8 
 9 /**
10  * 注解检测实现类
11  * 
12  * @author maomq
13  * @since 2013-08-29
14  */
15 public class LengthLimitRangeAnnotationChecker implements
16         FieldAnnotationChecker {
17 
18     @Override
19     public boolean check(Object value, Field field) {
20         if (null == value) {
21             System.out.println("The value is null or empty!");
22             return true;
23         }
24 
25         LengthLimitRange lengthRange = field
26                 .getAnnotation(LengthLimitRange.class);
27 
28         int maxValue = lengthRange.maxValue();
29 
30         int minValue = lengthRange.minValue();
31 
32         if (value instanceof String) {
33             String strValue = (String) value;
34             if (strValue.length() > maxValue || strValue.length() < minValue) {
35                 System.out
36                         .println("The input value is out of the value limit range!");
37                 return false;
38             }
39         } else if (value instanceof Collection<?>) {
40             Collection<?> collValue = (Collection<?>) value;
41             if (collValue.size() > maxValue || collValue.size() < minValue) {
42                 System.out
43                         .println("The input value is out of the value limit range!");
44                 return false;
45             }
46         } else if (value instanceof Map<?, ?>) {
47             Map<?, ?> mapValue = (Map<?, ?>) value;
48             if (mapValue.values().size() > maxValue
49                     || mapValue.values().size() < minValue) {
50                 System.out
51                         .println("The input value is out of the value limit range!");
52                 return false;
53             }
54         }
55         return true;
56     }
57 
58 }
长度限制检测实现类
 1 package com.maomq.testannotation.checker;
 2 
 3 import java.lang.reflect.Field;
 4 
 5 import com.maomq.testannotation.annotation.ArrayStringRange;
 6 
 7 /**
 8  * 注解检测实现类
 9  * 
10  * @author maomq
11  * @since 2013-08-29
12  */
13 public class ArrayStringRangeAnnotationChecker implements
14         FieldAnnotationChecker {
15 
16     @Override
17     public boolean check(Object value, Field field) {
18         if (null == value) {
19             System.out.println("The value is null or empty!");
20             return true;
21         }
22 
23         ArrayStringRange arrayRange = field
24                 .getAnnotation(ArrayStringRange.class);
25 
26         String[] strArray = arrayRange.valueArray();
27 
28         if (value instanceof String && strArray.length > 0) {
29             for (String strTemp : strArray) {
30                 if (strTemp.equalsIgnoreCase(value.toString())) {
31                     return true;
32                 }
33             }
34             System.out.println("The input value is out of the value range!");
35             return false;
36         }
37 
38         return true;
39     }
40 
41 }
字符串取值范围实现类

3.检测逻辑也完成了,我们是针对每个JAVABEAN中的属性,因此,不可避免的需要一个Util类获取JavaBean中的属性,上代码:

  1 package com.maomq.testannotation;
  2 
  3 import java.lang.annotation.Annotation;
  4 import java.lang.reflect.Field;
  5 import java.util.ArrayList;
  6 import java.util.HashMap;
  7 import java.util.List;
  8 import java.util.Map;
  9 
 10 import com.maomq.testannotation.annotation.ArrayStringRange;
 11 import com.maomq.testannotation.annotation.LengthLimitRange;
 12 import com.maomq.testannotation.annotation.Required;
 13 import com.maomq.testannotation.checker.ArrayStringRangeAnnotationChecker;
 14 import com.maomq.testannotation.checker.FieldAnnotationChecker;
 15 import com.maomq.testannotation.checker.LengthLimitRangeAnnotationChecker;
 16 import com.maomq.testannotation.checker.RequiredAnnotationChecker;
 17 
 18 /**
 19  * 注解检测测试类
 20  * @author maomq
 21  * @since 2013-08-29
 22  */
 23 public class AnnotationCheckerUtil {
 24 
 25     private static Map<Class<?>, FieldAnnotationChecker> holder = new HashMap<Class<?>, FieldAnnotationChecker>();
 26     
 27     static {
 28         holder.put(Required.class, new RequiredAnnotationChecker());
 29         holder.put(LengthLimitRange.class, new LengthLimitRangeAnnotationChecker());
 30         holder.put(ArrayStringRange.class, new ArrayStringRangeAnnotationChecker());
 31     }
 32     
 33     /**
 34      * 获取Bean中所有的属性
 35      * @param clazz
 36      * @param fieldList
 37      */
 38     private static void getAllField(Class<?> clazz, List<Field> fieldList)
 39     {
 40         if (fieldList == null)
 41         {
 42             fieldList = new ArrayList<Field>();
 43         }
 44         
 45         Field[] fieldArray = clazz.getDeclaredFields();        
 46         for (Field fieldTemp : fieldArray)
 47         {
 48             fieldList.add(fieldTemp);
 49         }
 50         
 51         Class<?> superClazz = clazz.getSuperclass();
 52         
 53         if(superClazz != Object.class)
 54         {
 55             getAllField(superClazz, fieldList);
 56         }
 57     }
 58     
 59     /**
 60      * 对传入的JAVABean属性进行检测(使用注解)
 61      * @param objParam
 62      * @return
 63      */
 64     public static boolean checkField(Object objParam)
 65     {
 66         List<Field> fieldList = new ArrayList<Field>();
 67         
 68         getAllField(objParam.getClass(), fieldList);
 69         
 70         if (fieldList == null || fieldList.isEmpty())
 71         {
 72             return true;
 73         }
 74         
 75         for (Field fieldTemp : fieldList)
 76         {
 77             fieldTemp.setAccessible(true);
 78             Object value = null;
 79             try {
 80                 value = fieldTemp.get(objParam);
 81             } catch (IllegalArgumentException e) {
 82                 e.printStackTrace();
 83             } catch (IllegalAccessException e) {
 84                 e.printStackTrace();
 85             }
 86             
 87             Annotation[] fieldAnnotations = fieldTemp.getAnnotations();
 88             
 89             for(Annotation annotation : fieldAnnotations)
 90             {
 91                 FieldAnnotationChecker checker = holder.get(annotation.annotationType());
 92                 
 93                 if (null != checker && !checker.check(value, fieldTemp))
 94                 {
 95                     return false;
 96                 }
 97             }
 98         }
 99         
100         return true;
101     }
102 }

4.上面的工作都已经准备好了,现在可以测试一下了,首先定义一个javabean,并对其中需要检测的项目予以标注。

 1 package com.maomq.testannotation;
 2 
 3 import com.maomq.testannotation.annotation.ArrayStringRange;
 4 import com.maomq.testannotation.annotation.LengthLimitRange;
 5 import com.maomq.testannotation.annotation.Required;
 6 
 7 /**
 8  * 注解检测测试Bean类
 9  * @author maomq
10  * @since 2013-08-29
11  */
12 public class TestAnnotationBean {
13     //必填项检测
14     @Required
15     private String userId;
16     //必填,长度限制
17     @Required
18     @LengthLimitRange(minValue = 1, maxValue = 10)
19     private String userName;
20     //必填,取值范围限制
21     @Required
22     @ArrayStringRange(valueArray = {"football", "basketball", "swimming"})
23     private String habby;
24     
25     @SuppressWarnings(value = { "" })
26     private String description;
27 
28     public String getUserId() {
29         return userId;
30     }
31 
32     public void setUserId(String userId) {
33         this.userId = userId;
34     }
35 
36     public String getUserName() {
37         return userName;
38     }
39 
40     public void setUserName(String userName) {
41         this.userName = userName;
42     }
43 
44     public String getHabby() {
45         return habby;
46     }
47 
48     public void setHabby(String habby) {
49         this.habby = habby;
50     }
51 
52     public String getDescription() {
53         return description;
54     }
55 
56     public void setDescription(String description) {
57         this.description = description;
58     }
59 }

对上面的结果进行验证:

 1 package com.maomq.testannotation;
 2 
 3 /**
 4  * 注解检测测试类
 5  * @author maomq
 6  * @since 2013-08-29
 7  */
 8 public class TestAnnotation {
 9 
10 
11     public static void main(String[] args) {
12         TestAnnotationBean testAnnotationBean =new TestAnnotationBean();
13         
14         testAnnotationBean.setUserId("AAA");
15         testAnnotationBean.setUserName("12345678901");
16         testAnnotationBean.setHabby("walking");
17         testAnnotationBean.setDescription("ggsgsgsggs");
18         
19         if(!AnnotationCheckerUtil.checkField(testAnnotationBean))
20         {
21             System.out.println("Something is wrong!");
22         }
23     }
24 
25 }

输出如我们所料:habby不符合取值范围。

The input value is out of the value limit range!
Something is wrong!

四、小结

通过上面的例子我们可以大致了解注解的功能,如果需要深挖,建议大家学习一下Spring中对java注解功能应用,尤其是涉及事务控制的注解,真的很精髓,有兴趣的同学一定要抽时间学习一下,我这只是抛砖引玉,还望不吝赐教。

转载于:https://www.cnblogs.com/MarvinMao/p/3308514.html

相关文章:

整合vs2005sp1到vs2005安装文件中

首先,需要大于3G的硬盘空间(解压VS2005用),这个补丁只会应用到VS2005上,和我们的MSND是没有啥关系的.1.解压VS2005.首先需要把我们VS2005安装光盘内的安装文件解压在我们的硬盘上.使用如下命令: 程序代码msiexec.exe /a G:/VS/vs_setup.msi TARGETDIRD:/VSSETUP /L*vx install.…

唏嘘!程序员,你的年底KPI完不成的原因找到了!

加班是每个互联网人不愿面对而却又绕不过去的话题&#xff0c;就连面试时“你怎么看待加班”的问题都成了必答题。现在临近年底&#xff0c;大家都在努力冲业绩&#xff0c;期待拿更多的年终奖&#xff0c;回家过个“富足年”。年底冲业绩&#xff0c;势必会增加我们的工作量&a…

Hooq 登陆新加坡,“亚洲版 Netflix ”要与对标公司抢夺东南亚视频市场

近日&#xff0c;在进入菲律宾、泰国、印度、印尼四国之后&#xff0c;Hooq 正式在新加坡推出其视频服务。 Hooq 是一家视频点播流媒体平台&#xff0c;成立于 2015 年&#xff0c;由 Singtel (新加坡最大的电信公司)、索尼和华纳兄弟共同出资 2200 万美元成立&#xff0c;其中…

c#如何取自身应用程序文件名和路径?

// 应用程序的路径&#xff0c;不带文件名 Application.StartupPath(); // 产品名称 Application.ProductName; // 产品版本&#xff08;可由.net自动升成版本控制&#xff09; Application.ProductVersion

使用阿里云服务器时遇到的问题及解决办法

2019独角兽企业重金招聘Python工程师标准>>> 1、在命令行里面直接输入中文数据会乱码&#xff0c;如果用phpmyadmin就不会了。 2、json返回的数据中中文乱码&#xff0c;通过修改文件的编码可以解决。 3、页面文件中<body>标签后面多了个空格和空行&#xff0…

“算法不行,干啥都不行!”面试官:面试基本都会考这点!

无论你是 Java&#xff0c;Python&#xff0c;还是 PHP&#xff0c;面试总逃脱不了一个问题&#xff1a;算法&#xff01;据统计&#xff0c;各大厂笔试平均通过率只有 10%~20%&#xff0c;基本都折在了算法上。滴滴出行笔试通过率为 18.2%&#xff1b;腾讯秋招笔试通过率不足1…

归于软银帐下,ARM需要接受的变与不变

摘要&#xff1a;软银此次对于ARM的收购&#xff0c;在无形之中也拉近了ARM与日本IDM大厂间的合作距离&#xff0c;可以帮助其更好地进行超算芯片的制造&#xff1b;而从另一个层面来讲&#xff0c;“后K超级计算机”又何尝不是ARM的一个“活字招牌”&#xff1f;7月中旬&#…

C#中TextBox只能输入数字的代码

private void txbSleep_KeyPress(object sender, KeyPressEventArgs e) { if (!(Char.IsNumber(e.KeyChar) || e.KeyChar /b)) { e.Handled true; } }

Linux技巧总结(个人经验版)

1&#xff1a;善用桌面&#xff1a;1、图形界面的编辑&#xff0c;2、终端只要开机就在第2桌面&#xff0c;3、浏览器在第3桌面&#xff0c;4、娱乐在第4桌面。 2&#xff1a;cd命令中&#xff0c;输入中文目录很不方便&#xff0c;用 ln -s 桌面 desktop 创建软链接&#xff0…

一流科技完成5000万人民币A轮融资,高瓴创投独家领投

2月4日&#xff0c;专注于人工智能基础设施软件的研发工作的一流科技宣布完成由高瓴创投独家领投的A轮融资&#xff0c;这是其两年来再次开放融资&#xff0c;融资总额5000万元人民币。本次融资将用于高端人才招募、核心产品研发和商业模式拓展。自2017年创立以来&#xff0c;一…

发改委:加速布局车联网与自动驾驶

发改委网站5日消息&#xff0c;近日&#xff0c;为深入贯彻落实《国务院关于积极推进“互联网”行动的指导意见》(国发〔2015〕40号)&#xff0c;国家相关部门联合发布《推进“互联网”便捷交通促进智能交通发展的实施方案》(以下简称《实施方案》)&#xff0c;旨在全面推进交通…

花了两天,终于把 Python 的 setup.py 给整明白了

作者 | 写代码的明哥来源 | Python编程时光头图 | 下载于视觉中国为什么需要对项目分发打包平常我们习惯了使用 pip 来安装一些第三方模块&#xff0c;这个安装过程之所以简单&#xff0c;是因为模块开发者为我们默默地为我们做了所有繁杂的工作&#xff0c;而这个过程就是 打包…

MyBatis 中的 set 元素用法(MyBatis 3.1.1)

2019独角兽企业重金招聘Python工程师标准>>> 现在的写法A&#xff1a; <update id"update" parameterType"ruleItem.Bean"> update t_rule_item <!-- set id#{id} --> <set> <if test"ruleId!null and rul…

在.NET环境下发送邮件

在微软.NET环境中的System.Web.Mail的命名空间里,提供了几个类,使得你根本就不需要了解POP3等一系列网络协议,就可以在程序中轻松的发送邮件,非常简单,本文就简要的介绍一下,如何用C#语言来实现。 首先,我们要添加这个命名空间 using System.Web.Mail; 现在,我们来生成邮件本身…

Google刚刚开源了一款用于测试iOS应用的工具:EarlGrey

Google于今日宣布了开源的EarlGrey软件&#xff0c;以便开发者更轻松地构建和运行“面向iOS apps源码”的用户界面测试(是的&#xff0c;你没看错!)当前托管于GitHub上、遵从开源Apache授权的EarlGrey&#xff0c;由Objective-C编写而成。不过本次发布的重要性在于&#xff0c;…

发送邮件程序(Csharp2005)

我觉得懂得编写发送邮件客服端丰常重要.这可以把它嵌入到你的软件里加强与用户的沟通与可以收集程运行的错误信息.以与我编写一小的发送邮件客服端来与在家交流.程序如下:发送邮件解决方案下载 接下来,我来说一下我开发的过程与体会:创建发送邮件客服端步骤:1.创建Smtp服务器…

reindex-maven 私服(nexus)架设以及项目管理中遇到的问题及解决方案(updating)

--- 用maven 的过程中 大问题小问题实在是不少 &#xff0c;就不一篇文章一篇文章的写了&#xff0c;干脆写在一起 ---- ------- nexus 加索引 点击Administration菜单下面的Repositories&#xff0c;将这三个仓库Apache Snapshots&#xff0c;Codehaus Snapshots&#xff…

爬了20W+条猫咪交易数据,它不愧是人类团宠

作者 | 叶庭云来源 | 修炼Python头图 | 下载于视觉中国前言看到可爱的猫咪表情包&#xff0c;总是会忍不住收藏&#xff0c;晒部分图如下&#xff1a;认识的一些朋友也养了猫&#xff0c;比如橘猫、英短、加菲猫之类的&#xff0c;看他们发朋友圈撸猫&#xff0c;老羡慕了&…

数据中心建设“优劣”在于这几个关键问题

数据中心的建设是一个整体结构&#xff0c;任何一个细节规划忽略都有可能导致问题的发生&#xff0c;规划设计的优劣&#xff0c;也只有在系统运行后才能做客观的评估&#xff0c;很多问题要经过较长时间&#xff0c;甚至是设备或系统的一个生命周期内才能暴露出来。因此&#…

如何有效的使用C#读取文件

你平时是怎么读取文件的&#xff1f;使用流读取。是的没错&#xff0c;C#给我们提供了非常强大的类库&#xff08;又一次吹捧了.NET一番&#xff09;&#xff0c;里面封装了几乎所有我们可以想到的和我们没有想到的类&#xff0c;流是读取文件的一般手段&#xff0c;那么你真的…

eclipse 默认jdk 的设置 eclipse.ini -vm 参数

2019独角兽企业重金招聘Python工程师标准>>> eclipse 的配置文件 eclipse.ini 不仅仅可以设置eclipse的堆栈内存大小&#xff0c;也可设置默认使用的jdk版本。 一、现有个eclipse 默认启动jdk版本是jdk1.5&#xff0c;需更改为1.6 步骤如下&#xff1a; 方法1&#…

用韩信三技能,讲清楚一致性哈希

作者 | 悟空聊架构来源 | 悟空聊架构头图 | 下载于视觉中国韩信点兵的成语来源淮安民间传说。常与多多益善搭配&#xff0c;寓意越多越好。我们来看下主公刘邦和韩信大将军的对话。刘邦&#xff1a;“你觉得我可以带兵多少&#xff1f;”韩信&#xff1a;“最多十万。”刘邦不解…

有计划地开放数据 促进大数据法规落地

5月1日起&#xff0c;《贵阳市政府数据共享开放条例》正式实施。 《条例》的出台&#xff0c;仅仅是我市大数据发展步入法治轨道的开始。如何更好地让《条例》实现落地&#xff0c;成为新的课题。 2017年1月18日&#xff0c;贵阳市政府数据开放平台正式上线。目前&#xff0c;平…

C#中Base64之编码,解码方法

编码 public string EncodeBase64(string code_type,string code) { string encode ""; byte[] bytes Encoding.GetEncoding(code_type).GetBytes(code); try { encode Convert.ToBase64String(bytes); } catch { encode code; } return encode; }…

自回归与非自回归模型如何兼得?预训练模型BANG或许可解

作者 | 齐炜祯、宫叶云、段楠来源 | 微软研究院AI头条头图 | 下载于视觉中国编者按&#xff1a;近两年&#xff0c;预训练技术的发展极大地提高了自然语言生成的效果&#xff0c;但随着数据量和模型大小的增加&#xff0c;模型在使用时的推断耗时也随之变大。为了降低自回归生成…

STL--自定义类型的排序

STL的排序太坑了&#xff0c;尤其是在VS2010上重载sort函数的第三个比较参数的时候。 invalid operator < 这个错在写多关键字排序的时候就没有停止过。 本来想查书解决&#xff0c;结果各种重载都试了还是不行&#xff0c;百度才知道是因为&#xff1a;strict weak orderin…

《树莓派Python编程指南》——2.3 小结

本节书摘来自华章计算机《树莓派Python编程指南》一书中的第2章&#xff0c;第2.3节,作者&#xff1a;&#xff08;美&#xff09; Alex Bradbury Ben Everard更多章节内容可以访问云栖社区“华章计算机”公众号查看。 2.3 小结 我们的Python快速导览到此为止。希望这些程序能…

十年沉浮,用Python看创业公司消亡史

作者 | 叶庭云来源 | 修炼Python头图 | 下载于视觉中国前言IT桔子有一个新经济死亡公司数据库&#xff1a;https://www.itjuzi.com/deathCompany&#xff0c;统计了2000-2020年之间比较出名的公司 "死亡" 数据。"死亡公司数据库" 的公司关闭时间是依据公开…

.NET下正则表达式应用的四个示例

1.确认有效电子邮件格式 下面的代码示例使用静态 Regex.IsMatch 方法验证一个字符串是否为有效电子邮件格式。如果字符串包含一个有效的电子邮件地址&#xff0c;则 IsValidEmail 方法返回 true&#xff0c;否则返回 false&#xff0c;但不采取其他任何操作。您可以使用 IsVali…

static的本质

通过反编译发现&#xff0c;static的本质是abstract sealed。因此&#xff0c;无法继承System.Math类&#xff0c;因为它是static的。转载于:https://www.cnblogs.com/Benjamin/p/3319856.html