TreeSet和TreeMap的一点总结

首先简单介绍下TreeSet和TreeMap的两种排序:

  • 自然排序
  • 通过comparator排序
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    private static void compareWithCpmparator(){
    TreeSet<String> treeSet =new TreeSet<>();
    List<String> list =new ArrayList<>();
    list.add("a");
    list.add("d");
    list.add("b");
    treeSet.addAll(list);
    Iterator<String> iterator =treeSet.iterator();
    while (iterator.hasNext()){
    System.out.println(iterator.next());
    }
    Comparator<String> comparator1 = (Comparator<String>) treeSet.comparator();
    if (comparator1 == null){
    System.out.println("comparator1是空");
    }else {
    System.out.println("comparator1不是空");
    }
    }

    public static void main(String[] args) {
    compareWithCpmparator();
    }
    运行之后的结果如下:
    1
    2
    3
    4
    a
    b
    d
    comparator1是空
    这段代码里面获取的comparator是空的,Debug一遍,发现这个方法其实调用的是NavigableMap里面的comparator
    1
    2
    3
    public Comparator<? super E> comparator() {
    return m.comparator();
    }
    查看官网上对其的介绍:
    1
    2
    3
    4
    Comparator<? super K> comparator()
    Returns the comparator used to order the keys in this map, or null if this map uses the natural ordering of its keys.
    Returns:
    the comparator used to order the keys in this map, or null if this map uses the natural ordering of its keys
    在调用这个方法的时候若是自然排序,那么会返回一个null。若是通过comparator进行排序的话当前集合采用的comparator
    查看官网对reeSet的无参构造器的解释:

    /**

    • Constructs a new, empty tree set, sorted according to the
    • natural ordering of its elements. All elements inserted into
    • the set must implement the {@link Comparable} interface.
    • Furthermore, all such elements must be mutually
    • comparable: {@code e1.compareTo(e2)} must not throw a
    • {@code ClassCastException} for any elements {@code e1} and
    • {@code e2} in the set. If the user attempts to add an element
    • to the set that violates this constraint (for example, the user
    • attempts to add a string element to a set whose elements are
    • integers), the {@code add} call will throw a
    • {@code ClassCastException}.

在使用TreeSet的时候,插入的元素需要实现Comparable这个接口,而刚刚的元素是String,查看String的代码发现:

1
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {

确实实现了,再测试一个没有实现的元素:

阅读更多

Spring Cloud的Zuul相关总结

Zuul是SpringCloud生态体系中的网关一环,首先简单配置如下:
开启注册中心并且配置yml文件,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
spring:
application:
name: somersames-erueka

server:
port: 8081

eureka:
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://localhost:8081/eureka/

开启用户的微服务:

1
2
3
4
5
6
7
8
9
spring:
application:
name: somersames-user
server:
port: 8082
eureka:
client:
service-url:
defaultZone: http://localhost:8081/eureka

编写一个测试的Controller:

阅读更多

线程的interrupt和stop区别,以及线程的中断机制

interrupt

在Java里面线程的中断是一个协作式的,也就是说线程会在自己合适的时候自己中断自己,一般来讲线程如果需要中断的话有如下两种方法:

  • 捕获InterruptException
  • 通过Thread的interrupted()或者isInterrupted()方法,但是需要注意的是interrupted会清除这个线程的状态

当一个线程调用另一个线程的interrupt的时候,另一个线程并不会马上结束,而是会设置一个中断的状态,如果一个线程处于阻塞的状态,那么此时该线程会马上抛出一个InterruptException,由上层的代码进行处理。
若线程没有处于阻塞的话,此时线程还是会执行的。但是线程需要自己在合适的地方通过上述的两个方法来判断自己是否应该中断。如果自己

stop

阅读更多

spring中使用MappingJackson2HttpMessageConverter遇到的一个坑

今天遇到的一个问题就是在Spring中如果继承 WebMvcConfigurerAdapter 然后实现 configureMessageConverters 方法来实现一个 Json 的转换的时候,此时会出现一个情况就是:
如果在Controller里面的那个参数是String的话就会一直提示一个错误 org.springframework.http.converter.HttpMessageNotReadableException","message":"JSON parse error: Can not deserialize instance of java.lang.String out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token\n at [Source: java.io.PushbackInputStream@35b22c23; line: 1, column: 1]","path":"/tetsjson"}
刚开始一直找不出原因,于是在 Spring 源码中 DEBUG :
在如下两处打断点发现是可以获取请求体的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage request, MethodParameter parameter,
Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException {

for (RequestBodyAdvice advice : getMatchingAdvice(parameter, RequestBodyAdvice.class)) {
if (advice.supports(parameter, targetType, converterType)) {
request = advice.beforeBodyRead(request, parameter, targetType, converterType);
}
}
return request;
}


@Override
public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter,
Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {

for (RequestBodyAdvice advice : getMatchingAdvice(parameter, RequestBodyAdvice.class)) {
if (advice.supports(parameter, targetType, converterType)) {
body = advice.afterBodyRead(body, inputMessage, parameter, targetType, converterType);
}
}
return body; // 可以正常解析出请求的body
}

但是一旦加上请求头Content-Type : application/json.在方法进入 beforeBodyRead 里面的 for循环 之后便跳转到了 org.springframework.web.servlet.mvc.method.annotationgetMatchingAdvice() 方法,然后继续走下去发现有一处提示如下:

1
2
3
4
5
6
7
8
9
@Override
public boolean supports(MethodParameter methodParameter, Type targetType,
Class<? extends HttpMessageConverter<?>> converterType) {

// ConverType :"class org.springframework.http.converter.json.MappingJackson2HttpMessgaeConverter"
return (AbstractJackson2HttpMessageConverter.class.isAssignableFrom(converterType) &&
methodParameter.getParameterAnnotation(JsonView.class) != null);
// methodParamter: "method 'XXX' 'Controller方法' paramter 0"
}

阅读更多

Spring Cloud使用ELK日志记录(四)

在ELK的使用过程中,遇到了一点困难, 所以正好写这一篇文章来记录下:

问题一:logstash连接elasticsearch报错

这个问题在这边是由于logstash连接报错,查看了下错误日志发现是由于解析模板出错,后来改了下之后便可以连接了

问题二:kibama可以连接上elasticsearch但是一直读取不了数据

"Couldn't find any Elasticsearch dataYou'll need to index some data into Elasticsearch before you can create an index pattern "
这个问题出现的原因比较复杂,需要仔细排除,不过当出现这个问题的时候可以先看下Elasticsearch 是否含有数据,若是没有数据则添加数据即可。http://localhost:9200/_cat/indices。当这一步没问题了以后,若发现kibana还是无法显示数据则可以在kibana的DevTool里面直接模拟数据。如下:

阅读更多

springcloud的其他组件使用记录之Config(四)

在使用Spring Config的时候遇到一些坑,在这里记录下,顺便梳理下这个使用。

Spring Cloud Config

使用Spring Config来配合git做一个配置文件管理,需要一个Config的服务端和一个Config的客户端,服务端主要是和git仓库进行一个连接,而config的客户端是连接服务端来刷新配置服务的。
在Spring Cloud Config里面客户端需要使用Spring4.0出现的一个注解@Value配合一起使用

Spring Config服务端

需要引入一下几个文件:

阅读更多

springcloud使用feign导致的Excepted authority 错误(三)

今天在用Feign的时候遇到了一个BUG,这个BUG虽然不是很难,但是由于网上没什么解决办法,而是自己的DEBUG解决的,所以暂且记录下:

异常就是java.net.URISyntaxException: Expected authority at index 7: http://,刚开始的时候一头雾水,在Google了一遍之后并未找出解决办法,后来又尝试了在代码中进行了DEBUG,发现代码嵌套的太深了,所以没办法走下去,之后便去StackOverflow中查看了下也没有什么头绪
在这里也检查过了是不是服务没注册还是Feign的注解微服务名称是不是有问题,都显示是正常的,并且可以通过这个名称获取其对应的地址

后来今早起来的时候再次逛StackOverflow看到有人提示try to debug into the LoadBalancerFeignClient.cleanUrl() 。查看了下这个方法的代码:

1
2
3
static URI cleanUrl(String originalUrl, String host) {
return URI.create(originalUrl.replaceFirst(host, ""));
}

猜测了下应该是负责创建Feign相关URL的一个类,所以尝试在这里DEBUG,然后再开启一个正常的可以使用Feign的服务,最后发现这两个服务的区别是,在这个出错的微服务里面发出的请求是http://xxx,而正常的微服务是http://xxx/user/name/XX,所以问题马上就定位出来了,就是请求的问题,

阅读更多

springcloud的服务注册与负载均衡

在springcloud中,服务注册和负载均衡分别是eureka和ribbon。其中eureka是一个服务注册组件,ribbon则是一个负载均衡组件。如果开启了hystrix之后ribbon就默认已经开启了。

Eureka

在使用Eureka的时候服务端开启之后直接在客户端的application.yml中加入如下代码即可:

1
2
3
4
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8083/eureka/

其中defaultZone代表的是服务端的地址,开启服务之后在eureka的服务面板便会看到这个注册信息。如果需要在这个客户端中加入一些元数据的话可以加入如下配置:

阅读更多

SpringCloud初步配置之起步

spring cloud是一个微服务治理框架,主要解决的是以前单应用过于臃肿的一些难点,在这里记录下初次使用springcloud的一些过程

创建一个springboot应用

在这里使用的是IDEA的spring Initializr创建的,创建好了之后将application.properties改成application.yml,其项目结构图如下:

在这里需要注意的是由于在这里的Test文件中含有一个@RunWith注解,所以需要在pom.xml中引入springboot的test包,否则项目可能启动不起来

引入spring cloud包

阅读更多

Mybatis中sql排序以及#和$的区别(二)

mybatis的orderby

在使用mybatis的时候,一般来讲是使用#{}这种方式来设置sql的参数,因为mybatis在解析sql的时候的时候对于使用#{}的参数首先会解析成?,然后再加入参数。具体可以看mybatis的解析日志:

1
2
DEBUG [main] - ==>  Preparing: select * from clazzentity where clazz_name = ? 
DEBUG [main] - ==> Parameters: 一年级(String)

但是在mybatis中如果需要使用groupby和orderby的话就需要注意不可以使用#了,因为使用#的话会导致解析出来的参数自动的带了一个引号,而使用$的话就会直接把参数带进去,所以在进行groupby的时候是需要使用$来进行参数的替换的。但是在使用${}这个的时候需要注意下。

mybatis的多参数和单参数

阅读更多