0%

文章字数:891,阅读全文大约需要3分钟

树是由一个根节点延伸到若干节点,再由这些若干节点向外延伸的数据结构。

概念

  1. 节点: 构成树的基本单位。
  2. : 是节点的有限集,当节点为空时成为空树。树只有一个根节点,多棵树之间无交互。
  3. : 节点拥有的子树(即子节点,子节点组成的数为子树)数量。
  4. 节点关系: 节点的下级节点成为该节点的孩子节点,节点是下级节点的双亲节点,节点下级节点之间互为兄弟节点
  5. 节点层次: 根节点为第一层,根节点的子节点为第二次,再往下为第三层…以此类推。
  6. 深度: 数节点的最大层次,成为改树的深度/高度。

二叉树

  1. 二叉树: 在树的定义之上增加子节点只有两个的限制,两个节点称为左节点右节点。左右节点次序不可以颠倒,只有一个节点也要区分左右节点。
  2. 斜树: 所有节点都只有左节点的二叉树称为左斜树,所有节点都只有右节点的二叉树称为右斜树
  3. 满二叉树: 二叉树上所有的分支节点都有左右节点,并且叶子节点处于同一层。即当前深度的二叉树中节点最多的结构。所有的层都是满的。
  4. 完全二叉树: 和满二叉树类型,只是最后一层不满,并且所有的空缺都在右边(先填满左节点再右节点)
  5. 二叉查找树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。[搜索,插入,删除的复杂度等于树高,O(log(n))]
  6. 红黑树: 一种自平衡的二叉查找树,解决了二叉查找树可能出现树不平衡的情况(全部在左边或者全部在右边等情况)
1
2
3
4
性质1. 节点是红色或黑色。
性质2. 根节点是黑色。(叶子节点null也是黑色的)
性质3 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
性质4. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

红黑树性质4保证了最长路径和最短路径差距不会超过两倍


文章字数:69,阅读全文大约需要1分钟

1
2
3
4
//获取系统中标记为 TR-TR 的语言(土耳其语)
trlocale = Locale.forLanguageTag(“TR-TR”);
//转换成土耳其语的 i (和英文不一样)
"i".toLowerCase(trlocale);

toLowerCase没设置语言则自动获取当前语言,可能会导致转换和想象的不一样


文章字数:333,阅读全文大约需要1分钟

桶排序的时间复杂度为 o(n+k) 即常数

思想

  1. 将有限的桶排列好顺序(包含所有数据或者数据范围)
  2. 将数据挨个放入相应的桶里(如果是范围,就在范围里线性排列)
  3. 按照桶的顺序取出所有数据,此时数据便排好了顺序

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*
* @param a 需要排序的数组
* @param max 用于自动生成桶,示例为小范围数字,所以直接生成顺序桶就好了。
*/
public static void bucketSort(int[] a, int max) {
int[] buckets;

if (a == null || max < 1){
return;
}

// 创建一个容量为max的数组buckets,并且将buckets中的所有数据都初始化为0。
buckets = new int[max];

// 1. 计数
for (int i = 0; i < a.length; i++){
buckets[a[i]]++;
}

// 2. 排序
for (int i = 0, j = 0; i < max; i++) {
while ((buckets[i]--) > 0) {
a[j++] = i;
}
}
buckets = null;
}

文章字数:43,阅读全文大约需要1分钟

  1. 当只有一个实现类时直接匹配(优先类型)
  2. 多个实现类匹配name
  3. name也匹配多个则报错

文章字数:97,阅读全文大约需要1分钟

根据一定的条件判断是否注入bean

声明两个条件

  • Windows环境下注入bean的条件
1
2
3
4
5
6
public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return context.getEvironment().getProperty("os.name").contains("Windows");
}
}
  • Linux环境下注入bean的条件
1
2
3
4
5
6
public class LinuxCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return context.getEvironment().getProperty("os.name").contains("Linux");
}
}

使用条件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Configuration
public class ConditionConfig {
@Bean
@Conditional(WindowsCondition.class)
public MyService windowMyService() {
// ...
}

@Bean
@Conditional(LinuxCondition.class)
public MyService linuxMyService() {
// ...
}
}

其它衍生的注解

1
2
3
@ConditionalOnMissingBean(xx.class) // 没有xx.class bean时注入
@ConditionalOnBean(xx.class) // 有xx.class bean 时注入
...

文章字数:624,阅读全文大约需要2分钟

Spring提供的自动将application.properties配置文件中参数绑定到指定类成员变量的注解,功能上类似@Value

基本使用

  1. 配置参数
1
2
myapp.mail.enable=true
myapp.mail.default-subject=test subject
  1. 绑定配置到配置类
1
2
3
4
5
6
7
8
9
10
11
12
// 必须要有setter方法
@Data
// 标记参数前缀
@ConfigurationProperties(prefix = "myapp.mail")
public class MailProperties {

/** 设置参数类型及默认值,如果配置文件里没有此参数,就使用默认值 */
/** */
private Boolean enable = Boolean.TRUE;

private String defaultSubject;
}

参数绑定规则

  1. 宽松绑定规则relaxed binding,多种书写方式都可以绑定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
myapp.mail.defaultSubject=test subject
myapp.mail.defaultsubject=test subject
myapp.mail.default-subject=test subject
myapp.mail.default_subject=test subject
myapp.mail.DEFAULT-SUBJECT=test subject
```

2. 前缀必须相同
3. 类型必须是可转换的,不可转换时默认抛出异常。设置`ignoreInvalidFields=true`可以忽略此错误
4. 未绑定的配置参数默认忽略,如果想存在未绑定参数是报错可以设置`ignoreUnknownFields=false`
5. 参数是否有效校验

```java
// 开启参数校验
@Validated
@Data
@ConfigurationProperties(prefix = "myapp.mail")
public class MailProperties {

/** 设置校验规则 */
@NotNull
private Boolean enable = Boolean.TRUE;
@NotEmpty
private String defaultSubject;
}

激活配置

  1. 创建了一个@ConfigurationProperties注解的配置类,还需要将其添加到应用上下文才能使用
  2. 可以直接@Componment将其添加到容器中
  3. 使用@configuration类中声明也有同样效果,和2类似,都是注册成bean
  4. 使用@EnableConfigurationProperties注解,让当前类被Spring容器感知

复杂类型属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/** list类型 */
private List<String> smtpServer;
/** 还支持map类型 */
private Map<String, String> serverInfo;

/** 持续时间,不写单位默认是毫秒,也可以指定默认单位 */
@DurationUnit(ChronoUnit.SECONDS)
private Duration mails;

/**
ns for nanoseconds (纳秒)
us for microseconds (微秒)
ms for milliseconds (毫秒)
s for seconds (秒)
m for minutes (分)
h for hours (时)
d for days (天)
*/

/** 数据大小,默认byte字节,也可以指定单位 */
@DataSizeUnit(DataUnit.MEGABYTES)
private DataSize maxAttachementSize = DataSize.ofMegabytes(2);

/**
B for bytes
KB for kilobytes
MB for megabytes
GB for gigabytes
TB for terabytes
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
myapp.mail.smtpServerp[0]=server0
myapp.mail.smtpServerp[1]=server1

# yml本身支持list
myapp:
mail:
smtp-servers:
- server0
- server1

# 可以指定单位,不指定按照默认单位
myapp.mail.mails=2s
myapp.mail.maxAttachementSize=1m

自定义类型

1
myapp.mail.weight=5kg
1
2
/** 声明属性 */
private Weight weight;
  • 自定义转换器
1
2
3
4
5
6
7
public class WeightConverter implements Converter<String, String> {

@Override
public Weight conver(String source) {
// 怎么将数值转换成类
}
}
  • 注册改转换器
1
2
3
4
5
6
7
8
9
@Configuration
class PropertiesConfig {

@Bean
@ConfigurationPropertiesBinding
public WeightConverter weightConverter() {
return new WeightConverter();
}
}

配置自动补全

  • 在书写配置时,可以自动提醒配置信息
  • 依赖
1
2
3
4
5
<dependency>
<groupId>com.springframwork.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
  • 重新build项目,configuration processor会自动生成一个spring-configuration-metadata.json
  • application.properties中写配置就会自动提示
  • 标记属性为deprecated标记原因和替代属性,并重新build
1
2
3
4
5
/** 在getter方法上加注解 */
@DeprecatedConfigurationProperty(reason="change name", replacement = "none")
public String getDefaultSubject() {

}

文章字数:317,阅读全文大约需要1分钟

@Configuration@Bean是Spring中常用的用于配置的Bean的两个注解(将@Bean注解的方法返回的类注入spring)

@Bean

  • 定义

    1
    2
    3
    //用于注解方法和注解的定义
    @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
    @Retention(RetentionPolicy.RUNTIME)
  • 适用范围
    @Bean可作用于组件@Component,该注解及其扩展注解均可使用:
    @Component定义类为组件,并且注入Spring中
    @Repository定义DAO层
    @ServiceService服务层类
    @Controller控制层类
    @Configuration标记这是一个配置Bean的类,通常和@bean一起使用。可以使用类中的其它@Bean注入的bean,其它不行。

  • 作用

    用@Bean注解的方法:会实例化、配置并初始化返回一个新的对象,这个对象会由spring IoC 容器管理。

    1
    2
    3
    4
    5
    6
    7
    @Configuration
    public class AppConfig{
    @Bean
    public MyService myService(){
    return new MyServiceImpl();
    }
    }

    相当于 (beam默认使用注解方法名作为bean的id)

    1
    2
    3
    <beans>
    <bean id="myService" class="com.acme.services.MyServiceImpl">
    </beans>

    给bean起名

    1
    2
    3
    4
    //指定名称
    @Bean(name = "myFoo")
    //指定多个名字
    @Bean(name = { "dataSource", "subsystemA-dataSource", "subsystemB-dataSource" })

@Configuration

@Configuration@Component区别在于@Configuration可以在注入类内依赖的Bean,即上一个方法注入的bean可以被下一个方法获取使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
@Configuration
public class ExampleConfiguration{
@Bean
public DataSource dataSource(){
return new BasicDataSource();
}

@Bean
public PlatformTransactionManager transactionManager(){
//直接调用上面的方法,在@Configuration中是使用上个方法注入的Bean而不是执行方法返回的新对象。
return new DataSourceTransactionManager(dataSource());
}
}

文章字数:216,阅读全文大约需要1分钟

将普通类导入到IOC容器中的注解

导入Bean的方法有

  1. @Bean注解
  2. @Controller @Service @Repository @Component等注解类,使用@ComponentScan扫描包
  3. @Import方法注入(4.2之前只能导入配置类)

常用方式

  • @Enablexxx注解中使用,此注解声明的类在加载之前会加载@inport注解中的类
  • 配合ImportSelector.class接口使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// BeanFactoryAware可以获取beanFactory相关信息
public class MyImportSelector implements ImportSelector, BeanFactoryAware {
private BeanFactory beanFactory;

@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}

@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
// importingClassMetadata可以获取注解所在类的其它注解信息
// 返回最终选择注入的className
return new String[]{XXXClass.class.getName()};
}
}
1
2
3
4
5
6
// 声明注解,并使用MyImportSelector
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.TYPE)
@Import(MyImportSelector.class)
public @interface EnableXXX {}
1
2
3
// 在配置类上使用注解,就能在加载配置类之前加载好选择的类
@EnableXXX
@Configuration

文章字数:24,阅读全文大约需要1分钟

写了个原生,结果报错 Validation failed for query for method public abstract

解决:nativeQuery=true ,jpa默认是hql查询


文章字数:34,阅读全文大约需要1分钟

Could not resolve placeholder ‘xxx’ in value ‘zzz’

找不到key对应的value,需要给value一个默认参数。

1
2
@Value("${some.key:defaultValue}")
private String stringWithDefaultValue;

这样就不会找不到了