11.5
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();
}
- PlatformTransactionManager
PlatformTransactionManager 接口是 Spring 提供的平台事务管理器,用于管理事务。该接口中提供了三个事务操作方法,具体如下。
TransactionStatus getTransaction(TransactionDefinition definition):用于获取事务状态信息。
void commit(TransactionStatus status):用于提交事务。
void rollback(TransactionStatus status):用于回滚事务。
在项目中,Spring 将 xml 中配置的事务详细信息封装到对象 TransactionDefinition 中,然后通过事务管理器的 getTransaction() 方法获得事务的状态(TransactionStatus),并对事务进行下一步的操作。
- 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。
- 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”包