倒序

11.5

list

list的分类

无状态:指元素的处理不受之前元素的影响;
有状态:指该操作只有拿到所有元素之后才能继续下去。
非短路操作:指必须处理所有元素才能得到最终结果;
短路操作:指遇到某些符合条件的元素就可以得到最终结果


10.25

extend T 存放的都是T和其子类。 super T 存放的都是T和其父类

extend get原则 放不进去,因为不知道具体类型 可以取出来看
super put/set原则 可以放 取不出来,因为不知道如何转换

擦除

错误原因:一个 T 不能代表两个类型,不能即是TestBase 又是 Test1th,所以get(Test1th) 在编译器都不会通过。

public class Tested<T> {
    List<TestBase> list1 = new ArrayList<>();
    List<Test1th> list2 = new ArrayList<>();

    public Tested() {
        list1.add(new TestBase());
        list2.add(new Test1th());
    }

    public T get(List<T> t) {
        return t.get(0);
    }

    public List<TestBase> getList1() {
        return list1;
    }

    public List<Test1th> getList2() {
        return list2;
    }
}

测试类
public class TestBase { }
public class Test1th extends TestBase { }
    public void startTest() {
        Tested<TestBase> list = new Tested<>();
        TestBase t1 = list.get(list.getList1()); // suc
        TestBase t2 = (Test1th) list.get(list.getList2()); // fail
    }
修改方法 extend/super定下边界

1.      ? extend T 

    public Tested() {
        list1.add(new TestBase());
        list2.add(new Test1th());
    }

   public T get(List<? extends T> t) {
        return t.get(0);//在这里List<? extends T> t 这个List的元素类型的上边界是类型T,List的元素类型还可以是 T 的子类
    }




2.    ? super T 
    public void set(List<? super T> t, T item) {
        t.add(item);
    }

   public void startTest() {
        Tested<Test1th> list = new Tested<>();
        list.set(list.getList1(), new Test1th()); // suc
        list.set(list.getList2(), new Test1th()); // suc
    }



10.11

在编辑器内,也会遇到选择了一段代码准备复制的时候,经常也会把代码拖动到其他位置,导致错乱,还需要ctrl+z取消操作,禁用:设置file-setting 去掉 Move code


8.11

使用字符串String 的plit 方法时,传入的分隔字符串是正则表达式,则部分关键字(比如 .| 等)需要转义。

// . 需要转译
String[] split2 = "a.ab.abc".split("\\.");
System.out.println(Arrays.toString(split2));  // 结果为["a", "ab", "abc"]

// | 需要转译
String[] split3 = "a|ab|abc".split("\\|");
System.out.println(Arrays.toString(split3));  // 结果为["a", "ab", "abc"]


枚举的属性字段必须是私有且不可变

枚举通常被当做常量使用,如果枚举中存在公共属性字段或设置字段方法,那么这些枚举常量的属性很容易被修改;
理想情况下,枚举中的属性字段是私有的,并在私有构造函数中赋值,没有对应的Setter 方法,最好加上final 修饰符。

public enum SwitchStatus {

    // 枚举的属性字段正例
    DISABLED(0, "禁用"),
    ENABLED(1, "启用");

    // final 修饰
    private final int num;
    private final String description;

    private SwitchStatus(int num, String description) {
        this.num = num;
        this.description = description;
    }

    // 没有Setter 方法
    public int getNum() { return num; }
    public String getDescription() { return description; }


    public static String getDescriptionByNum(int num){
        for(SwitchStatus e : SwitchStatus.values()){
            if(num == e.num){
                return e.name;
            }
        }
        return "";
    }


}


优先使用常量或确定值调用equals 方法

对象的equals 方法容易抛空指针异常,应使用常量或确定有值的对象来调用equals 方法。

反例:
private static boolean fileReader(String fileName)throws IOException{
 // 可能抛空指针异常
 return fileName.equals("Charming");
}

正例:
private static boolean fileReader(String fileName)throws IOException{

    // 使用常量或确定有值的对象来调用 equals 方法
    return "Charming".equals(fileName);

    //或使用:java.util.Objects.equals() 方法
   return Objects.equals("Charming",fileName);
}


返回空数组和集合而非 null

正例:
public static Result[] getResults() {
    return new Result[0];
}

public static List<Result> getResultList() {
    return Collections.emptyList();
}

public static Map<String, Result> getResultMap() {
    return Collections.emptyMap();
}`</pre>


使用静态代码块实现赋值静态成员变量

对于集合类型的静态成员变量,应该使用静态代码块赋值,而不是使用集合实现来赋值

反例:
private static Map<String, Integer> map = new HashMap<String, Integer>(){
    {
        map.put("Leo",1);
        map.put("Family-loving",2);
        map.put("Cold on the out side passionate on the inside",3);
    }
};
private static List<String> list = new ArrayList<>(){
    {
        list.add("Sagittarius");
        list.add("Charming");
        list.add("Perfectionist");
    }
};

正例:
private static Map<String, Integer> map = new HashMap<String, Integer>();
static {
    map.put("Leo",1);
    map.put("Family-loving",2);
    map.put("Cold on the out side passionate on the inside",3);
}

private static List<String> list = new ArrayList<>();
static {
    list.add("Sagittarius");
    list.add("Charming");
    list.add("Perfectionist");
}`


若需频繁调用Collection.contains 方法则使用Set

        List<Object> list = new ArrayList();
        Set<Object> set = new HashSet(list);
        for (int i = 0; i < set.size(); i++) {
            if(set.contains(i)){
                System.out.println(" 先将集合list 转换成HashSet 实现,将O(n) 的时间复杂度将为O(1)");
            }
        }


7.14

Arraylist

retainAll() 方法用于保留 arraylist 中在指定集合中也存在的那些元素,也就是删除指定集合中不存在的那些元素。
arraylist.retainAll(Collection c);
如果 arraylist 中删除了元素则返回 true。
如果 arraylist 类中存在的元素与指定 collection 的类中元素不兼容,则抛出 ClassCastException 异常。
如果 arraylist 包含 null 元素,并且指定 collection 不允许 null 元素,则抛出 NullPointerException 。

containsAll() 方法检查了 collection 是否是动态数组中的一个子集
arraylist.containsAll(Collection c)
如果动态数组中包含的集合中的所有元素,则返回 true。
如果 arraylist 中存在的元素与指定 collection 中的元素不兼容,则抛出 ClassCastException。
如果 collection 中包含 null 元素,并且 arraylist 中不允许 null值,则抛出 NullPointerException 异常。

list.removeAll(list1); //从list中移除与list1相同的元素


7.9

&& || 具有短路的功能

if(str != null && !str.equals(“”))if((s==null)||(s.length()==0)){}表达式,当str为null时,后面的表达式不会执行,所以不会出现NullPointerException

7.1

网站自定义图标 No mapping for GET /favicon.ico

修改配置文件关闭系统图标 spring.mvc.favicon.enabled=false
在拦截器增加路径

/**
 * Spring MVC 配置
 */
@Configuration
@Slf4j
public class WebMvcConfigurer extends WebMvcConfigurationSupport {
  ...

   /**
     * 添加拦截器
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
            registry
                   .addInterceptor(...)
                   .excludePathPatterns("/favicon.ico");
        }
    }



    /**
     * 添加资源处理
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        registry.addResourceHandler("/static/**")
                .addResourceLocations("classpath:/static/");

        registry.addResourceHandler("/favicon.ico")
                .addResourceLocations("classpath:/static/"); //注意:上面即使已有/static的路径,也要写上这段,因为路径不同

    }

}


6.21

把静态资源放域名根目录

1.因为是ngnix代理 修改路径为/etc/nginx/conf.d/server.conf的文件加上内容

    location ^~ /8eafa7ee889cf4f84d8f86fe92b9bb92.html  {
        alias /root/8eafa7ee889cf4f84d8f86fe92b9bb92.html;
    }

保存退出后重载配置nginx -s reload;
2.复制文件到/root路径下 scp 文件全路径名 root@服务器地址:/root



6.7

对接支付宝时报某些参数不存在,不要用sdk里面的驼峰参数如goodId,直接用参数如good_id


A instanceof B 用来判断A是否是B的实例或者子类的实例对象


class Dog extends Animal
Animal anAnimal = new Dog();
此时不能直接用anAnimal调用子类独有的方法

if(anAnimal instanceof Dog){
//强转后就可以调用子类独有方法了
Dog dog = (Dog)anAnimal;
dog.bark();
}


事务三大接口
PlatformTransactionManager 事务管理器
TransactionDefinition 事务的一些基础信息,如超时时间、隔离级别、传播属性等
TransactionStatus 事务的一些状态信息,如是否一个新的事务、是否已被标记为回滚

//1
TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionDefinition);
platformTransactionManager.commit(transactionStatus);

//2
 catch (Exception e) {
 e.printStackTrace();
 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
  1. PlatformTransactionManager
    PlatformTransactionManager 接口是 Spring 提供的平台事务管理器,用于管理事务。该接口中提供了三个事务操作方法,具体如下。
    TransactionStatus getTransaction(TransactionDefinition definition):用于获取事务状态信息。
    void commit(TransactionStatus status):用于提交事务。
    void rollback(TransactionStatus status):用于回滚事务。

在项目中,Spring 将 xml 中配置的事务详细信息封装到对象 TransactionDefinition 中,然后通过事务管理器的 getTransaction() 方法获得事务的状态(TransactionStatus),并对事务进行下一步的操作。

  1. TransactionDefinition
    TransactionDefinition 接口是事务定义(描述)的对象,它提供了事务相关信息获取的方法,其中包括五个操作,具体如下。
    String getName():获取事务对象名称。
    int getIsolationLevel():获取事务的隔离级别。
    int getPropagationBehavior():获取事务的传播行为。
    int getTimeout():获取事务的超时时间。
    boolean isReadOnly():获取事务是否只读。

在上述五个方法的描述中,事务的传播行为是指在同一个方法中,不同操作前后所使用的事务。传播行为的种类如表 1 所示。

属性名称 描述
单元格 单元格 单格
PROPAGATION_REQUIRED required 支持当前事务。如果 A 方法已经在事务中,则 B 事务将直接使用。否则将创建新事务
PROPAGATION_SUPPORTS supports 支持当前事务。如果 A 方法已经在事务中,则 B 事务将直接使用。否则将以非事务状态执行
PROPAGATION_MANDATORY mandatory 支持当前事务。如果 A 方法没有事务,则抛出异常
PROPAGATION_REQUIRES_NEW requires_new 将创建新的事务,如果 A 方法已经在事务中,则将 A 事务挂起
PROPAGATION_NOT_SUPPORTED not_supported 不支持当前事务,总是以非事务状态执行。如果 A 方法已经在事务中,则将其挂起
PROPAGATION_NEVER never 不支持当前事务,如果 A 方法在事务中,则抛出异常
PROPAGATION.NESTED nested 嵌套事务,底层将使用 Savepoint 形成嵌套事务

通常情况下,数据的查询不会改变原数据,所以不需要进行事务管理,而对于数据的增加、修改和删除等操作,必须进行事务管理。如果没有指定事务的传播行为,则 Spring3 默认的传播行为是 required。

  1. TransactionStatus
    TransactionStatus 接口是事务的状态,它描述了某一时间点上事务的状态信息。其中包含六个操作,具体如表 2 所示。
名称 说明
void flush() 刷新事务
boolean hasSavepoint() 获取是否存在保存点
boolean isCompleted() 获取事务是否完成
boolean isNewTransaction() 获取是否是新事务
boolean isRollbackOnly() 获取是否回滚
void setRollbackOnly() 设置事务回滚



5.27

生成sign:按字典排序,有下划线靠前

            String A
                    = "amount=" + amount
                    + "&check_name=" + "NO_CHECK"
                    + "&desc=" + desc
                    + "&mch_appid=" + appId
                    + "&mchid=" + mchId
                    + "&nonce_str=" + noncestr
                    + "&openid=" + openId
                    + "&partner_trade_no=" + partnerTradeNo;
            String stringSignTemp = A
                    + "&key=" +key;  
            paramMap.put("sign", MD5(stringSignTemp));


BigDecimal初始化最好用String


让编号位数相同,在几千范围内可以先加1000之后减去

for (int j = 1000; j < 1000 + positionList.size(); j++) {
            VemRoutePosition position = positionList.get(j - 1000);
            sdd(j, ourMachine, appendMachine, appendSize, position.getRouteId(), position.getId(),position.getGpsLat(), position.getGpsLng());
        }


报错:67行报空指针 实际错误在68行 -> 换行的原因




5.25

1.提现功能

资金入账,提现绑定(冻结资金),运营商审核,提现,(失败返回资金),返回信息。

1.微信提供企业向个人付款的功能。企业通过APPID+OpenID锁定目标用户,向用户付款,因此只有关注了企业公众号的用户才能付款成功。
2.企业付款的公众号可以和微信公众号相同,但公众号的收款账号和付款账号不能共享。企业付款需要下载数字证书,Java只需要商户证书文件apiclient_cert.p12。
3.登陆商户平台开通企业付款到个人




5.21

3.maven


2.swagger

1.1 swagger下拉框
@ApiOperation(value = "测试swagger下拉框")
@ApiImplicitParams({
        @ApiImplicitParam(name = "type", value = "类型", dataType = "String", paramType = "query",
                allowableValues = "苹果,荔枝,菠萝", allowMultiple = true)
})
@RequestMapping(value = "/select", method = {RequestMethod.GET})
public String[] mystyle(String[] type) {
    return type;
}
1.2 分组配置
@Bean("质量管理")
public Docket controller1Apis() {
  return new Docket(DocumentationType.SWAGGER_2)
      .groupName("质量管理")
      .select()
      .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
      .paths(PathSelectors.regex("/quality/.*"))
      .build()
      .apiInfo(apiInfo())
      .enable(swaggerEnabled);
}
其中“"/quality/.*”就是controller中配置的url,会根据controller里面配置的url分spec
1.3 整体配置
@Configuration
public class Swagger2Configurer {

    @Resource
    private ConfigUtil configUtil;
    
    /**
     * 正式环境标识
     */
    private static String DEV = "prod";
    @Bean
    public Docket createRestApi() {
        if (DEV.equals(configUtil.SPRING_PROFILES_ACTIVE)) {
            ParameterBuilder aParameterBuilder = new ParameterBuilder();
            aParameterBuilder
                    .name("Authorization")
                    .description("Authorization").defaultValue("Bearer ")
                    .modelRef(new ModelRef("string"))
                    .parameterType("header")
                    .required(true)
                    .build();
            ParameterBuilder userParameterBuilder = new ParameterBuilder();
            userParameterBuilder
                    .name("Account")
                    .description("Account").defaultValue("PC账号名字")
                    .modelRef(new ModelRef("string"))
                    .parameterType("header")
                    .required(true)
                    .build();
            List<Parameter> aParameters = Lists.newArrayList();
            aParameters.add(aParameterBuilder.build());
            aParameters.add(userParameterBuilder.build());

            return new Docket(DocumentationType.SWAGGER_2)
                    .enable(configUtil.SWAGGER_ENABLE)
                    .host(configUtil.SWAGGER_OPS_HOST)
                    .globalOperationParameters(aParameters)
                    .apiInfo(apiInfo())
                    .select()
                    // 检索的包下面的控制器
                    .apis(RequestHandlerSelectors.basePackage(configUtil.BASE_PACKAGE))
                    .paths(PathSelectors.any())
                    .build();
        }
        return new Docket(DocumentationType.SWAGGER_2)
                .enable(configUtil.SWAGGER_ENABLE)
                .host(configUtil.SWAGGER_BASE_HOST)
                .apiInfo(apiInfo())
                .select()
                // 检索的包下面的控制器
                .apis(RequestHandlerSelectors.basePackage(configUtil.BASE_PACKAGE))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("机器平台")
                .termsOfServiceUrl("xxx")
                .version("1.0")
                .build();
    }
}


1.JApiDocs

2.1获取项目根路径, 其中xxx是当前的类名 
 
- 根据上下文获取
     ServletActionContext.getServletContext().getRealPath("");
 
    或getRequest().getSession().getServletContext().getRealPath("");
 
   这种在普通情况下是正常可以用的,但是在定时器里就不好使了,会报空指针异常,这是就要使用下面的方法了
 
- 根据当前类获取
    path = xxx.class.getClassLoader().getResource("/").getPath();// 这个是classes文件夹路径
 
    path = path.replace("/WEB-INF/classes", ""); //这个是root文件夹路径
 
- 获取子文件夹
    xxx.class.getClassLoader().getResource(“文件”).getPath(); //获取classes路径下“文件”的路径 
 
- 无类加载器
    xxx.class.getResource(“”).getPath();// 缺少类加载器,获取xxx类经编译后的xxx.class路径 
2.2 配置
tip: maven导入报找不到不要紧,直接reload

public class JApiDocs {

    public static void main(String[] args) {
        DocsConfig config = new DocsConfig();
        config.setProjectPath("/Users/xxx/Desktop/ch_-sale_-module"); // 项目根目录
        config.setProjectName("xxx"); // 项目名称
        config.addJavaSrcPath("/Users/mjl/Desktop/ch_-sale_-module/controller/extra/src/main/java/com/xxx/xxxx/controller/extra");//设置模块,可不写
        config.setApiVersion("V1.0");       // 声明该API的版本
        config.setDocsPath("/Users/mjl/Desktop/ch_-sale_-module/doc"); // 生成API 文档所在目录
        config.setAutoGenerate(Boolean.TRUE);  // 配置自动生成
        Docs.buildHtmlDocs(config); // 执行生成文档
    }
}

2.3 
报错:java.nio.file.NoSuchFileException: /V1.0/apidoc.log.lck 
at sun.nio.fs.UnixException.translateToIOException

解决:按照报错设置完整的文件夹绝对路径,并添加文件夹V1.0和文件apidoc.log.lck 
2.4 
报错:Exception in thread "main" java.lang.NoClassDefFoundError: freemarker/template/TemplateException
解决:向lib文件夹中复制“freemarker-xx.xx.jar”包 
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352

推荐阅读更多精彩内容