java-study初次提交
This commit is contained in:
parent
6991fc74a5
commit
778a7ff1ac
16
README.md
Normal file
16
README.md
Normal file
@ -0,0 +1,16 @@
|
||||
## java-study
|
||||
`java-study` 是本人学习过程中记录的一些代码!
|
||||
从Java基础的数据类型、修饰符、String类、IO、集合、线程等等到一些常用框架,Netty、Mina、SpringBoot、kafka、storm、zookeeper、redis、hbase、hive等等。
|
||||
|
||||
|
||||
## 项目结构
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 相关文章
|
||||
|
||||
|
||||
|
||||
|
||||
319
pom.xml
Normal file
319
pom.xml
Normal file
@ -0,0 +1,319 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>1.0.0</groupId>
|
||||
<artifactId>java_study</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>java_study</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
|
||||
|
||||
<dependencies>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!--日志 -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.25</version>
|
||||
</dependency>
|
||||
|
||||
<!-- logback 相关jar -->
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.2.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-core</artifactId>
|
||||
<version>1.2.3</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- 工具包 start -->
|
||||
|
||||
<!--jackson -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.jaxrs</groupId>
|
||||
<artifactId>jackson-jaxrs-json-provider</artifactId>
|
||||
<version>2.9.6</version>
|
||||
</dependency>
|
||||
|
||||
<!-- gson -->
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.5</version>
|
||||
</dependency>
|
||||
|
||||
<!-- fastjson -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.49</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>1.11</version>
|
||||
</dependency>
|
||||
|
||||
<!-- apache 工具包 -->
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
<version>2.6</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.7</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 压缩使用的 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-compress</artifactId>
|
||||
<version>1.18</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
<!--Excel表格 相关jar -->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
<version>3.9</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>3.17</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 二维码工具jar包 -->
|
||||
<dependency>
|
||||
<groupId>com.google.zxing</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>3.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.zxing</groupId>
|
||||
<artifactId>javase</artifactId>
|
||||
<version>3.0.0</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!--pagehelper分页工具类 -->
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper</artifactId>
|
||||
<version>4.1.0</version>
|
||||
</dependency>
|
||||
|
||||
<!--使用lombok 在pojo中可以免去写getter和setter -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.16.18</version>
|
||||
</dependency>
|
||||
|
||||
<!--gecco 爬虫 -->
|
||||
<dependency>
|
||||
<groupId>com.geccocrawler</groupId>
|
||||
<artifactId>gecco</artifactId>
|
||||
<version>1.2.8</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!--protobuf jar -->
|
||||
<dependency>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-java</artifactId>
|
||||
<version>3.5.1</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!--quartz定时器 -->
|
||||
<dependency>
|
||||
<groupId>org.quartz-scheduler</groupId>
|
||||
<artifactId>quartz</artifactId>
|
||||
<version>2.3.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.quartz-scheduler</groupId>
|
||||
<artifactId>quartz-jobs</artifactId>
|
||||
<version>2.3.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 工具包 end -->
|
||||
|
||||
|
||||
|
||||
<!-- 数据库相关jar start -->
|
||||
|
||||
<!--redis 相关jar -->
|
||||
<dependency>
|
||||
<groupId>redis.clients</groupId>
|
||||
<artifactId>jedis</artifactId>
|
||||
<version>2.9.0</version>
|
||||
</dependency>
|
||||
|
||||
<!--mysql驱动包 -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.41</version>
|
||||
</dependency>
|
||||
|
||||
<!--sqlite相关jar -->
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.20.1</version>
|
||||
</dependency>
|
||||
|
||||
<!--SQL Server 驱动包 -->
|
||||
<dependency>
|
||||
<groupId>com.microsoft.sqlserver</groupId>
|
||||
<artifactId>sqljdbc4</artifactId>
|
||||
<version>4.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 数据库相关jar end -->
|
||||
|
||||
|
||||
|
||||
<!-- 通信相关jar start -->
|
||||
|
||||
<!--netty 相关jar -->
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.1.17.Final</version>
|
||||
</dependency>
|
||||
|
||||
<!--mina 相关jar -->
|
||||
<dependency>
|
||||
<groupId>org.apache.mina</groupId>
|
||||
<artifactId>mina-core</artifactId>
|
||||
<version>2.0.16</version>
|
||||
</dependency>
|
||||
|
||||
<!--http相关jar -->
|
||||
<dependency>
|
||||
<groupId>com.github.kevinsawicki</groupId>
|
||||
<artifactId>http-request</artifactId>
|
||||
<version>6.0</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- 通信相关jar end -->
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- 消息中间件 相关jar start -->
|
||||
|
||||
<!--rabbitmq 相关jar -->
|
||||
<dependency>
|
||||
<groupId>com.rabbitmq</groupId>
|
||||
<artifactId>amqp-client</artifactId>
|
||||
<version>4.3.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- kafka -->
|
||||
<dependency>
|
||||
<groupId>org.apache.kafka</groupId>
|
||||
<artifactId>kafka_2.12</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.apache.zookeeper</groupId>
|
||||
<artifactId>zookeeper</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.kafka</groupId>
|
||||
<artifactId>kafka-clients</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.kafka</groupId>
|
||||
<artifactId>kafka-streams</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 消息中间件 相关jar end -->
|
||||
|
||||
|
||||
<!-- 大数据相关 jar start -->
|
||||
|
||||
<!-- zookeeper -->
|
||||
<dependency>
|
||||
<groupId>org.apache.zookeeper</groupId>
|
||||
<artifactId>zookeeper</artifactId>
|
||||
<version>3.4.10</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- zookeeper 工具类 -->
|
||||
<dependency>
|
||||
<groupId>com.101tec</groupId>
|
||||
<artifactId>zkclient</artifactId>
|
||||
<version>0.10</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 大数据相关 jar end -->
|
||||
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
13
src/main/java/com/pancm/App.java
Normal file
13
src/main/java/com/pancm/App.java
Normal file
@ -0,0 +1,13 @@
|
||||
package com.pancm;
|
||||
|
||||
/**
|
||||
* Hello world!
|
||||
*
|
||||
*/
|
||||
public class App
|
||||
{
|
||||
public static void main( String[] args )
|
||||
{
|
||||
System.out.println( "Hello World!" );
|
||||
}
|
||||
}
|
||||
162
src/main/java/com/pancm/arithmetic/PatternMatchingTest.java
Normal file
162
src/main/java/com/pancm/arithmetic/PatternMatchingTest.java
Normal file
@ -0,0 +1,162 @@
|
||||
package com.pancm.arithmetic;
|
||||
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* @Title: PatternMatchingTest
|
||||
* @Description: 模式匹配算法
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年9月14日
|
||||
*/
|
||||
public class PatternMatchingTest {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 暴力匹配
|
||||
* 时间复杂度为O(n*m);n为主串长度,m为模式串长度
|
||||
算法的基本思想:
|
||||
从主串的起始位置(或指定位置)开始与模式串的第一个字符比较,若相等,则继续逐个比较后续字符;
|
||||
否则从主串的下一个字符再重新和模式串的字符比较。
|
||||
依次类推,直到模式串成功匹配,返回主串中第一次出现模式串字符的位置,或者模式串匹配不成功,这里约定返回-1;
|
||||
* @param source
|
||||
* @param pattern
|
||||
* @return
|
||||
*/
|
||||
public static int bruteForceStringMatch(String source, String pattern) {
|
||||
int slen = source.length();
|
||||
int plen = pattern.length();
|
||||
char[] s = source.toCharArray();
|
||||
char[] p = pattern.toCharArray();
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
if (slen < plen)
|
||||
return -1; // 如果主串长度小于模式串,直接返回-1,匹配失败
|
||||
else {
|
||||
while (i < slen && j < plen) {
|
||||
if (s[i] == p[j]) // 如果i,j位置上的字符匹配成功就继续向后匹配
|
||||
{
|
||||
++i;
|
||||
++j;
|
||||
} else {
|
||||
i = i - (j - 1); // i回溯到主串上一次开始匹配下一个位置的地方
|
||||
j = 0; // j重置,模式串从开始再次进行匹配
|
||||
}
|
||||
}
|
||||
if (j == plen) // 匹配成功
|
||||
return i - j;
|
||||
else
|
||||
return -1; // 匹配失败
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* KMP算法
|
||||
KMP算法是D.E.Knuth、V.R.Pratt和J.H.Morris同时发现,所以命名为KMP算法。
|
||||
此算法可以在O(n+m)的时间数量级上完成串的模式匹配。
|
||||
主要就是改进了暴力匹配中i回溯的操作,KMP算法中当一趟匹配过程中出现字符比较不等时,
|
||||
不直接回溯i,而是利用已经得到的“部分匹配”的结果将模式串向右移动(j-next[k])的距离。
|
||||
|
||||
* @param source
|
||||
* @param pattern
|
||||
* @return
|
||||
*/
|
||||
public static int kmpStringMatch(String source, String pattern)
|
||||
{
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
char[] s = source.toCharArray();
|
||||
char[] p = pattern.toCharArray();
|
||||
int slen = s.length;
|
||||
int plen = p.length;
|
||||
int[] next = getNext(p);
|
||||
while(i < slen && j < plen)
|
||||
{
|
||||
if(j == -1 || s[i] == p[j])
|
||||
{
|
||||
++i;
|
||||
++j;
|
||||
}
|
||||
else
|
||||
{
|
||||
//如果j != -1且当前字符匹配失败,则令i不变,
|
||||
//j = next[j],即让pattern模式串右移j - next[j]个单位
|
||||
j = next[j];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(j == plen)
|
||||
return i - j;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 关于next[k]数组的计算引出的两种办法,一种是递归,一种对递归优化,第一种对应的就是KMP算法,第二种就是优化的KMP算法。
|
||||
next函数值仅取决于模式串本身而和主串无关。
|
||||
有很多讲next函数值计算办法的资料,在此我想用一种直观的比较容易理解的办法来表达。
|
||||
举个栗子:现在有一个模式串abab
|
||||
|
||||
模式串的各个字串 前缀 后缀 最大公共元素长度
|
||||
a null null 0
|
||||
ab a b 0
|
||||
aba a,ab a,ba 1
|
||||
abab a,ab,aba b,ab,bab 2
|
||||
* @param p
|
||||
* @return
|
||||
*/
|
||||
private static int[] getNext(char[] p)
|
||||
{
|
||||
/**
|
||||
* 已知next[j] = k, 利用递归的思想求出next[j+1]的值
|
||||
* 1.如果p[j] = p[k],则next[j+1] = next[k] + 1;
|
||||
* 2.如果p[j] != p[k],则令k = next[k],如果此时p[j] == p[k],则next[j+1] = k+1
|
||||
* 如果不相等,则继续递归前缀索引,令k=next[k],继续判断,直至k=-1(即k=next[0])或者p[j]=p[k]为止
|
||||
*/
|
||||
int plen = p.length;
|
||||
int[] next = new int[plen];
|
||||
int k = -1;
|
||||
int j = 0;
|
||||
next[0] = -1; //这里采用-1做标识
|
||||
while(j < plen -1)
|
||||
{
|
||||
if(k == -1 || p[j] == p[k])
|
||||
{
|
||||
++k;
|
||||
++j;
|
||||
next[j] = k;
|
||||
}
|
||||
else
|
||||
{
|
||||
k = next[k];
|
||||
}
|
||||
}
|
||||
System.out.println("next函数值:");
|
||||
for(int ii = 0;ii<next.length;ii++)
|
||||
{
|
||||
|
||||
System.out.print(next[ii]+ " ");
|
||||
}
|
||||
System.out.println();
|
||||
return next;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
public static void main(String[] args) {
|
||||
Scanner sc = new Scanner(System.in);
|
||||
String a = sc.nextLine();
|
||||
String b = sc.nextLine();
|
||||
System.out.println(bruteForceStringMatch(a, b));
|
||||
System.out.println(kmpStringMatch(a, b));
|
||||
}
|
||||
}
|
||||
8
src/main/java/com/pancm/arithmetic/package-info.java
Normal file
8
src/main/java/com/pancm/arithmetic/package-info.java
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @Title: package-info
|
||||
* @Description: 算法相关类
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年9月14日
|
||||
*/
|
||||
package com.pancm.arithmetic;
|
||||
63
src/main/java/com/pancm/basics/AbstractTest.java
Normal file
63
src/main/java/com/pancm/basics/AbstractTest.java
Normal file
@ -0,0 +1,63 @@
|
||||
package com.pancm.basics;
|
||||
|
||||
/**
|
||||
* @author pancm
|
||||
* @Data 2017-6-1
|
||||
* @Description abstract 抽象类测试
|
||||
*/
|
||||
public class AbstractTest {
|
||||
public static void main(String[] args) {
|
||||
// 这句会报错,因为抽象类不能实例化
|
||||
// Animal a=new Animal();
|
||||
Animal a = new Dog();
|
||||
a.show();
|
||||
|
||||
E p = new F();
|
||||
p.show();
|
||||
E q = new G();
|
||||
q.show();
|
||||
|
||||
/*
|
||||
*
|
||||
* 1、抽象类和抽象方法都需要被abstract修饰。抽象方法一定要定义在抽象类中。
|
||||
*
|
||||
* 2、抽象类不可以创建实例,原因:调用抽象方法没有意义。
|
||||
*
|
||||
* 3、只有覆盖了抽象类中所有的抽象方法后,其子类才可以实例化。否则该子类还是一个抽象类。
|
||||
*
|
||||
* 之所以继承,更多的是在思想,是面对共性类型操作会更简单。
|
||||
*
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Animal {
|
||||
abstract void show();
|
||||
|
||||
public void print() {
|
||||
System.out.println("Animal");
|
||||
}
|
||||
}
|
||||
|
||||
class Dog extends Animal {
|
||||
@Override
|
||||
void show() {
|
||||
System.out.println("This is Dog!");
|
||||
}
|
||||
}
|
||||
|
||||
abstract class E {
|
||||
public abstract void show();
|
||||
}
|
||||
|
||||
class F extends E {
|
||||
public void show() {
|
||||
System.out.print("test all FFFF \n");
|
||||
}
|
||||
}
|
||||
|
||||
class G extends E {
|
||||
public void show() {
|
||||
System.out.print("test all GGGG \n");
|
||||
}
|
||||
}
|
||||
224
src/main/java/com/pancm/basics/CloneTest.java
Normal file
224
src/main/java/com/pancm/basics/CloneTest.java
Normal file
@ -0,0 +1,224 @@
|
||||
package com.pancm.basics;
|
||||
|
||||
/**
|
||||
*
|
||||
* @Title: CloneTest
|
||||
* @Description: 克隆测试
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2017-7-24
|
||||
*/
|
||||
public class CloneTest {
|
||||
public static void main(String args[]) {
|
||||
|
||||
/*
|
||||
* 浅拷贝1
|
||||
*/
|
||||
Student stu1 = new Student();
|
||||
stu1.setNumber(12345);
|
||||
Student stu2 = (Student)stu1.clone();
|
||||
|
||||
System.out.println("学生1:" + stu1.getNumber()); //12345
|
||||
System.out.println("学生2:" + stu2.getNumber()); //12345
|
||||
|
||||
stu2.setNumber(54321);
|
||||
//说明拷贝成功
|
||||
System.out.println("学生1:" + stu1.getNumber()); //12345
|
||||
System.out.println("学生2:" + stu2.getNumber()); //54321
|
||||
|
||||
System.out.println(stu1==stu2);//false
|
||||
|
||||
|
||||
/*
|
||||
* 浅拷贝2
|
||||
* 是浅复制只是复制了addr变量的引用,并没有真正的开辟另一块空间,将值复制后再将引用返回给新对象。
|
||||
所以,为了达到真正的复制对象,而不是纯粹引用复制。
|
||||
*/
|
||||
Address addr = new Address();
|
||||
addr.setAdd("杭州市");
|
||||
Student2 student1 = new Student2();
|
||||
student1.setNumber(123);
|
||||
student1.setAddr(addr);
|
||||
Student2 student2 = (Student2)stu1.clone();
|
||||
|
||||
//学生1:123,地址:杭州市
|
||||
System.out.println("学生1:" + student1.getNumber() + ",地址:" + student1.getAddr().getAdd());
|
||||
//学生2:123,地址:杭州市
|
||||
System.out.println("学生2:" + student2.getNumber() + ",地址:" + student2.getAddr().getAdd());
|
||||
|
||||
addr.setAdd("深圳市");
|
||||
//学生1:123,地址:深圳市
|
||||
System.out.println("学生1:" + student1.getNumber() + ",地址:" + student1.getAddr().getAdd());
|
||||
//学生1:123,地址:深圳市
|
||||
System.out.println("学生2:" + student2.getNumber() + ",地址:" + student2.getAddr().getAdd());
|
||||
|
||||
|
||||
/*
|
||||
* 浅克隆3
|
||||
* 是浅复制只是复制了addr变量的引用,并没有真正的开辟另一块空间,将值复制后再将引用返回给新对象。
|
||||
所以,为了达到真正的复制对象,而不是纯粹引用复制。
|
||||
*/
|
||||
Address3 addr3 = new Address3();
|
||||
addr.setAdd("杭州市");
|
||||
Student3 st1 = new Student3();
|
||||
st1.setNumber(123);
|
||||
st1.setAddr(addr3);
|
||||
Student3 st2 = (Student3)stu1.clone();
|
||||
|
||||
//学生1:123,地址:杭州市
|
||||
System.out.println("学生1:" + st1.getNumber() + ",地址:" + st1.getAddr().getAdd());
|
||||
//学生2:123,地址:杭州市
|
||||
System.out.println("学生2:" + st2.getNumber() + ",地址:" + st2.getAddr().getAdd());
|
||||
|
||||
addr3.setAdd("武汉市");
|
||||
//学生1:123,地址:武汉市
|
||||
System.out.println("学生1:" + st1.getNumber() + ",地址:" + st1.getAddr().getAdd());
|
||||
//学生1:123,地址:杭州市
|
||||
System.out.println("学生2:" + st2.getNumber() + ",地址:" + st2.getAddr().getAdd());
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 浅克隆1
|
||||
*/
|
||||
//被复制的类需要实现Cloneable接口 重写Object方法
|
||||
class Student implements Cloneable{
|
||||
private int number;
|
||||
|
||||
public int getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public void setNumber(int number) {
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
Student stu = null;
|
||||
try{
|
||||
stu = (Student)super.clone();
|
||||
}catch(CloneNotSupportedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return stu;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* 浅克隆2
|
||||
*/
|
||||
//该对象不继承Cloneable
|
||||
class Address {
|
||||
private String add;
|
||||
|
||||
public String getAdd() {
|
||||
return add;
|
||||
}
|
||||
|
||||
public void setAdd(String add) {
|
||||
this.add = add;
|
||||
}
|
||||
}
|
||||
|
||||
//此对象依旧继承 Cloneable
|
||||
class Student2 implements Cloneable{
|
||||
private int number;
|
||||
|
||||
private Address addr;
|
||||
|
||||
public Address getAddr() {
|
||||
return addr;
|
||||
}
|
||||
|
||||
public void setAddr(Address addr) {
|
||||
this.addr = addr;
|
||||
}
|
||||
|
||||
public int getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public void setNumber(int number) {
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
Student2 stu = null;
|
||||
try{
|
||||
stu = (Student2)super.clone();
|
||||
}catch(CloneNotSupportedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return stu;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 浅克隆3
|
||||
*/
|
||||
//该对象继承Cloneable
|
||||
class Address3 implements Cloneable {
|
||||
private String add;
|
||||
public String getAdd() {
|
||||
return add;
|
||||
}
|
||||
|
||||
public void setAdd(String add) {
|
||||
this.add = add;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone(){
|
||||
Address3 addr=null;
|
||||
try{
|
||||
addr=(Address3)super.clone();
|
||||
}catch(CloneNotSupportedException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
|
||||
//此对象依旧继承 Cloneable
|
||||
class Student3 implements Cloneable{
|
||||
private int number;
|
||||
|
||||
private Address3 addr;
|
||||
|
||||
public Address3 getAddr() {
|
||||
return addr;
|
||||
}
|
||||
|
||||
public void setAddr(Address3 addr) {
|
||||
this.addr = addr;
|
||||
}
|
||||
|
||||
public int getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public void setNumber(int number) {
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
Student3 stu = null;
|
||||
try{
|
||||
stu = (Student3)super.clone(); //浅复制
|
||||
}catch(CloneNotSupportedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
stu.addr = (Address3)addr.clone(); //深度复制
|
||||
return stu;
|
||||
}
|
||||
}
|
||||
|
||||
55
src/main/java/com/pancm/basics/ExtendsTest.java
Normal file
55
src/main/java/com/pancm/basics/ExtendsTest.java
Normal file
@ -0,0 +1,55 @@
|
||||
package com.pancm.basics;
|
||||
/**
|
||||
* @author ZERO
|
||||
* @Data 2017-6-2 上午11:46:45
|
||||
* @Description 继承测试 经典题
|
||||
*/
|
||||
public class ExtendsTest {
|
||||
public static void main(String[] args) {
|
||||
A a1 = new A();
|
||||
A a2 = new B();
|
||||
B b = new B();
|
||||
C c = new C();
|
||||
D d = new D();
|
||||
|
||||
System.out.println("1--" + a1.show(b)); //A and A
|
||||
System.out.println("2--" + a1.show(c)); //A and A
|
||||
System.out.println("3--" + a1.show(d)); //A and D
|
||||
System.out.println("4--" + a2.show(b)); //B and A
|
||||
System.out.println("5--" + a2.show(c)); //B and A
|
||||
System.out.println("6--" + a2.show(d)); //A and D
|
||||
System.out.println("7--" + b.show(b)); //B and B
|
||||
System.out.println("8--" + b.show(c)); //B and B
|
||||
System.out.println("9--" + b.show(d)); //A and D
|
||||
}
|
||||
}
|
||||
|
||||
class A {
|
||||
public String show(D obj) {
|
||||
return ("A and D");
|
||||
}
|
||||
|
||||
public String show(A obj) {
|
||||
return ("A and A");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class B extends A{
|
||||
public String show(B obj){
|
||||
return ("B and B");
|
||||
}
|
||||
|
||||
public String show(A obj){
|
||||
return ("B and A");
|
||||
}
|
||||
}
|
||||
|
||||
class C extends B{
|
||||
|
||||
}
|
||||
|
||||
class D extends B{
|
||||
|
||||
}
|
||||
|
||||
54
src/main/java/com/pancm/basics/ForTest.java
Normal file
54
src/main/java/com/pancm/basics/ForTest.java
Normal file
@ -0,0 +1,54 @@
|
||||
package com.pancm.basics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @Title: ForTest
|
||||
* @Description: 循环测试
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2017年9月29日
|
||||
*/
|
||||
public class ForTest {
|
||||
public static void main(String[] args) {
|
||||
/*
|
||||
* 阿里巴巴开发手册中的遍历移除测试
|
||||
*/
|
||||
iteratorTest();
|
||||
forEachTest();
|
||||
}
|
||||
private static void forEachTest(){
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add("1");
|
||||
list.add("2");
|
||||
System.out.println("list1:"+list);
|
||||
for (String item : list) {
|
||||
//如果是1就不会出现
|
||||
if ("2".equals(item)) {
|
||||
list.remove(item);
|
||||
//加上break就不会抛异常
|
||||
// break;
|
||||
}
|
||||
}
|
||||
System.out.println("list2:"+list);
|
||||
}
|
||||
private static void iteratorTest(){
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add("1");
|
||||
list.add("2");
|
||||
System.out.println("list3:"+list);
|
||||
Iterator<String> iterator = list.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
String item = iterator.next();
|
||||
if ("2".equals(item)) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
System.out.println("list4:"+list);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
234
src/main/java/com/pancm/basics/IoTest.java
Normal file
234
src/main/java/com/pancm/basics/IoTest.java
Normal file
@ -0,0 +1,234 @@
|
||||
package com.pancm.basics;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @Title: IoTest
|
||||
* @Description:
|
||||
* io字符流和字节流测试
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年6月11日
|
||||
*/
|
||||
public class IoTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
// test();
|
||||
// test2();
|
||||
// test3();
|
||||
// test4();
|
||||
// test5();
|
||||
// test6();
|
||||
test7();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 字符流
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void test() throws IOException {
|
||||
String str;
|
||||
// 使用 System.in 创建 BufferedReader
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
|
||||
System.out.println("输入字符, 输入 'quit' 退出。");
|
||||
// 读取字符
|
||||
do {
|
||||
str=br.readLine();
|
||||
System.out.println("您输入的字符是:"+str);
|
||||
} while(!str.equals("quit"));
|
||||
br.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* 字节流
|
||||
* 创建一个文件并新增一条记录
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void test2() throws IOException {
|
||||
String path="E:/test/hello.txt";
|
||||
String str="hello world";
|
||||
//创建一个文件并向文件中写数据 需要文件夹存在
|
||||
OutputStream output = new FileOutputStream(path);
|
||||
output.write(str.getBytes());
|
||||
output.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入和读取文件
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void test3() throws IOException {
|
||||
//创建要操作的文件路径和名称
|
||||
String path ="E:/test/hello.txt";
|
||||
String str="你好!";
|
||||
FileWriter fw = new FileWriter(path);
|
||||
BufferedWriter bw=new BufferedWriter(fw);
|
||||
bw.write(str);
|
||||
bw.close();
|
||||
fw.close();
|
||||
|
||||
FileReader fr = new FileReader(path);
|
||||
BufferedReader br=new BufferedReader(fr);
|
||||
StringBuffer sb=new StringBuffer();
|
||||
while(br.ready()){
|
||||
sb.append((char)br.read());
|
||||
}
|
||||
System.out.println("输出:"+sb.toString());
|
||||
br.close();
|
||||
fr.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 字节流
|
||||
* 创建一个文件并读取记录 防止乱码
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void test4() throws IOException {
|
||||
String path="E:/test/hello.txt";
|
||||
String path2="E:/test/你好.txt";
|
||||
String str="你好!";
|
||||
//从文件读取数据
|
||||
InputStream input = new FileInputStream(path);
|
||||
InputStreamReader reader = new InputStreamReader(input, "UTF-8");
|
||||
StringBuffer sb=new StringBuffer();
|
||||
while(reader.ready()){
|
||||
sb.append((char)reader.read());
|
||||
}
|
||||
|
||||
input.close();
|
||||
reader.close();
|
||||
|
||||
//创建一个文件并向文件中写数据
|
||||
OutputStream output = new FileOutputStream(path2);
|
||||
OutputStreamWriter writer = new OutputStreamWriter(output, "UTF-8");
|
||||
writer.write(sb+str);
|
||||
|
||||
writer.close();
|
||||
output.close();
|
||||
|
||||
//从文件读取数据
|
||||
InputStream input2 = new FileInputStream(path2);
|
||||
InputStreamReader reader2 = new InputStreamReader(input2, "UTF-8");
|
||||
StringBuffer sb2=new StringBuffer();
|
||||
while(reader2.ready()){
|
||||
sb2.append((char)reader2.read());
|
||||
}
|
||||
System.out.println("输出:"+sb2);
|
||||
input2.close();
|
||||
reader2.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 字符流
|
||||
* 写入和读取文件
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void test6() throws IOException {
|
||||
//创建要操作的文件路径和名称
|
||||
//其中,File.separator表示系统相关的分隔符,Linux下为:/ Windows下为:\\
|
||||
String path ="E:/test2/hello.txt";
|
||||
String str="hello world";
|
||||
FileWriter fw = new FileWriter(path);
|
||||
//以path为路径创建一个新的FileWriter对象
|
||||
//如果需要追加数据,而不是覆盖,则使用FileWriter(path,true)构造方法
|
||||
//将字符串写入到流中,\r\n表示换行想有好的
|
||||
fw.write(str);
|
||||
fw.close();
|
||||
|
||||
FileReader fr = new FileReader(path);
|
||||
StringBuffer sb=new StringBuffer();
|
||||
while(fr.ready()){
|
||||
sb.append((char)fr.read());
|
||||
}
|
||||
System.out.println("输出:"+sb.toString());
|
||||
fr.close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 字符流
|
||||
* 写入和读取文件
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void test7() throws IOException {
|
||||
//创建要操作的文件路径和名称
|
||||
String path ="E:/test2/hello.txt";
|
||||
Properties prop=new Properties();
|
||||
prop.setProperty("name", "zz");
|
||||
FileWriter fw = new FileWriter(path);
|
||||
BufferedWriter bw=new BufferedWriter(fw);
|
||||
bw.write(prop.toString());
|
||||
bw.close();
|
||||
fw.close();
|
||||
|
||||
FileReader fr = new FileReader(path);
|
||||
BufferedReader br=new BufferedReader(fr);
|
||||
StringBuffer sb=new StringBuffer();
|
||||
while(br.ready()){
|
||||
sb.append((char)br.read());
|
||||
}
|
||||
System.out.println("输出:"+sb.toString());
|
||||
br.close();
|
||||
fr.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 新建文件夹和文件
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void test5() throws IOException {
|
||||
String path="E:/test/test2";
|
||||
String path2="E:/test/test3/test3";
|
||||
String path3="E:/test/test2/test2.txt";
|
||||
File f = new File(path);
|
||||
File f2 = new File(path2);
|
||||
File f3 = new File(path3);
|
||||
//创建文件夹
|
||||
System.out.println("="+f.mkdir());
|
||||
//创建文件夹和所有父文件夹
|
||||
System.out.println("=="+f2.mkdirs());
|
||||
//创建一个文本
|
||||
System.out.println("==="+f3.createNewFile());
|
||||
//获取名称
|
||||
System.out.println("==="+f3.getName());
|
||||
//获取父级名称
|
||||
System.out.println("==="+f3.getParent());
|
||||
//获取当前路径
|
||||
System.out.println("==="+f3.getPath());
|
||||
//判断是否是目录
|
||||
System.out.println("=="+f2.isDirectory());
|
||||
System.out.println("==="+f3.isDirectory());
|
||||
//删除该文件
|
||||
System.out.println("==="+f3.delete());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
292
src/main/java/com/pancm/basics/ListTest.java
Normal file
292
src/main/java/com/pancm/basics/ListTest.java
Normal file
@ -0,0 +1,292 @@
|
||||
package com.pancm.basics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
*
|
||||
* @Title: ListTest
|
||||
* @Description:关于list测试
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2017年10月13日
|
||||
*/
|
||||
public class ListTest {
|
||||
|
||||
private final static int count=50000;
|
||||
|
||||
private static ArrayList arrayList = new ArrayList<>();
|
||||
private static LinkedList linkedList = new LinkedList<>();
|
||||
private static Vector vector = new Vector<>();
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
// test1();
|
||||
// test2();
|
||||
// test3();
|
||||
test4();
|
||||
// test5();
|
||||
|
||||
Vector<String> v=new Vector<>();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 遍历方法
|
||||
*/
|
||||
private static void test1() {
|
||||
List<String> list=new ArrayList<String>();
|
||||
list.add("a");
|
||||
list.add("b");
|
||||
list.add("c");
|
||||
|
||||
System.out.println("list截取:"+list.subList(0, 1));
|
||||
System.out.println("list截取:"+list.subList(1, 3));
|
||||
|
||||
|
||||
//第一种使用
|
||||
for(int i=0;i<list.size();i++){
|
||||
System.out.println(list.get(i));
|
||||
}
|
||||
//第二种遍历方法使用foreach遍历List
|
||||
for (String str : list) {
|
||||
System.out.println(str);
|
||||
}
|
||||
|
||||
//第三种遍历 使用迭代器进行相关遍历
|
||||
Iterator<String> iterator=list.iterator();
|
||||
while(iterator.hasNext())//判断下一个元素之后有值
|
||||
{
|
||||
System.out.println(iterator.next());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 数组变化遍历
|
||||
*/
|
||||
private static void test2() {
|
||||
|
||||
List<String> list1 = new ArrayList<String>();
|
||||
list1.add("1");
|
||||
list1.add("2");
|
||||
System.out.println("list1遍历之前:"+list1);
|
||||
Iterator<String> iterator = list1.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
String item = iterator.next();
|
||||
if ("2".equals(item)) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
System.out.println("list1遍历之后:"+list1);
|
||||
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add("1");
|
||||
list.add("2");
|
||||
System.out.println("list遍历之前:"+list);
|
||||
for (String item : list) {
|
||||
if ("2".equals(item)) {
|
||||
list.remove(item);
|
||||
//如果这里不适用break的话,会直接报错的
|
||||
break;
|
||||
}
|
||||
}
|
||||
System.out.println("list遍历之后:"+list);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 常用方法
|
||||
*/
|
||||
private static void test3() {
|
||||
List<Integer> list=initData(100);
|
||||
System.out.println("list:"+list);
|
||||
System.out.println("removeList:"+removeList(list,10,20));
|
||||
list.subList(10, 20).clear();
|
||||
System.out.println("subList:"+list);
|
||||
|
||||
List<String> ls1=new ArrayList<String>();
|
||||
List<String> ls2=new ArrayList<String>();
|
||||
ls1.add("a");
|
||||
ls1.add("b");
|
||||
ls1.add("c");
|
||||
ls2.add("a");
|
||||
ls2.add("d");
|
||||
ls2.add("e");
|
||||
// System.out.println("合集:"+addAll(ls1,ls2));
|
||||
System.out.println("交集 :"+retainAll(ls1,ls2));
|
||||
System.out.println("差集 :"+removeAll(ls1,ls2));
|
||||
System.out.println("并集 :"+andAll(ls1,ls2));
|
||||
|
||||
}
|
||||
|
||||
private static void test4() {
|
||||
LinkedList<Integer> list=new LinkedList<Integer>();
|
||||
list.add(3);
|
||||
list.add(5);
|
||||
list.add(4);
|
||||
System.out.println(list);
|
||||
list.addFirst(2);
|
||||
list.addLast(4);
|
||||
System.out.println(list);
|
||||
|
||||
LinkedList<Integer> list2=new LinkedList<Integer>();
|
||||
list2.add(1);
|
||||
list2.add(2);
|
||||
list2.add(4);
|
||||
list2.add(4);
|
||||
list2.add(6);
|
||||
list2.add(6);
|
||||
list2.add(5);
|
||||
System.out.println("去重之前:"+list2);
|
||||
//jdk1.8去重
|
||||
List<Integer> newList = list2.stream().distinct().collect(Collectors.toList());
|
||||
System.out.println("去重之后:"+newList);
|
||||
|
||||
}
|
||||
|
||||
private static void test5() {
|
||||
insertList(arrayList);
|
||||
insertList(linkedList);
|
||||
insertList(vector);
|
||||
|
||||
System.out.println("--------------------");
|
||||
|
||||
readList(arrayList);
|
||||
readList(linkedList);
|
||||
readList(vector);
|
||||
|
||||
System.out.println("--------------------");
|
||||
|
||||
delList(arrayList);
|
||||
delList(linkedList);
|
||||
delList(vector);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static void insertList(List list){
|
||||
long start=System.currentTimeMillis();
|
||||
Object o = new Object();
|
||||
for(int i=0;i<count;i++){
|
||||
list.add(0, o);
|
||||
}
|
||||
System.out.println(getName(list)+"插入"+count+"条数据,耗时:"+(System.currentTimeMillis()-start)+"ms");
|
||||
}
|
||||
|
||||
private static void readList(List list){
|
||||
long start=System.currentTimeMillis();
|
||||
Object o = new Object();
|
||||
for(int i = 0 ; i < count ; i++){
|
||||
list.get(i);
|
||||
}
|
||||
System.out.println(getName(list)+"查询"+count+"条数据,耗时:"+(System.currentTimeMillis()-start)+"ms");
|
||||
}
|
||||
|
||||
|
||||
private static void delList(List list){
|
||||
long start=System.currentTimeMillis();
|
||||
Object o = new Object();
|
||||
for(int i = 0 ; i < count ; i++){
|
||||
list.remove(0);
|
||||
}
|
||||
System.out.println(getName(list)+"删除"+count+"条数据,耗时:"+(System.currentTimeMillis()-start)+"ms");
|
||||
}
|
||||
|
||||
private static String getName(List list) {
|
||||
String name = "";
|
||||
if(list instanceof ArrayList){
|
||||
name = "ArrayList";
|
||||
}
|
||||
else if(list instanceof LinkedList){
|
||||
name = "LinkedList";
|
||||
}
|
||||
else if(list instanceof Vector){
|
||||
name = "Vector";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* for循环移除指定数据
|
||||
* @param list
|
||||
* @param s 要移除的起始位置
|
||||
* @param d 要移除的最后位置
|
||||
*/
|
||||
private static List<Integer> removeList(List<Integer> list,int s,int d){
|
||||
for(int i=0,j=list.size();i<j;i++){
|
||||
if(i>=s&&i<d){
|
||||
list.remove(i);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数组数据
|
||||
* @param j
|
||||
* @return
|
||||
*/
|
||||
private static List<Integer> initData(int j){
|
||||
List<Integer> list=new ArrayList<Integer>();
|
||||
for(int i=1;i<=j;i++){
|
||||
list.add(i);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数组合集
|
||||
* @param ls1
|
||||
* @param ls2
|
||||
* @return
|
||||
*/
|
||||
private static List<String> addAll(List<String> ls1,List<String>ls2){
|
||||
ls1.addAll(ls2);
|
||||
return ls1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数组交集 (retainAll 会删除 ls1在ls2中没有的元素)
|
||||
* @param ls1
|
||||
* @param ls2
|
||||
* @return
|
||||
*/
|
||||
private static List<String> retainAll(List<String> ls1,List<String>ls2){
|
||||
System.out.println("ls1:"+ls1+";ls2:"+ls2);
|
||||
ls1.retainAll(ls2);
|
||||
return ls1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 差集 (删除ls2中没有ls1中的元素)
|
||||
* @param ls1
|
||||
* @param ls2
|
||||
* @return
|
||||
*/
|
||||
private static List<String> removeAll(List<String> ls1,List<String>ls2){
|
||||
ls1.removeAll(ls2);
|
||||
System.out.println(ls1+";ls2:"+ls2);
|
||||
return ls1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 无重复的并集 (ls1和ls2中并集,并无重复)
|
||||
* @param ls1
|
||||
* @param ls2
|
||||
* @return
|
||||
*/
|
||||
private static List<String> andAll(List<String> ls1,List<String>ls2){
|
||||
//删除在ls1中出现的元素
|
||||
ls2.removeAll(ls1);
|
||||
//将剩余的ls2中的元素添加到ls1中
|
||||
ls1.addAll(ls2);
|
||||
System.out.println(ls1+";ls2:"+ls2);
|
||||
return ls1;
|
||||
}
|
||||
}
|
||||
124
src/main/java/com/pancm/basics/MapTest.java
Normal file
124
src/main/java/com/pancm/basics/MapTest.java
Normal file
@ -0,0 +1,124 @@
|
||||
package com.pancm.basics;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
*
|
||||
* Title: MapTest
|
||||
* Description:集合map测试
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2017年11月16日
|
||||
*/
|
||||
public class MapTest {
|
||||
private static Map<String,String> map = new HashMap<String,String>();
|
||||
|
||||
public static Map<String,String> getHashMap(){
|
||||
if(map == null || map.isEmpty()){
|
||||
map = new HashMap<String,String>();
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
//普通的HashMap
|
||||
// Map<String,String> map=mapTest.getHashMap();
|
||||
// map.put("a", "1");
|
||||
// map.put("b", "1");
|
||||
// map.put("c", "e");
|
||||
// System.out.println(map.toString());
|
||||
// Map<String,String> map1=mapTest.getHashMap();
|
||||
// System.out.println("-----"+map1.get("a"));
|
||||
|
||||
//上锁的HashMap
|
||||
// Map<String,String> sMap=Collections.synchronizedMap(new HashMap());
|
||||
|
||||
// getMap1();
|
||||
|
||||
test1();
|
||||
test2();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void test1() {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("1", "value1");
|
||||
map.put("2", "value2");
|
||||
map.put("3", "value3");
|
||||
//第一种:普遍使用,二次取值
|
||||
System.out.println("通过Map.keySet遍历key和value:");
|
||||
for (String key : map.keySet()) {
|
||||
System.out.println("key= "+ key + " and value= " + map.get(key));
|
||||
}
|
||||
|
||||
//第二种 使用迭代器Iterator进行遍历
|
||||
System.out.println("通过Map.entrySet使用iterator遍历key和value:");
|
||||
Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry<String, String> entry = it.next();
|
||||
System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
|
||||
}
|
||||
|
||||
//第三种:使用entrySet遍历 推荐,尤其是容量大时
|
||||
System.out.println("通过Map.entrySet遍历key和value");
|
||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||
System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private static void test2() {
|
||||
Map<String,Object> hashMap=new HashMap<String,Object>();
|
||||
hashMap.put("a", 1);
|
||||
hashMap.put("c", 3);
|
||||
hashMap.put("b", 2);
|
||||
System.out.println("HashMap:"+hashMap);
|
||||
|
||||
Map<String,Object> treeMap=new TreeMap<String,Object>();
|
||||
treeMap.put("a", 1);
|
||||
treeMap.put("c", 3);
|
||||
treeMap.put("b", 2);
|
||||
System.out.println("TreeMap:"+treeMap);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private static void getMap1(){
|
||||
Map<Integer,Integer> map1 =new HashMap<Integer,Integer>();
|
||||
Map<Integer,Integer> map2 =new HashMap<Integer,Integer>();
|
||||
map1.put(1, 1);
|
||||
map1.put(2, 2);
|
||||
map1.put(3, 3);
|
||||
map2.put(11, 11);
|
||||
map2.put(22, 22);
|
||||
map2.put(33, 33);
|
||||
Map<Integer,Map<Integer,Integer>> map3 =new HashMap<Integer,Map<Integer,Integer>>();
|
||||
map3.put(1, map1);
|
||||
map3.put(2, map2);
|
||||
|
||||
System.out.println("map3:"+map3);
|
||||
StringBuffer sb=new StringBuffer();
|
||||
for(Entry<Integer,Map<Integer,Integer>> entry:map3.entrySet()){
|
||||
sb.append(entry.getKey());
|
||||
sb.append(":");
|
||||
Map<Integer,Integer> map4=entry.getValue();
|
||||
for(Entry<Integer,Integer> entry1:map4.entrySet()){
|
||||
sb.append(entry1.getKey());
|
||||
sb.append("_");
|
||||
sb.append(entry1.getValue());
|
||||
sb.append(",");
|
||||
}
|
||||
|
||||
}
|
||||
sb.deleteCharAt(sb.lastIndexOf(","));
|
||||
System.out.println("sb:"+sb);
|
||||
}
|
||||
}
|
||||
311
src/main/java/com/pancm/basics/SetTest.java
Normal file
311
src/main/java/com/pancm/basics/SetTest.java
Normal file
@ -0,0 +1,311 @@
|
||||
package com.pancm.basics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @Title: setTest
|
||||
* @Description: 重写set中的equals和hashcode
|
||||
* @Version:1.0.0
|
||||
* @author panchengming
|
||||
* @date 2017年9月17日
|
||||
*/
|
||||
public class SetTest {
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
Set hashSet = new HashSet();
|
||||
Set treeSet = new TreeSet();
|
||||
Set linkedSet = new LinkedHashSet();
|
||||
|
||||
|
||||
set();
|
||||
hashSetTest();
|
||||
treeSet1();
|
||||
treeSet2();
|
||||
}
|
||||
|
||||
/**
|
||||
* set去重
|
||||
*/
|
||||
public static void set(){
|
||||
// 初始化list
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add("Jhon");
|
||||
list.add("Jency");
|
||||
list.add("Mike");
|
||||
list.add("Dmitri");
|
||||
list.add("Mike");
|
||||
// 利用set不允许元素重复的性质去掉相同的元素
|
||||
Set<String> set = new HashSet<String>();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
String items = list.get(i);
|
||||
System.out.println("items:"+items);
|
||||
if (!set.add(items)) {
|
||||
// 打印重复的元素
|
||||
System.out.println("重复的数据: " + items);
|
||||
}
|
||||
}
|
||||
System.out.println("list:"+list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用hashSet去重
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public static void hashSetTest(){
|
||||
HashSet hs = new HashSet();
|
||||
// TreeMap tm=new TreeMap();
|
||||
hs.add(new AA("ABC", 20));
|
||||
hs.add(new AA("BCD", 20));
|
||||
hs.add(new AA("CDE", 20));
|
||||
hs.add(new AA("ABC", 20));
|
||||
hs.add(new AA("BCD", 20));
|
||||
Iterator it = hs.iterator(); //定义迭代器
|
||||
while (it.hasNext()) {
|
||||
Object next = it.next();
|
||||
System.out.println("排序之前:"+next);
|
||||
// Entry<String, Object> me=(Entry<String, Object>) it.next();
|
||||
// tm.put(me.getKey(), me.getValue());
|
||||
}
|
||||
// System.out.println("TreeMap排序之后:"+tm);
|
||||
}
|
||||
|
||||
/**
|
||||
* 一,让容器自身具备比较性,自定义比较器。
|
||||
需求:当元素自身不具备比较性,或者元素自身具备的比较性不是所需的。
|
||||
那么这时只能让容器自身具备。
|
||||
定义一个类实现Comparator 接口,覆盖compare方法。
|
||||
并将该接口的子类对象作为参数传递给TreeSet集合的构造函数。
|
||||
当Comparable比较方式,及Comparator比较方式同时存在,以Comparator
|
||||
比较方式为主
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public static void treeSet1(){
|
||||
TreeSet ts = new TreeSet(new MyComparator());
|
||||
ts.add(new Book("think in java", 100));
|
||||
ts.add(new Book("java 核心技术", 75));
|
||||
ts.add(new Book("现代操作系统", 50));
|
||||
ts.add(new Book("java就业教程", 35));
|
||||
ts.add(new Book("think in java", 100));
|
||||
ts.add(new Book("ccc in java", 100));
|
||||
|
||||
System.out.println("treeSet1:"+ts);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
二,让元素自身具备比较性。
|
||||
也就是元素需要实现Comparable接口,覆盖compareTo 方法。
|
||||
这种方式也作为元素的自然排序,也可称为默认排序。
|
||||
年龄按照搜要条件,年龄相同再比姓名。
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public static void treeSet2(){
|
||||
TreeSet ts = new TreeSet();
|
||||
ts.add(new Person("aa", 20, "男"));
|
||||
ts.add(new Person("bb", 18, "女"));
|
||||
ts.add(new Person("cc", 17, "男"));
|
||||
ts.add(new Person("dd", 17, "女"));
|
||||
ts.add(new Person("dd", 15, "女"));
|
||||
ts.add(new Person("dd", 15, "女"));
|
||||
|
||||
System.out.println("treeSet2:"+ts);
|
||||
System.out.println(ts.size()); // 5
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class AA{
|
||||
private String name;
|
||||
private int age;
|
||||
|
||||
public AA(String name, int age) {
|
||||
this.name=name;
|
||||
this.age=age;
|
||||
}
|
||||
|
||||
AA() {
|
||||
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
//重写hashCode
|
||||
@Override
|
||||
public int hashCode() {
|
||||
System.out.println("hashCode:" + this.name);
|
||||
return this.name.hashCode() + age * 37;
|
||||
}
|
||||
|
||||
//重写equals
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof AA) {
|
||||
AA a = (AA) obj;
|
||||
return this.name.equals(a.name) && this.age == a.age;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "姓名:" + this.name + " 年龄:" + this.age;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
class Person implements Comparable {
|
||||
private String name;
|
||||
private int age;
|
||||
private String gender; //性别
|
||||
|
||||
public Person() {
|
||||
}
|
||||
|
||||
public Person(String name, int age, String gender) {
|
||||
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
this.gender = gender;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public String getGender() {
|
||||
return gender;
|
||||
}
|
||||
|
||||
public void setGender(String gender) {
|
||||
this.gender = gender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return name.hashCode() + age * 37;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
System.err.println(this + "equals :" + obj);
|
||||
if (!(obj instanceof Person)) {
|
||||
return false;
|
||||
}
|
||||
Person p = (Person) obj;
|
||||
return this.name.equals(p.name) && this.age == p.age;
|
||||
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Person [name=" + name + ", age=" + age + ", gender=" + gender
|
||||
+ "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Object obj) {
|
||||
Person p = (Person) obj;
|
||||
System.out.println(this+" compareTo:"+p);
|
||||
if (this.age > p.age) {
|
||||
return 1;
|
||||
}
|
||||
if (this.age < p.age) {
|
||||
return -1;
|
||||
}
|
||||
return this.name.compareTo(p.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
class MyComparator implements Comparator {
|
||||
|
||||
public int compare(Object o1, Object o2) {
|
||||
Book b1 = (Book) o1;
|
||||
Book b2 = (Book) o2;
|
||||
System.out.println(b1+" comparator "+b2);
|
||||
if (b1.getPrice() > b2.getPrice()) {
|
||||
return 1;
|
||||
}
|
||||
if (b1.getPrice() < b2.getPrice()) {
|
||||
return -1;
|
||||
}
|
||||
return b1.getName().compareTo(b2.getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Book {
|
||||
private String name;
|
||||
private double price;
|
||||
|
||||
public Book() {
|
||||
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public double getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(double price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public Book(String name, double price) {
|
||||
|
||||
this.name = name;
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Book [name=" + name + ", price=" + price + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
186
src/main/java/com/pancm/basics/SocketTest.java
Normal file
186
src/main/java/com/pancm/basics/SocketTest.java
Normal file
@ -0,0 +1,186 @@
|
||||
package com.pancm.basics;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.Selector;
|
||||
import java.nio.channels.ServerSocketChannel;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @Title: SocketTest
|
||||
* @Description:Socket测试
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2017年11月16日
|
||||
*/
|
||||
public class SocketTest {
|
||||
/** 端口 */
|
||||
private static final int portNumber = 6789;
|
||||
|
||||
private static String request = null;
|
||||
private static String response = null;
|
||||
|
||||
public static void main(String[] args) {
|
||||
request = "Hello";
|
||||
socketTest(request);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* socket简单连接测试
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
private static void socketTest(String request) {
|
||||
try {
|
||||
// 创建一个新的 ServerSocket, 用 以监听指定端口上的连接请求
|
||||
ServerSocket serverSocket = new ServerSocket(portNumber);
|
||||
// 对 accept()方法的调用将被阻塞,直到一个连接建立
|
||||
Socket clientSocket = serverSocket.accept();
|
||||
// 这些流对象都派生于该套接字的流对象
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(
|
||||
clientSocket.getInputStream()));
|
||||
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),
|
||||
true);
|
||||
// 循环处理开始
|
||||
while ((request = in.readLine()) != null) {
|
||||
// 如果客户端发送了“Done”,则退出处理循环
|
||||
if ("Done".equals(request)) {
|
||||
break;
|
||||
}
|
||||
// 请求被传递给服务器的处理方法
|
||||
response = processRequest(request);
|
||||
System.out.println("response:" + response);
|
||||
// 服务器的响应被发送给了客户端
|
||||
out.println(response);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static String processRequest(String request) {
|
||||
return "hi";
|
||||
}
|
||||
|
||||
/**
|
||||
* socket简单并发测试
|
||||
* @param port
|
||||
* @throws IOException
|
||||
*/
|
||||
public void serve(int port) throws IOException {
|
||||
// 将服务器绑定到指定端口
|
||||
final ServerSocket socket = new ServerSocket(port);
|
||||
try {
|
||||
for (;;) {
|
||||
// 接受连接
|
||||
final Socket clientSocket = socket.accept();
|
||||
System.out.println("Accepted connection from " + clientSocket);
|
||||
// 创建一个新的线程来处理该连接
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
OutputStream out;
|
||||
try {
|
||||
out = clientSocket.getOutputStream();
|
||||
// 将消息写给已连接的客户端
|
||||
out.write("Hi!\r\n".getBytes(Charset
|
||||
.forName("UTF-8")));
|
||||
out.flush();
|
||||
clientSocket.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
clientSocket.close();
|
||||
} catch (IOException ex) {
|
||||
// ignore on close
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* socket 实现非阻塞 I/O
|
||||
* @param port
|
||||
* @throws IOException
|
||||
*/
|
||||
public void serve1(int port) throws IOException {
|
||||
ServerSocketChannel serverChannel = ServerSocketChannel.open();
|
||||
serverChannel.configureBlocking(false);
|
||||
ServerSocket ssocket = serverChannel.socket();
|
||||
InetSocketAddress address = new InetSocketAddress(port);
|
||||
ssocket.bind(address);
|
||||
//打开Selector来处理Channel
|
||||
Selector selector = Selector.open();
|
||||
//将ServerSocket 注册到Selector以接受连接
|
||||
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
|
||||
final ByteBuffer msg = ByteBuffer.wrap("Hi!\r\n".getBytes());
|
||||
for (;;) {
|
||||
try {
|
||||
//等待需要处理的新事件; 阻 塞 将一直持续到下一个传入事件
|
||||
selector.select();
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
break;
|
||||
}
|
||||
//获取所有接收事件的Selection-Key实例
|
||||
Set<SelectionKey> readyKeys = selector.selectedKeys();
|
||||
Iterator<SelectionKey> iterator = readyKeys.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
SelectionKey key = iterator.next();
|
||||
iterator.remove();
|
||||
try {
|
||||
//检查事件是否是一个新的已经就绪可以被接受的连接
|
||||
if (key.isAcceptable()) {
|
||||
ServerSocketChannel server = (ServerSocketChannel) key.channel();
|
||||
SocketChannel client = server.accept();
|
||||
client.configureBlocking(false);
|
||||
//接受客户端,并将它注册到选择器
|
||||
client.register(selector, SelectionKey.OP_WRITE
|
||||
| SelectionKey.OP_READ, msg.duplicate());
|
||||
System.out.println("Accepted connection from " + client);
|
||||
}
|
||||
//检查套接字是否已经准备好写数据
|
||||
if (key.isWritable()) {
|
||||
SocketChannel client = (SocketChannel) key.channel();
|
||||
ByteBuffer buffer = (ByteBuffer) key.attachment();
|
||||
//将数据写到已连接的客户端
|
||||
while (buffer.hasRemaining()) {
|
||||
if (client.write(buffer) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
client.close();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
key.cancel();
|
||||
try {
|
||||
key.channel().close();
|
||||
} catch (IOException cex) {
|
||||
// ignore on close
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
72
src/main/java/com/pancm/basics/StaticTest.java
Normal file
72
src/main/java/com/pancm/basics/StaticTest.java
Normal file
@ -0,0 +1,72 @@
|
||||
package com.pancm.basics;
|
||||
|
||||
/**
|
||||
*
|
||||
* @Title: StaticTest
|
||||
* @Description: 构造块和静态方法测试
|
||||
* @Version:1.0.0
|
||||
* @author Administrator
|
||||
* @date 2017-8-14
|
||||
*/
|
||||
public class StaticTest {
|
||||
public static StaticTest t1 = new StaticTest();
|
||||
public static StaticTest t2 = new StaticTest();
|
||||
{
|
||||
System.out.println("构造块");
|
||||
}
|
||||
static {
|
||||
System.out.println("静态块");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
StaticTest t = new StaticTest(); // 构造块 构造块 静态块 构造块
|
||||
|
||||
|
||||
// new HelloA(); extends HelloA
|
||||
new HelloB(); //3
|
||||
/*
|
||||
* 总结:创建对象时构造器的调用顺序是:先初始化静态成员,然后调用父类构造器,再初始化非静态成员,最后调用自身构造器。
|
||||
*/
|
||||
|
||||
/*
|
||||
* 总结 开始时JVM加载B.class,对所有的静态成员进行声明,t1 t2被初始化为默认值,为null, 又因为t1
|
||||
* t2需要被显式初始化,所以对t1进行显式初始化,初始化代码块→构造函数(没有就是调用默认的构造函数),
|
||||
* 咦!静态代码块咋不初始化?因为在开始时已经对static部分进行了初始化,虽然只对static变量进行了初始化,
|
||||
* 但在初始化t1时也不会再执行static块了,因为JVM认为这是第二次加载类B了,所以static会在t1初始化时被忽略掉,
|
||||
* 所以直接初始化非static部分,也就是构造块部分(输出''构造块'')接着构造函数(无输出)。
|
||||
* 接着对t2进行初始化过程同t1相同(输出'构造块'),此时就对所有的static变量都完成了初始化,
|
||||
* 接着就执行static块部分(输出'静态块'),接着执行,main方法,同样也,new了对象, 调用构造函数输出('构造块')
|
||||
*
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class HelloA {
|
||||
private int i=10;
|
||||
public HelloA() {
|
||||
System.out.println("HelloA"); //5
|
||||
}
|
||||
|
||||
{ System.out.println("I'm A class"); } //4
|
||||
|
||||
static { System.out.println("static A"); } //1
|
||||
|
||||
}
|
||||
class HelloB extends HelloA{
|
||||
private int j=12;
|
||||
public HelloB() {
|
||||
System.out.println("HelloB"); //7
|
||||
}
|
||||
|
||||
{ System.out.println("I'm B class"); } //6
|
||||
|
||||
static { System.out.println("static B"); } //2
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
49
src/main/java/com/pancm/basics/SuperTest.java
Normal file
49
src/main/java/com/pancm/basics/SuperTest.java
Normal file
@ -0,0 +1,49 @@
|
||||
package com.pancm.basics;
|
||||
|
||||
/**
|
||||
*
|
||||
* @Title: SuperTest
|
||||
* @Description: super测试
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2017-5-24
|
||||
*/
|
||||
public class SuperTest extends Person8 {
|
||||
SuperTest() {
|
||||
super(); // 调用父类构造函数(1)
|
||||
prt("A chinese.");// (4)
|
||||
}
|
||||
|
||||
SuperTest(String name) {
|
||||
super(name);// 调用父类具有相同形参的构造函数(2) 调用了Person中的Person(String name)方法
|
||||
prt("his name is:" + name);
|
||||
}
|
||||
|
||||
SuperTest(String name, int age) {
|
||||
this(name);// 调用当前具有相同形参的构造函数(3) 调用了SuperTest(String name)
|
||||
prt("his age is:" + age);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SuperTest cn = new SuperTest(); // A Person. A chinese.
|
||||
cn = new SuperTest("kevin"); //A person name is:kevin his name is:kevin
|
||||
cn = new SuperTest("kevin", 22);//A person name is:kevin his name is:kevin his age is:22
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Person8 {
|
||||
|
||||
public static void prt(String s) {
|
||||
System.out.println(s);
|
||||
}
|
||||
|
||||
Person8() {
|
||||
prt("A Person.");
|
||||
}
|
||||
|
||||
Person8(String name) {
|
||||
prt("A person name is:" + name);
|
||||
|
||||
}
|
||||
}
|
||||
8
src/main/java/com/pancm/basics/package-info.java
Normal file
8
src/main/java/com/pancm/basics/package-info.java
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @Title: package-info
|
||||
* @Description: Java 基础知识的相关代码
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年9月20日
|
||||
*/
|
||||
package com.pancm.basics;
|
||||
8
src/main/java/com/pancm/bigdata/package-info.java
Normal file
8
src/main/java/com/pancm/bigdata/package-info.java
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @Title: package-info
|
||||
* @Description: 大数据相关代码
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年9月20日
|
||||
*/
|
||||
package com.pancm.bigdata;
|
||||
61
src/main/java/com/pancm/commons/apache/CompressTest.java
Normal file
61
src/main/java/com/pancm/commons/apache/CompressTest.java
Normal file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package com.pancm.commons.apache;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
|
||||
|
||||
/**
|
||||
* @Title: compressTest
|
||||
* @Description:
|
||||
* 压缩测试
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年5月14日
|
||||
*/
|
||||
public class CompressTest {
|
||||
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
test();
|
||||
}
|
||||
|
||||
/**
|
||||
* 压缩文件测试
|
||||
*/
|
||||
private static void test() {
|
||||
|
||||
// 创建压缩对象
|
||||
ZipArchiveEntry entry = new ZipArchiveEntry("CompressTest");
|
||||
// 要压缩的文件
|
||||
File f = new File("d:\\user.txt");
|
||||
FileInputStream fis;
|
||||
try {
|
||||
fis = new FileInputStream(f);
|
||||
// 输出的对象 压缩的文件
|
||||
ZipArchiveOutputStream zipOutput = new ZipArchiveOutputStream(new File("d:\\user.zip"));
|
||||
zipOutput.putArchiveEntry(entry);
|
||||
int i = 0, j;
|
||||
while ((j = fis.read()) != -1) {
|
||||
zipOutput.write(j);
|
||||
i++;
|
||||
}
|
||||
System.out.println("压缩成功!遍历了:" + i + "次");
|
||||
zipOutput.closeArchiveEntry();
|
||||
zipOutput.close();
|
||||
fis.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
64
src/main/java/com/pancm/commons/apache/LangTest.java
Normal file
64
src/main/java/com/pancm/commons/apache/LangTest.java
Normal file
@ -0,0 +1,64 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package com.pancm.commons.apache;
|
||||
|
||||
import org.apache.commons.lang.StringEscapeUtils;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.ClassUtils;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
|
||||
/**
|
||||
* @Title: LangTest
|
||||
* @Description:
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年5月14日
|
||||
*/
|
||||
public class LangTest {
|
||||
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
test();
|
||||
}
|
||||
|
||||
public static void test() {
|
||||
// 1 合并两个数组: org.apache.commons.lang. ArrayUtils
|
||||
String[] s1 = new String[] { "1", "2", "3" };
|
||||
String[] s2 = new String[] { "a", "b", "c" };
|
||||
String[] s = (String[]) ArrayUtils.addAll(s1, s2);
|
||||
for (int i = 0; i < s.length; i++) {
|
||||
System.out.println(s[i]);
|
||||
}
|
||||
String str = ArrayUtils.toString(s);
|
||||
str = str.substring(1, str.length() - 1);
|
||||
System.out.println(str + ">>" + str.length());
|
||||
|
||||
System.out.println("测试截取:" + StringUtils.substringAfter("SELECT * FROM PERSON ", "FROM"));
|
||||
// 3 判断该字符串是不是为数字(0~9)组成,如果是,返回true 但该方法不识别有小数点和 请注意。
|
||||
System.out.println("数字判断:" + StringUtils.isNumeric("454534"));
|
||||
System.out.println("取得类名:" + ClassUtils.getShortClassName(LangTest.class));
|
||||
System.out.println("获取包名:" + ClassUtils.getPackageName(LangTest.class));
|
||||
|
||||
System.out.println("是否是数字:" + NumberUtils.isCreatable("123"));
|
||||
System.out.println("随机数字和字母:" + RandomStringUtils.randomAlphanumeric(5));
|
||||
System.out.println("<>进行转义" + StringEscapeUtils.escapeHtml("<html>"));
|
||||
|
||||
System.out.println("是否是null字符 :" + StringUtils.isBlank(null));
|
||||
System.out.println("是否是空字符 :" + StringUtils.isBlank(""));
|
||||
System.out.println("是否是空格字符 :" + StringUtils.isBlank(" "));
|
||||
System.out.println("分割数组:" + StringUtils.join(s1, ","));
|
||||
System.out.println("添加某个字符,使其长度等于所设置的:" + StringUtils.rightPad("abc", 6, 'T'));
|
||||
System.out.println("首字母大写:" + StringUtils.capitalize("abc"));
|
||||
System.out.println("去掉空格:" + StringUtils.deleteWhitespace(" ab c "));
|
||||
System.out.println("是否包含该字符:" + StringUtils.contains("abc", "ba"));
|
||||
System.out.println("表示左边的字符:" + StringUtils.left("abc", 2));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
8
src/main/java/com/pancm/commons/apache/package-info.java
Normal file
8
src/main/java/com/pancm/commons/apache/package-info.java
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @Title: package-info
|
||||
* @Description: apache相关的工具类
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年9月20日
|
||||
*/
|
||||
package com.pancm.commons.apache;
|
||||
52
src/main/java/com/pancm/commons/google/GoogleTest.java
Normal file
52
src/main/java/com/pancm/commons/google/GoogleTest.java
Normal file
@ -0,0 +1,52 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package com.pancm.commons.google;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.pancm.pojo.User;
|
||||
|
||||
/**
|
||||
* @Title: googleTest
|
||||
* @Description:
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年5月14日
|
||||
*/
|
||||
public class GoogleTest {
|
||||
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
test();
|
||||
}
|
||||
|
||||
/**
|
||||
* 数组里所有对象的某个属性的值改变
|
||||
*/
|
||||
private static void test(){
|
||||
List<User> userList=new ArrayList<>();
|
||||
User user=new User();
|
||||
user.setId(1);
|
||||
user.setName("张三");
|
||||
userList.add(user);
|
||||
User user2=new User();
|
||||
user2.setId(2);
|
||||
user2.setName("李四");
|
||||
userList.add(user2);
|
||||
System.out.println("更改之前的数据:"+userList);
|
||||
userList=Lists.transform(userList,new Function<User, User>() {
|
||||
@Override
|
||||
public User apply(User user) {
|
||||
user.setName("王五");
|
||||
return user;
|
||||
}
|
||||
});
|
||||
System.out.println("更改之后的数据:"+userList);
|
||||
}
|
||||
}
|
||||
8
src/main/java/com/pancm/commons/google/package-info.java
Normal file
8
src/main/java/com/pancm/commons/google/package-info.java
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @Title: package-info
|
||||
* @Description: 谷歌的相关测试代码
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年9月20日
|
||||
*/
|
||||
package com.pancm.commons.google;
|
||||
8
src/main/java/com/pancm/commons/package-info.java
Normal file
8
src/main/java/com/pancm/commons/package-info.java
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @Title: package-info
|
||||
* @Description: 这里的commons指第三方的一些工具测试类
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年9月20日
|
||||
*/
|
||||
package com.pancm.commons;
|
||||
115
src/main/java/com/pancm/design/adapter/AdapterTest.java
Normal file
115
src/main/java/com/pancm/design/adapter/AdapterTest.java
Normal file
@ -0,0 +1,115 @@
|
||||
package com.pancm.design.adapter;
|
||||
|
||||
/**
|
||||
* @Title: AdapterTest
|
||||
* @Description:
|
||||
* 适配器模式
|
||||
* 将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
|
||||
*
|
||||
* 有两种种模式
|
||||
* 1.类适配器模式
|
||||
* 2.对象适配器模式
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月8日
|
||||
*/
|
||||
public class AdapterTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
/*
|
||||
* 1.类适配器模式
|
||||
* 通过继承来实现适配器功能。
|
||||
* 有一个视频播放器,但是只能播放MP4格式的视频
|
||||
* 有一个AVI格式的视频需要播放,这时便可以使用格式工厂软件进行转换(适配器)进行转换成MP4格式,然后就可以播放了
|
||||
*/
|
||||
Mp4 mp4=new VideoPlayer();
|
||||
mp4.playMp4();
|
||||
Avi avi=new FormatFactory();
|
||||
avi.playAvi();
|
||||
|
||||
/*
|
||||
* 2.对象适配器模式
|
||||
* 通过组合来实现适配器功能。
|
||||
* 推荐使用对象适配器模式,设计原则的合成复用原则中描述,尽量使用合成/聚合的方式,而不是使用继承。
|
||||
*
|
||||
*/
|
||||
Rvmb rvmb=new FormatFactory2(new VideoPlayer());
|
||||
rvmb.playRvmb();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface Mp4{
|
||||
void playMp4();
|
||||
}
|
||||
|
||||
interface Avi{
|
||||
void playAvi();
|
||||
}
|
||||
|
||||
|
||||
interface Rvmb{
|
||||
void playRvmb();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @Title: VideoPlayer
|
||||
* @Description: 视频播放器
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月21日
|
||||
*/
|
||||
class VideoPlayer implements Mp4{
|
||||
|
||||
@Override
|
||||
public void playMp4() {
|
||||
System.out.println("播放Mp4格式的视频文件.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @Title: FormatFactory
|
||||
* @Description: 格式工厂
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月21日
|
||||
*/
|
||||
class FormatFactory extends VideoPlayer implements Avi{
|
||||
|
||||
@Override
|
||||
public void playAvi() {
|
||||
//转换成MP4格式的视频
|
||||
playMp4();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @Title: FormatFactory2
|
||||
* @Description: 格式工厂
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月21日
|
||||
*/
|
||||
class FormatFactory2 implements Rvmb{
|
||||
private Mp4 mp4;
|
||||
|
||||
public FormatFactory2(Mp4 mp4) {
|
||||
this.mp4=mp4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playRvmb() {
|
||||
mp4.playMp4();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
8
src/main/java/com/pancm/design/adapter/package-info.java
Normal file
8
src/main/java/com/pancm/design/adapter/package-info.java
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @Title: package-info
|
||||
* @Description: 适配器模式
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月8日
|
||||
*/
|
||||
package com.pancm.design.adapter;
|
||||
82
src/main/java/com/pancm/design/bridge/BridgeTest.java
Normal file
82
src/main/java/com/pancm/design/bridge/BridgeTest.java
Normal file
@ -0,0 +1,82 @@
|
||||
package com.pancm.design.bridge;
|
||||
|
||||
/**
|
||||
* @Title: BridgeTest
|
||||
* @Description:桥接模式
|
||||
* 将抽象部分与实现部分分离,使它们都可以独立的变化。
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月8日
|
||||
*/
|
||||
public class BridgeTest {
|
||||
public static void main(String[] args) {
|
||||
Paper paper=new ExaminationPaper();
|
||||
paper.setPen(new RedPen());
|
||||
paper.writing();
|
||||
|
||||
Paper paper2=new NewsPaper();
|
||||
paper2.setPen(new BlackPen());
|
||||
paper2.writing();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @Title: ColourPen
|
||||
* @Description:
|
||||
* 笔
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月22日
|
||||
*/
|
||||
interface Pen{
|
||||
void write();
|
||||
}
|
||||
|
||||
class RedPen implements Pen{
|
||||
@Override
|
||||
public void write() {
|
||||
System.out.println("红色的字");
|
||||
}
|
||||
}
|
||||
|
||||
class BlackPen implements Pen{
|
||||
@Override
|
||||
public void write() {
|
||||
System.out.println("黑色的字");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
abstract class Paper{
|
||||
protected Pen pen;
|
||||
|
||||
void setPen(Pen pen){
|
||||
this.pen=pen;
|
||||
}
|
||||
|
||||
abstract void writing();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @Title: ExaminationPaper
|
||||
* @Description:考试用的卷子
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月22日
|
||||
*/
|
||||
class ExaminationPaper extends Paper{
|
||||
@Override
|
||||
void writing() {
|
||||
pen.write();
|
||||
}
|
||||
}
|
||||
|
||||
class NewsPaper extends Paper{
|
||||
@Override
|
||||
void writing() {
|
||||
pen.write();
|
||||
}
|
||||
}
|
||||
|
||||
8
src/main/java/com/pancm/design/bridge/package-info.java
Normal file
8
src/main/java/com/pancm/design/bridge/package-info.java
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @Title: package-info
|
||||
* @Description: 桥接模式
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月8日
|
||||
*/
|
||||
package com.pancm.design.bridge;
|
||||
148
src/main/java/com/pancm/design/builder/BuilderTest.java
Normal file
148
src/main/java/com/pancm/design/builder/BuilderTest.java
Normal file
@ -0,0 +1,148 @@
|
||||
package com.pancm.design.builder;
|
||||
|
||||
/**
|
||||
* @Title: BuilderTest
|
||||
* @Description:
|
||||
* 建造者模式
|
||||
* 将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月7日
|
||||
*/
|
||||
public class BuilderTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
FoodStore foodStore=new FoodStore();
|
||||
Meal meal=foodStore.createBreakfast(new Breakfast());
|
||||
Meal meal2=foodStore.createBreakfast(new Lunch());
|
||||
System.out.println("小明早上吃的是:"+meal.getFood()+",喝的饮料是:"+meal.getDrinks());
|
||||
System.out.println("小明中午吃的是:"+meal2.getFood()+",喝的饮料是:"+meal2.getDrinks());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @Title: Breakfast
|
||||
* @Description:
|
||||
* 定义一份餐点
|
||||
* 分为吃的和喝的
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月7日
|
||||
*/
|
||||
class Meal{
|
||||
private String food;
|
||||
private String drinks;
|
||||
|
||||
public String getFood() {
|
||||
return food;
|
||||
}
|
||||
public void setFood(String food) {
|
||||
this.food = food;
|
||||
}
|
||||
|
||||
public String getDrinks() {
|
||||
return drinks;
|
||||
}
|
||||
public void setDrinks(String drinks) {
|
||||
this.drinks = drinks;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @Title: IBuilderFood
|
||||
* @Description:
|
||||
* 定义一个食物接口
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月7日
|
||||
*/
|
||||
interface IBuilderFood{
|
||||
void buildFood();
|
||||
void buildDrinks();
|
||||
Meal createMeal();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @Title: Breakfast
|
||||
* @Description:定义一份早餐
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月7日
|
||||
*/
|
||||
class Breakfast implements IBuilderFood{
|
||||
Meal meal;
|
||||
|
||||
public Breakfast(){
|
||||
meal=new Meal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildFood() {
|
||||
meal.setFood("煎饼");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildDrinks() {
|
||||
meal.setDrinks("豆浆");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Meal createMeal() {
|
||||
return meal;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @Title: Lunch
|
||||
* @Description: 定义一份午餐
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月15日
|
||||
*/
|
||||
class Lunch implements IBuilderFood{
|
||||
Meal meal;
|
||||
|
||||
public Lunch(){
|
||||
meal=new Meal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildFood() {
|
||||
meal.setFood("盒饭");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildDrinks() {
|
||||
meal.setDrinks("果汁");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Meal createMeal() {
|
||||
return meal;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @Title: FoodStore
|
||||
* @Description:
|
||||
* 定义一个餐点
|
||||
* 导演者
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月15日
|
||||
*/
|
||||
class FoodStore{
|
||||
public Meal createBreakfast(IBuilderFood bf){
|
||||
bf.buildDrinks();
|
||||
bf.buildFood();
|
||||
return bf.createMeal();
|
||||
}
|
||||
}
|
||||
|
||||
8
src/main/java/com/pancm/design/builder/package-info.java
Normal file
8
src/main/java/com/pancm/design/builder/package-info.java
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @Title: package-info
|
||||
* @Description:建造者模式
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月7日
|
||||
*/
|
||||
package com.pancm.design.builder;
|
||||
83
src/main/java/com/pancm/design/composite/CompositeTest.java
Normal file
83
src/main/java/com/pancm/design/composite/CompositeTest.java
Normal file
@ -0,0 +1,83 @@
|
||||
package com.pancm.design.composite;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Title: CompositeTest
|
||||
* @Description: 组合模式
|
||||
* 将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月8日
|
||||
*/
|
||||
public class CompositeTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
/*
|
||||
* 建立一个学生类,包含学生姓名和职位
|
||||
*
|
||||
*/
|
||||
Student studentLeader=new Student("小明","学生会主席");
|
||||
|
||||
Student committeeMember=new Student("小刚","学生会委员");
|
||||
|
||||
Student student=new Student("小红","学生");
|
||||
|
||||
committeeMember.add(student);
|
||||
studentLeader.add(committeeMember);
|
||||
|
||||
System.out.println("-"+studentLeader);
|
||||
studentLeader.get().forEach(sl->{
|
||||
System.out.println("--"+sl);
|
||||
sl.get().forEach(cm->{
|
||||
System.out.println("---"+cm);
|
||||
});
|
||||
});
|
||||
|
||||
/*
|
||||
* -Student [name=小明, position=学生会主席]
|
||||
--Student [name=小刚, position=学生会委员]
|
||||
---Student [name=小红, position=学生]
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Student{
|
||||
private String name;
|
||||
|
||||
private String position;
|
||||
|
||||
private List<Student> students;
|
||||
|
||||
public Student(String name, String position) {
|
||||
this.name = name;
|
||||
this.position = position;
|
||||
students=new ArrayList<Student>();
|
||||
}
|
||||
|
||||
|
||||
public void add(Student student){
|
||||
students.add(student);
|
||||
}
|
||||
|
||||
public void remove(Student student){
|
||||
students.remove(student);
|
||||
}
|
||||
|
||||
public List<Student> get(){
|
||||
return students;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Student [name=" + name + ", position=" + position + "]";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @Title: package-info
|
||||
* @Description: 组合模式
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月8日
|
||||
*/
|
||||
package com.pancm.design.composite;
|
||||
111
src/main/java/com/pancm/design/decorator/DecoratorTest.java
Normal file
111
src/main/java/com/pancm/design/decorator/DecoratorTest.java
Normal file
@ -0,0 +1,111 @@
|
||||
package com.pancm.design.decorator;
|
||||
|
||||
/**
|
||||
* @Title: DecoratorTest
|
||||
* @Description: 装饰器模式
|
||||
* 动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
|
||||
* 比如一个人,可以穿不同的装饰,外套、T恤、短裤、西服等等
|
||||
* 人是不变的
|
||||
Component抽象构件角色:真实对象和装饰对象有相同的接口。这样,客户端对象就能够以与真实对象相同的方式同装饰对象交互。
|
||||
ConcreteComponent具体构件角色(真实对象):io流中的FileInputStream、 FileOutputStream
|
||||
Decorator装饰角色:持有一个抽象构件的引用。装饰对象接受所有客户端的请求,并把这些请求转发给真实的对象。这样,就能在真实对象调用前后增加新的功能。
|
||||
ConcreteDecorator具体装饰角色:负责给构件对象增加新的责任。
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月8日
|
||||
*/
|
||||
public class DecoratorTest {
|
||||
public static void main(String[] args) {
|
||||
//组装模型
|
||||
Model gundam=new GUNDAM();
|
||||
Model mrgu=new MrGu();
|
||||
gundam.assemble();
|
||||
mrgu.assemble();
|
||||
|
||||
//组装模型并添加武器
|
||||
Model gModel=new LightSaber(new GUNDAM());
|
||||
gModel.assemble();
|
||||
Model mModel=new RocketLauncher(new MrGu());
|
||||
mModel.assemble();
|
||||
|
||||
/*
|
||||
*
|
||||
组装一个高达模型
|
||||
组装一个扎古模型
|
||||
组装一个高达模型
|
||||
添加光剑
|
||||
组装一个扎古模型
|
||||
添加火箭筒
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface Model{
|
||||
void assemble();
|
||||
}
|
||||
|
||||
class GUNDAM implements Model{
|
||||
@Override
|
||||
public void assemble() {
|
||||
System.out.println("组装一个高达模型");
|
||||
}
|
||||
}
|
||||
|
||||
class MrGu implements Model{
|
||||
@Override
|
||||
public void assemble() {
|
||||
System.out.println("组装一个扎古模型");
|
||||
}
|
||||
}
|
||||
|
||||
//添加额外的功能
|
||||
//装饰器
|
||||
abstract class AddExtra implements Model{
|
||||
protected Model model;
|
||||
|
||||
public AddExtra(Model model){
|
||||
this.model=model;
|
||||
}
|
||||
public void assemble(){
|
||||
model.assemble();
|
||||
}
|
||||
}
|
||||
|
||||
//添加光剑
|
||||
class LightSaber extends AddExtra{
|
||||
|
||||
public LightSaber(Model model) {
|
||||
super(model);
|
||||
}
|
||||
|
||||
public void assemble(){
|
||||
model.assemble();
|
||||
addLightSaber();
|
||||
}
|
||||
public void addLightSaber(){
|
||||
System.out.println("添加光剑");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//添加火箭筒
|
||||
class RocketLauncher extends AddExtra{
|
||||
|
||||
public RocketLauncher(Model model) {
|
||||
super(model);
|
||||
}
|
||||
|
||||
public void assemble(){
|
||||
model.assemble();
|
||||
addRocketLauncher();
|
||||
}
|
||||
public void addRocketLauncher(){
|
||||
System.out.println("添加火箭筒");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @Title: package-info
|
||||
* @Description: 装饰器模式
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月8日
|
||||
*/
|
||||
package com.pancm.design.decorator;
|
||||
83
src/main/java/com/pancm/design/facade/FacadeTest.java
Normal file
83
src/main/java/com/pancm/design/facade/FacadeTest.java
Normal file
@ -0,0 +1,83 @@
|
||||
package com.pancm.design.facade;
|
||||
|
||||
/**
|
||||
* @Title: FacadeTest
|
||||
* @Description:
|
||||
* 外观模式测试代码
|
||||
*
|
||||
* 为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
|
||||
*
|
||||
* 比如windows开机:启动CPU、启动内存、启动硬盘
|
||||
* windows关机:关闭硬盘、关闭内存、关闭CPU
|
||||
*
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月8日
|
||||
*/
|
||||
public class FacadeTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
/*
|
||||
* 对外提供 一个界面
|
||||
* 游戏装在电脑上,想玩游戏就在电脑启动游戏就可以了
|
||||
*/
|
||||
Computer computer=new Computer();
|
||||
computer.playDNF();
|
||||
computer.playLOL();
|
||||
computer.playWOW();
|
||||
}
|
||||
}
|
||||
|
||||
interface Game{
|
||||
void play();
|
||||
}
|
||||
|
||||
class DNF implements Game{
|
||||
|
||||
@Override
|
||||
public void play() {
|
||||
System.out.println("正在玩DNF...");
|
||||
}
|
||||
}
|
||||
|
||||
class LOL implements Game{
|
||||
@Override
|
||||
public void play() {
|
||||
System.out.println("正在玩LOL...");
|
||||
}
|
||||
}
|
||||
|
||||
class WOW implements Game{
|
||||
@Override
|
||||
public void play() {
|
||||
System.out.println("正在玩WOW...");
|
||||
}
|
||||
}
|
||||
|
||||
class Computer{
|
||||
|
||||
private Game dnf;
|
||||
private Game lol;
|
||||
private Game wow;
|
||||
|
||||
public Computer() {
|
||||
dnf=new DNF();
|
||||
lol=new LOL();
|
||||
wow=new WOW();
|
||||
}
|
||||
|
||||
public void playDNF(){
|
||||
dnf.play();
|
||||
}
|
||||
|
||||
public void playLOL(){
|
||||
lol.play();
|
||||
}
|
||||
|
||||
public void playWOW(){
|
||||
wow.play();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
8
src/main/java/com/pancm/design/facade/package-info.java
Normal file
8
src/main/java/com/pancm/design/facade/package-info.java
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @Title: package-info
|
||||
* @Description: 外观模式
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月8日
|
||||
*/
|
||||
package com.pancm.design.facade;
|
||||
175
src/main/java/com/pancm/design/factory/FactorymTest.java
Normal file
175
src/main/java/com/pancm/design/factory/FactorymTest.java
Normal file
@ -0,0 +1,175 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package com.pancm.design.factory;
|
||||
|
||||
/**
|
||||
* @Title: FactorymTest
|
||||
* @Description:
|
||||
* 简单工厂模式测试
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年7月23日
|
||||
*/
|
||||
public class FactorymTest {
|
||||
private static final String LOL="LOL";
|
||||
private static final String DNF="DNF";
|
||||
private static final String WOW="WOW";
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
/**
|
||||
* 简单工厂模式
|
||||
* 根据条件决定一个接口由哪个具体产品类来实现
|
||||
* 优点:
|
||||
* 缺点:扩展性差
|
||||
*/
|
||||
Game game= ComputerFactory.playGame(LOL);
|
||||
Game game2= ComputerFactory.playGame(DNF);
|
||||
game.play();
|
||||
game2.play();
|
||||
|
||||
/**
|
||||
* 工厂方法模式
|
||||
*
|
||||
* 优点:扩展性高
|
||||
* 缺点:增加了复杂度
|
||||
*/
|
||||
Game game3=new LOLFactory().playGame(LOL);
|
||||
Game game4=new DNFFactory().playGame(DNF);
|
||||
Game game5=new WOWFactory().playGame(WOW);
|
||||
game3.play();
|
||||
game4.play();
|
||||
game5.play();
|
||||
|
||||
|
||||
/**
|
||||
* 抽象工厂模式
|
||||
*
|
||||
* 优点:
|
||||
*
|
||||
*/
|
||||
ComputerFactory3 cf3=new PVPFactory();
|
||||
cf3.playGame().play();
|
||||
cf3.playGame2().play();
|
||||
ComputerFactory3 cf4=new PVEFactory();
|
||||
cf4.playGame().play();
|
||||
cf4.playGame2().play();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 定义一个接口
|
||||
*/
|
||||
interface Game{
|
||||
void play();
|
||||
}
|
||||
|
||||
/**
|
||||
* 定义一个实现类
|
||||
*/
|
||||
class LOL implements Game{
|
||||
@Override
|
||||
public void play() {
|
||||
System.out.println("正在玩LOL...");
|
||||
}
|
||||
}
|
||||
|
||||
class DNF implements Game{
|
||||
@Override
|
||||
public void play() {
|
||||
System.out.println("正在玩DNF...");
|
||||
}
|
||||
}
|
||||
|
||||
class WOW implements Game{
|
||||
@Override
|
||||
public void play() {
|
||||
System.out.println("正在玩WOW...");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 定义一个电脑
|
||||
*/
|
||||
class ComputerFactory{
|
||||
private static final String LOL="LOL";
|
||||
private static final String DNF="DNF";
|
||||
//玩游戏
|
||||
public static Game playGame(String game){
|
||||
if(LOL.equalsIgnoreCase(game)){
|
||||
return new LOL();
|
||||
}else if(DNF.equalsIgnoreCase(game)){
|
||||
return new DNF();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
interface ComputerFactory2{
|
||||
Game playGame(String game);
|
||||
}
|
||||
|
||||
class LOLFactory implements ComputerFactory2{
|
||||
@Override
|
||||
public Game playGame(String game) {
|
||||
return new LOL();
|
||||
}
|
||||
}
|
||||
|
||||
class DNFFactory implements ComputerFactory2{
|
||||
@Override
|
||||
public Game playGame(String game) {
|
||||
return new DNF();
|
||||
}
|
||||
}
|
||||
|
||||
class WOWFactory implements ComputerFactory2{
|
||||
@Override
|
||||
public Game playGame(String game) {
|
||||
return new WOW();
|
||||
}
|
||||
}
|
||||
|
||||
interface ComputerFactory3{
|
||||
Game playGame();
|
||||
|
||||
Game playGame2();
|
||||
}
|
||||
|
||||
class PVPFactory implements ComputerFactory3{
|
||||
|
||||
@Override
|
||||
public Game playGame() {
|
||||
return new LOL();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Game playGame2() {
|
||||
return new WOW();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class PVEFactory implements ComputerFactory3{
|
||||
|
||||
@Override
|
||||
public Game playGame() {
|
||||
return new DNF();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Game playGame2() {
|
||||
return new WOW();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
11
src/main/java/com/pancm/design/factory/package-info.java
Normal file
11
src/main/java/com/pancm/design/factory/package-info.java
Normal file
@ -0,0 +1,11 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* Title: package-info
|
||||
* Description: 工厂测试
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2017年10月13日
|
||||
*/
|
||||
package com.pancm.design.factory;
|
||||
181
src/main/java/com/pancm/design/filter/FilterTest.java
Normal file
181
src/main/java/com/pancm/design/filter/FilterTest.java
Normal file
@ -0,0 +1,181 @@
|
||||
package com.pancm.design.filter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Title: FilterTest
|
||||
* @Description: 过滤器模式
|
||||
* 过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,
|
||||
* 这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。
|
||||
* 这种类型的设计模式属于结构型模式,它结合多个标准来获得单一标准。
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月8日
|
||||
*/
|
||||
public class FilterTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
/*
|
||||
* 1.创建学生,有姓名、性别、年级这三个属性
|
||||
* 2.根据这三个属性进行过滤分组
|
||||
*
|
||||
*/
|
||||
List<Student> list=new ArrayList<Student>();
|
||||
list.add(new Student("小明", "male", 1));
|
||||
list.add(new Student("小红", "female", 2));
|
||||
list.add(new Student("小刚", "male", 2));
|
||||
list.add(new Student("小霞", "female", 3));
|
||||
list.add(new Student("小智", "male", 3));
|
||||
list.add(new Student("虚无境", "male", 1));
|
||||
|
||||
|
||||
FilterinGrule male = new MaleStudents();
|
||||
FilterinGrule female = new FemaleStudents();
|
||||
FilterinGrule secondGrade = new SecondGrade();
|
||||
FilterinGrule secondGradeMale = new And(secondGrade, male);
|
||||
FilterinGrule secondGradeOrFemale = new Or(secondGrade, female);
|
||||
|
||||
System.out.println("男生:"+male.filter(list));
|
||||
System.out.println("女生:"+female.filter(list));
|
||||
System.out.println("二年级学生:"+secondGrade.filter(list));
|
||||
System.out.println("二年级男生:"+secondGradeMale.filter(list));
|
||||
System.out.println("二年级的学生或女生:"+secondGradeOrFemale.filter(list));
|
||||
|
||||
/*
|
||||
*
|
||||
男生:[Student [name=小明, gender=male, grade=1], Student [name=小刚, gender=male, grade=2], Student [name=小智, gender=male, grade=3], Student [name=虚无境, gender=male, grade=1]]
|
||||
女生:[Student [name=小红, gender=female, grade=2], Student [name=小霞, gender=female, grade=3]]
|
||||
二年级学生:[Student [name=小红, gender=female, grade=2], Student [name=小刚, gender=male, grade=2]]
|
||||
二年级男生:[Student [name=小刚, gender=male, grade=2]]
|
||||
二年级的学生或女生:[Student [name=小红, gender=female, grade=2], Student [name=小刚, gender=male, grade=2], Student [name=小霞, gender=female, grade=3]]
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class Student{
|
||||
private String name;
|
||||
private String gender;
|
||||
private Integer grade;
|
||||
public Student(String name, String gender, Integer grade) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.gender = gender;
|
||||
this.grade = grade;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getGender() {
|
||||
return gender;
|
||||
}
|
||||
|
||||
public void setGender(String gender) {
|
||||
this.gender = gender;
|
||||
}
|
||||
|
||||
public Integer getGrade() {
|
||||
return grade;
|
||||
}
|
||||
|
||||
public void setGrade(Integer grade) {
|
||||
this.grade = grade;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Student [name=" + name + ", gender=" + gender + ", grade=" + grade + "]";
|
||||
}
|
||||
}
|
||||
|
||||
interface FilterinGrule {
|
||||
List<Student> filter(List<Student> students);
|
||||
}
|
||||
|
||||
class MaleStudents implements FilterinGrule{
|
||||
@Override
|
||||
public List<Student> filter(List<Student> students) {
|
||||
List<Student> maleStudents = new ArrayList<Student>();
|
||||
students.forEach(student->{
|
||||
if(student.getGender().equalsIgnoreCase("male")){
|
||||
maleStudents.add(student);
|
||||
}
|
||||
});
|
||||
return maleStudents;
|
||||
}
|
||||
}
|
||||
|
||||
class FemaleStudents implements FilterinGrule{
|
||||
@Override
|
||||
public List<Student> filter(List<Student> students) {
|
||||
List<Student> femaleStudents = new ArrayList<Student>();
|
||||
students.forEach(student->{
|
||||
if(student.getGender().equalsIgnoreCase("female")){
|
||||
femaleStudents.add(student);
|
||||
}
|
||||
});
|
||||
return femaleStudents;
|
||||
}
|
||||
}
|
||||
|
||||
class SecondGrade implements FilterinGrule{
|
||||
@Override
|
||||
public List<Student> filter(List<Student> students) {
|
||||
List<Student> secondGradeStudents = new ArrayList<Student>();
|
||||
students.forEach(student->{
|
||||
if(student.getGrade() == 2){
|
||||
secondGradeStudents.add(student);
|
||||
}
|
||||
});
|
||||
|
||||
return secondGradeStudents;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class And implements FilterinGrule{
|
||||
private FilterinGrule filter;
|
||||
private FilterinGrule filter2;
|
||||
|
||||
public And(FilterinGrule filter,FilterinGrule filter2) {
|
||||
this.filter=filter;
|
||||
this.filter2=filter2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Student> filter(List<Student> students) {
|
||||
List<Student> students2=filter.filter(students);
|
||||
return filter2.filter(students2);
|
||||
}
|
||||
}
|
||||
|
||||
class Or implements FilterinGrule{
|
||||
private FilterinGrule filter;
|
||||
private FilterinGrule filter2;
|
||||
|
||||
public Or(FilterinGrule filter,FilterinGrule filter2) {
|
||||
this.filter=filter;
|
||||
this.filter2=filter2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Student> filter(List<Student> students) {
|
||||
List<Student> students1=filter.filter(students);
|
||||
List<Student> students2=filter2.filter(students);
|
||||
students2.forEach(student->{
|
||||
if(!students1.contains(student)){
|
||||
students1.add(student);
|
||||
}
|
||||
});
|
||||
return students1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
8
src/main/java/com/pancm/design/filter/package-info.java
Normal file
8
src/main/java/com/pancm/design/filter/package-info.java
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @Title: package-info
|
||||
* @Description: 过滤器模式
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月8日
|
||||
*/
|
||||
package com.pancm.design.filter;
|
||||
60
src/main/java/com/pancm/design/package-info.java
Normal file
60
src/main/java/com/pancm/design/package-info.java
Normal file
@ -0,0 +1,60 @@
|
||||
/**
|
||||
* @Title: package-info
|
||||
* @Description: 设计模式相关测试代码
|
||||
设计模式有23种类型。按照主要分类可以分为三大类:
|
||||
|
||||
一、创建型模式
|
||||
|
||||
这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。
|
||||
|
||||
单例模式
|
||||
工厂模式
|
||||
抽象工厂模式
|
||||
建造者模式
|
||||
原型模式
|
||||
二、结构型模式
|
||||
|
||||
这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。
|
||||
|
||||
适配器模式
|
||||
桥接模式
|
||||
过滤器模式
|
||||
组合模式
|
||||
装饰器模式
|
||||
外观模式
|
||||
享元模式
|
||||
代理模式
|
||||
三、行为型模式
|
||||
|
||||
这些设计模式特别关注对象之间的通信。
|
||||
|
||||
责任链模式
|
||||
命令模式
|
||||
解释器模式
|
||||
迭代器模式
|
||||
中介者模式
|
||||
备忘录模式
|
||||
观察者模式
|
||||
状态模式
|
||||
空对象模式
|
||||
策略模式
|
||||
模板模式
|
||||
访问者模式
|
||||
|
||||
|
||||
设计模式的原则
|
||||
设计模式的六大原则
|
||||
开闭原则:对扩展开放,对修改关闭。
|
||||
里氏代换原则:对开闭原则的补充。任何基类可以出现的地方,子类一定可以出现。LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。
|
||||
依赖倒转原则:针对接口编程,依赖于抽象而不依赖于具体。
|
||||
接口隔离原则:尽量使用多个隔离的接口,为了降低类之间的耦合度。
|
||||
迪米特法则:一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。
|
||||
合成复用原则:尽量使用合成/聚合的方式,而不是使用继承。
|
||||
|
||||
|
||||
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年7月7日
|
||||
*/
|
||||
package com.pancm.design;
|
||||
71
src/main/java/com/pancm/design/prototype/PrototypeTest.java
Normal file
71
src/main/java/com/pancm/design/prototype/PrototypeTest.java
Normal file
@ -0,0 +1,71 @@
|
||||
package com.pancm.design.prototype;
|
||||
|
||||
/**
|
||||
* @Title: PrototypeTest
|
||||
* @Description: 原型模式
|
||||
* 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
|
||||
* 所谓原型模式,就是java中的克隆技术,以某个对象为原型。复制出新的对象。显然新的对象具备原型对象的特点。
|
||||
* 1、实现克隆操作,在 JAVA 继承 Cloneable,重写 clone()。
|
||||
* 2、原型模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些"易变类"拥有稳定的接口。
|
||||
*
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月13日
|
||||
*/
|
||||
public class PrototypeTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Mail mail=new Mail();
|
||||
mail.setMsg("生日快乐!");
|
||||
Mail mail2=(Mail) mail.clone();
|
||||
System.out.println("小明:"+mail.getMsg());
|
||||
System.out.println("小红:"+mail2.getMsg());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Title:
|
||||
* @Description: 定义一个原型的邮件信息
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月15日
|
||||
*/
|
||||
class Mail implements Cloneable {
|
||||
protected String msg;
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
|
||||
public Object clone() {
|
||||
Object clone = null;
|
||||
try {
|
||||
clone = super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
void sendMail() {
|
||||
}
|
||||
}
|
||||
|
||||
class BirthdayMail extends Mail {
|
||||
|
||||
public BirthdayMail() {
|
||||
msg = "生日快乐!";
|
||||
}
|
||||
|
||||
@Override
|
||||
void sendMail() {
|
||||
System.out.println(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
10
src/main/java/com/pancm/design/prototype/package-info.java
Normal file
10
src/main/java/com/pancm/design/prototype/package-info.java
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
/**
|
||||
* @Title: package-info
|
||||
* @Description:
|
||||
* 原型模式
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月7日
|
||||
*/
|
||||
package com.pancm.design.prototype;
|
||||
145
src/main/java/com/pancm/design/singleton/SingletonTest.java
Normal file
145
src/main/java/com/pancm/design/singleton/SingletonTest.java
Normal file
@ -0,0 +1,145 @@
|
||||
package com.pancm.design.singleton;
|
||||
/**
|
||||
* @author ZERO
|
||||
* @Data 2017-6-7 下午4:08:26
|
||||
* @Description
|
||||
*/
|
||||
|
||||
/**
|
||||
* 方法一
|
||||
* 单例模式的实现:饿汉式,线程安全 但效率比较低
|
||||
*
|
||||
* 方法一就是传说的中的饿汉模式
|
||||
* 优点是:写起来比较简单,而且不存在多线程同步问题,避免了synchronized所造成的性能问题;
|
||||
* 缺点是:当类SingletonTest被加载的时候,会初始化static的instance,静态变量被创建并分配内存空间,
|
||||
* 从这以后,这个static的instance对象便一直占着这段内存(即便你还没有用到这个实例),
|
||||
* 当类被卸载时,静态变量被摧毁,并释放所占有的内存,因此在某些特定条件下会耗费内存。
|
||||
*
|
||||
*/
|
||||
class SingletonTest1 {
|
||||
|
||||
// 定义一个私有的构造方法
|
||||
private SingletonTest1() {
|
||||
}
|
||||
|
||||
// 将自身的实例对象设置为一个属性,并加上Static和final修饰符
|
||||
private static final SingletonTest1 instance = new SingletonTest1();
|
||||
|
||||
// 静态方法返回该类的实例
|
||||
public static SingletonTest1 getInstance() {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 方法二
|
||||
* 单例模式的实现:饱汉式,非线程安全
|
||||
* 方法二就是传说的中的饱汉模式
|
||||
* 优点是:写起来比较简单,当类SingletonTest被加载的时候,静态变量static的instance未被创建并分配内存空间,
|
||||
* 当getInstance方法第一次被调用时,初始化instance变量,并分配内存,因此在某些特定条件下会节约了内存;
|
||||
* 缺点是:并发环境下很可能出现多个SingletonTest实例。
|
||||
*/
|
||||
class SingletonTest2 {
|
||||
// 定义私有构造方法(防止通过 new SingletonTest()去实例化)
|
||||
private SingletonTest2() {
|
||||
}
|
||||
|
||||
// 定义一个SingletonTest类型的变量(不初始化,注意这里没有使用final关键字)
|
||||
private static SingletonTest2 instance;
|
||||
|
||||
// 定义一个静态的方法(调用时再初始化SingletonTest,但是多线程访问时,可能造成重复初始化问题)
|
||||
public static SingletonTest2 getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new SingletonTest2();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*方法三
|
||||
* 单例模式的实现:饱汉式,线程安全简单实现
|
||||
* 方法三为方法二的简单优化
|
||||
* 优点是:使用synchronized关键字避免多线程访问时,出现多个SingletonTest实例。
|
||||
* 缺点是:同步方法频繁调用时,效率略低
|
||||
*/
|
||||
class SingletonTest3 {
|
||||
// 定义私有构造方法(防止通过 new SingletonTest()去实例化)
|
||||
private SingletonTest3() {
|
||||
}
|
||||
// 定义一个SingletonTest类型的变量(不初始化,注意这里没有使用final关键字)
|
||||
private static SingletonTest3 instance;
|
||||
|
||||
// 定义一个静态的方法(调用时再初始化SingletonTest,使用synchronized 避免多线程访问时,可能造成重的复初始化问题)
|
||||
public static synchronized SingletonTest3 getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new SingletonTest3();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 方法四
|
||||
* 静态内部类
|
||||
* 这种写法仍然使用JVM本身机制保证了线程安全问题;由于SingletonTest5是私有的, 除了getInstance()之外没有办法访问它,
|
||||
* 因此它是懒汉式的;同时读取实例的时候不会进行同步,没有性能缺陷;也不依赖JDK版本。
|
||||
*/
|
||||
class SingletonTest4 {
|
||||
private SingletonTest4(){
|
||||
}
|
||||
private static class SingletonTest5{
|
||||
private static SingletonTest4 instance = new SingletonTest4();
|
||||
}
|
||||
public static final SingletonTest4 getInstance(){
|
||||
return SingletonTest5.instance;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 方法五 双重锁
|
||||
* 单例模式最优方案
|
||||
* 线程安全 并且效率高
|
||||
* 方法四为单例模式的最佳实现。内存占用低,效率高,线程安全,多线程操作原子性。
|
||||
*/
|
||||
class SingletonTest6 {
|
||||
// 定义一个私有构造方法
|
||||
private SingletonTest6() {
|
||||
}
|
||||
//定义一个静态私有变量(不初始化,不使用final关键字,使用volatile保证了多线程访问时instance变量的可见性,避免了instance初始化时其他变量属性还没赋值完时,被另外线程调用)
|
||||
private static volatile SingletonTest6 instance;
|
||||
//定义一个共有的静态方法,返回该类型实例
|
||||
public static SingletonTest6 getIstance() {
|
||||
// 对象实例化时与否判断(不使用同步代码块,instance不等于null时,直接返回对象,提高运行效率)
|
||||
if (instance == null) {
|
||||
//同步代码块(对象未初始化时,使用同步代码块,保证多线程访问时对象在第一次创建后,不再重复被创建)
|
||||
synchronized (SingletonTest6.class) {
|
||||
//未初始化,则初始instance变量
|
||||
if (instance == null) {
|
||||
instance = new SingletonTest6();
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法六,枚举单例模式
|
||||
* 1.从Java1.5开始支持;
|
||||
* 2.无偿提供序列化机制;
|
||||
* 3.绝对防止多次实例化,即使在面对复杂的序列化或者反射攻击的时候;
|
||||
* 自由序列化,线程安全,保证单例
|
||||
*/
|
||||
enum SingletonTest7{
|
||||
INSTANCE;
|
||||
}
|
||||
|
||||
public class SingletonTest {
|
||||
public static void main(String[] args) {
|
||||
}
|
||||
}
|
||||
11
src/main/java/com/pancm/design/singleton/package-info.java
Normal file
11
src/main/java/com/pancm/design/singleton/package-info.java
Normal file
@ -0,0 +1,11 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* Title: package-info
|
||||
* Description: 单例模式测试
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2017年11月7日
|
||||
*/
|
||||
package com.pancm.design.singleton;
|
||||
65
src/main/java/com/pancm/jdk8/LambdaTest.java
Normal file
65
src/main/java/com/pancm/jdk8/LambdaTest.java
Normal file
@ -0,0 +1,65 @@
|
||||
package com.pancm.jdk8;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.pancm.pojo.User;
|
||||
|
||||
/**
|
||||
* @Title: LambdaTest
|
||||
* @Description: 拉姆达表达式
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年8月28日
|
||||
*/
|
||||
public class LambdaTest {
|
||||
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
test1();
|
||||
test2();
|
||||
}
|
||||
|
||||
private static void test1(){
|
||||
Map<String , String> map = new HashMap<>();
|
||||
map.put("a","a");
|
||||
map.put("b","b");
|
||||
map.put("c","c");
|
||||
map.put("d","d");
|
||||
map.put("e","e");
|
||||
map.put("f","f");
|
||||
|
||||
map.forEach((k,v)->{
|
||||
System.out.println("k="+k+",v="+v);
|
||||
});
|
||||
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add("aaa");
|
||||
list.add("bbbbb");
|
||||
list.add("ccccccc");
|
||||
list.add("dddd");
|
||||
list.forEach(v->{
|
||||
System.out.println(v);
|
||||
});
|
||||
}
|
||||
|
||||
private static void test2(){
|
||||
List<User> list = new ArrayList<User>();
|
||||
List<User> list2 = new ArrayList<User>();
|
||||
list.add(new User(1, "张三"));
|
||||
list.add(new User(2, "李四"));
|
||||
list.add(new User(3, "王五"));
|
||||
list.add(new User(4, "赵六"));
|
||||
System.out.println("list:"+list);
|
||||
list.forEach(v->{
|
||||
if(v.getId()>2){
|
||||
list2.add(v);
|
||||
}
|
||||
});
|
||||
System.out.println("list2:"+list2);
|
||||
}
|
||||
}
|
||||
423
src/main/java/com/pancm/jdk8/StreamTest.java
Normal file
423
src/main/java/com/pancm/jdk8/StreamTest.java
Normal file
@ -0,0 +1,423 @@
|
||||
package com.pancm.jdk8;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.pancm.pojo.User;
|
||||
|
||||
/**
|
||||
* @Title: StreamTest
|
||||
* @Description: Stream测试用例 流的操作类型分为两种:
|
||||
*
|
||||
* Intermediate:一个流可以后面跟随零个或多个 intermediate
|
||||
* 操作。其目的主要是打开流,做出某种程度的数据映射/过滤,然后返回一个新的流,交给下一个操作使用。
|
||||
* 这类操作都是惰性化的(lazy),就是说,仅仅调用到这类方法,并没有真正开始流的遍历。 Terminal:一个流只能有一个
|
||||
* terminal 操作,当这个操作执行后,流就被使用“光”了,无法再被操作。 所以这必定是流的最后一个操作。 Terminal
|
||||
* 操作的执行,才会真正开始流的遍历,并且会生成一个结果,或者一个 side effect。
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年9月3日
|
||||
*/
|
||||
public class StreamTest {
|
||||
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
test1();
|
||||
test2();
|
||||
test3();
|
||||
test4();
|
||||
|
||||
/*
|
||||
* Stream 的特性可以归纳为:
|
||||
不是数据结构
|
||||
它没有内部存储,它只是用操作管道从 source(数据结构、数组、generator function、IO channel)抓取数据。
|
||||
它也绝不修改自己所封装的底层数据结构的数据。例如 Stream 的 filter 操作会产生一个不包含被过滤元素的新 Stream,而不是从 source 删除那些元素。
|
||||
所有 Stream 的操作必须以 lambda 表达式为参数
|
||||
不支持索引访问
|
||||
你可以请求第一个元素,但无法请求第二个,第三个,或最后一个。不过请参阅下一项。
|
||||
很容易生成数组或者 List
|
||||
惰性化
|
||||
很多 Stream 操作是向后延迟的,一直到它弄清楚了最后需要多少数据才会开始。
|
||||
Intermediate 操作永远是惰性化的。
|
||||
并行能力
|
||||
当一个 Stream 是并行化的,就不需要再写多线程代码,所有对它的操作会自动并行进行的。
|
||||
可以是无限的
|
||||
集合有固定大小,Stream 则不必。limit(n) 和 findFirst() 这类的 short-circuiting 操作可以对无限的 Stream 进行运算并很快完成。
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* 简单实用
|
||||
*/
|
||||
private static void test1() {
|
||||
/*
|
||||
* 普通的方式过滤
|
||||
*/
|
||||
List<String> list = Arrays.asList("张三", "李四", "王五");
|
||||
System.out.println("过滤之前:" + list);
|
||||
List<String> result = new ArrayList<>();
|
||||
for (String str : list) {
|
||||
if (!"李四".equals(str)) {
|
||||
result.add(str);
|
||||
}
|
||||
}
|
||||
System.out.println("过滤之后:" + result);
|
||||
|
||||
/*
|
||||
* stream 过滤
|
||||
*/
|
||||
List<String> result2 = list.stream().filter(str -> !"李四".equals(str)).collect(Collectors.toList());
|
||||
System.out.println("stream 过滤之后:" + result2);
|
||||
// 另一种方式输出
|
||||
result2.forEach(System.out::println);
|
||||
|
||||
// 使用stream.filter ()过滤一列表,并.findAny().orElse
|
||||
// 遍历该list,查询数据,如果查不到,就返回 找不到!
|
||||
String result3 = list.stream().filter(str -> "李四".equals(str)).findAny().orElse("找不到!");
|
||||
String result4 = list.stream().filter(str -> "李二".equals(str)).findAny().orElse("找不到!");
|
||||
|
||||
System.out.println("stream 过滤之后 2:" + result3);
|
||||
System.out.println("stream 过滤之后 3:" + result4);
|
||||
}
|
||||
|
||||
/**
|
||||
* 基本使用
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes", "unused" })
|
||||
private static void test2() {
|
||||
|
||||
/*
|
||||
* 构造流的几种方式
|
||||
*/
|
||||
Stream stream = Stream.of("a", "b", "c");
|
||||
String[] strArray = new String[] { "a", "b", "c" };
|
||||
stream = Stream.of(strArray);
|
||||
stream = Arrays.stream(strArray);
|
||||
List<String> list = Arrays.asList(strArray);
|
||||
stream = list.stream();
|
||||
|
||||
/*
|
||||
* 流之间的相互转化 一个 Stream 只可以使用一次,这段代码为了简洁而重复使用了数次,因此会抛出异常
|
||||
*/
|
||||
try {
|
||||
Stream<String> stream2 = Stream.of("a", "b", "c");
|
||||
// 转换成 Array
|
||||
String[] strArray1 = stream2.toArray(String[]::new);
|
||||
|
||||
// 转换成 Collection
|
||||
List<String> list1 = stream2.collect(Collectors.toList());
|
||||
List<String> list2 = stream2.collect(Collectors.toCollection(ArrayList::new));
|
||||
|
||||
Set set1 = stream2.collect(Collectors.toSet());
|
||||
Stack stack1 = stream2.collect(Collectors.toCollection(Stack::new));
|
||||
|
||||
// 转换成 String
|
||||
String str = stream.collect(Collectors.joining()).toString();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
/*
|
||||
* 汇总操作
|
||||
*/
|
||||
List<User> lists = new ArrayList<User>();
|
||||
lists.add(new User(6, "张三"));
|
||||
lists.add(new User(2, "李四"));
|
||||
lists.add(new User(3, "王五"));
|
||||
lists.add(new User(1, "张三"));
|
||||
// 计算这个list中出现 "张三" id的值
|
||||
int sum = lists.stream().filter(u -> "张三".equals(u.getName())).mapToInt(u -> u.getId()).sum();
|
||||
|
||||
System.out.println("计算结果:" + sum); // 7
|
||||
|
||||
/*
|
||||
* 数值类型的流 包括IntStream, LongStream和DoubleStream
|
||||
*/
|
||||
System.out.println("遍历输出该数组的数据:");
|
||||
IntStream.of(new int[] { 1, 2, 3, 4 }).forEach(System.out::println);
|
||||
System.out.println("查询范围在 2-3(2<=i<3)之间的数据:");
|
||||
IntStream.range(2, 3).forEach(System.out::println);
|
||||
System.out.println("查询范围在2-3(2<=i<=3)之间的数据:");
|
||||
IntStream.rangeClosed(2, 3).forEach(System.out::println);
|
||||
|
||||
/* stream中的 map使用 */
|
||||
|
||||
/*
|
||||
* 转换大写
|
||||
*/
|
||||
List<String> list3 = Arrays.asList("zhangSan", "liSi", "wangWu");
|
||||
System.out.println("转换之前的数据:" + list3);// 转换之前的数据:[zhangSan, liSi,
|
||||
// wangWu]
|
||||
List<String> list4 = list3.stream().map(String::toUpperCase).collect(Collectors.toList());
|
||||
System.out.println("转换之后的数据:" + list4); // 转换之后的数据:[ZHANGSAN, LISI,
|
||||
// WANGWU]
|
||||
|
||||
/*
|
||||
* 转换数据类型
|
||||
*/
|
||||
List<String> list31 = Arrays.asList("1", "2", "3");
|
||||
System.out.println("转换之前的数据:" + list31);// 转换之前的数据:[1, 2, 3]
|
||||
List<Integer> list41 = list31.stream().map(Integer::valueOf).collect(Collectors.toList());
|
||||
System.out.println("转换之后的数据:" + list41); // [1, 2, 3]
|
||||
|
||||
|
||||
/*
|
||||
* 转换数据类型
|
||||
* 对象转map
|
||||
*/
|
||||
List<User> list32 = new ArrayList<User>();
|
||||
for(int i=1;i<=10;i++){
|
||||
list32.add(new User(i,"张三"+i));
|
||||
}
|
||||
|
||||
System.out.println("转换之前的数据:" + list32);// 转换之前的数据:[1, 2, 3]
|
||||
List<Map> list42 = list32.stream().map(User::toMap).collect(Collectors.toList());
|
||||
System.out.println("转换之后的数据:" + list42); // [1, 2, 3]
|
||||
|
||||
|
||||
/*
|
||||
* 获取平方
|
||||
*/
|
||||
List<Integer> list5 = Arrays.asList(new Integer[] { 1, 2, 3, 4, 5 });
|
||||
List<Integer> list6 = list5.stream().map(n -> n * n).collect(Collectors.toList());
|
||||
System.out.println("平方的数据:" + list6);// 转换之前的数据:[1, 4, 9, 16, 25]
|
||||
|
||||
/*
|
||||
* flatMap 一对多 得到多个数组里面的数字
|
||||
*/
|
||||
Stream<List<Integer>> inputStream = Stream.of(Arrays.asList(1), Arrays.asList(2, 3), Arrays.asList(4, 5, 6));
|
||||
Stream<Integer> outputStream = inputStream.flatMap((childList) -> childList.stream());
|
||||
System.out.println("打印 stream中的数字:");
|
||||
outputStream.forEach(System.out::println);
|
||||
|
||||
/*
|
||||
* 得到一段句子中的单词
|
||||
*/
|
||||
String worlds = "Never let success get to your head and never let failure get to your heart.";
|
||||
List<String> list7 = new ArrayList<>();
|
||||
list7.add(worlds);
|
||||
List<String> list8 = list7.stream().flatMap(str -> Stream.of(str.split(" ")))
|
||||
.filter(world -> world.length() > 0).collect(Collectors.toList());
|
||||
System.out.println("单词:");
|
||||
list8.forEach(System.out::println);
|
||||
|
||||
/*
|
||||
* peek 对每个元素执行操作并返回一个新的 Stream
|
||||
*/
|
||||
System.out.println("peek使用:");
|
||||
Stream.of("one", "two", "three", "four").filter(e -> e.length() > 3).peek(e -> System.out.println("转换之前: " + e))
|
||||
.map(String::toUpperCase).peek(e -> System.out.println("转换之后: " + e)).collect(Collectors.toList());
|
||||
|
||||
/*
|
||||
* limit 和 skip limit 返回 Stream 的前面 n 个元素;skip 则是扔掉前 n 个元素(它是由一个叫
|
||||
* subStream 的方法改名而来)。
|
||||
*/
|
||||
List<User> list9 = new ArrayList<User>();
|
||||
for (int i = 1; i < 10; i++) {
|
||||
User user = new User(i, "pancm" + i);
|
||||
list9.add(user);
|
||||
}
|
||||
System.out.println("截取之前的数据:");
|
||||
// 取前5条数据,但是扔掉了前面的3条,可以理解为拿到的数据为 3<=i<5 (i 是数值下标)
|
||||
List<String> list10 = list9.stream().map(User::getName).limit(5).skip(3).collect(Collectors.toList());
|
||||
System.out.println("截取之后的数据:" + list10);
|
||||
|
||||
/*
|
||||
* sort 进行排序 先获取在排序效率更高
|
||||
*/
|
||||
System.out.println("排序之前的数据:");
|
||||
List<User> list11 = list9.stream().sorted((u1, u2) -> u1.getName().compareTo(u2.getName())).limit(3)
|
||||
.collect(Collectors.toList());
|
||||
System.out.println("排序之后的数据:" + list11);
|
||||
List<User> list12 = list9.stream().limit(3).sorted((u1, u2) -> u1.getName().compareTo(u2.getName()))
|
||||
.collect(Collectors.toList());
|
||||
System.out.println("优化排序之后的数据:" + list12);
|
||||
|
||||
/*
|
||||
* min/max/distinct
|
||||
* 最大,最小和去重
|
||||
*/
|
||||
BufferedReader br;
|
||||
int longest = 0;
|
||||
List<String> words = null;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader("test.properties"));
|
||||
longest = br.lines().mapToInt(String::length).max().getAsInt();
|
||||
br.close();
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
System.out.println("test.properties 最长的字符串的长度是:" + longest);
|
||||
|
||||
String lines = "good good study day day up";
|
||||
List<String> list13 = new ArrayList<String>();
|
||||
list13.add(lines);
|
||||
words = list13.stream().flatMap(line -> Stream.of(line.split(" "))).filter(word -> word.length() > 0)
|
||||
.map(String::toLowerCase).distinct().sorted().collect(Collectors.toList());
|
||||
System.out.println("去重复之后:" + words);
|
||||
|
||||
/*
|
||||
* Match 匹配
|
||||
*
|
||||
* allMatch:Stream 中全部元素符合传入的 predicate,返回 true anyMatch:Stream
|
||||
* 中只要有一个元素符合传入的 predicate,返回 true noneMatch:Stream 中没有一个元素符合传入的
|
||||
* predicate,返回 true
|
||||
*/
|
||||
|
||||
boolean all = lists.stream().allMatch(u -> u.getId() > 3);
|
||||
System.out.println("是否都大于3:" + all);
|
||||
boolean any = lists.stream().anyMatch(u -> u.getId() > 3);
|
||||
System.out.println("是否有一个大于3:" + any);
|
||||
boolean none = lists.stream().noneMatch(u -> u.getId() > 3);
|
||||
System.out.println("是否没有一个大于3的:" + none);
|
||||
|
||||
/*
|
||||
* 生成随机数 通过实现 Supplier 接口,你可以自己来控制流的生成。这种情形通常用于随机数、常量的
|
||||
* Stream,或者需要前后元素间维持着某种状态信息的 Stream。 把 Supplier 实例传递给 Stream.generate()
|
||||
* 生成的 Stream,默认是串行(相对 parallel 而言)但无序的(相对 ordered 而言)。
|
||||
* 由于它是无限的,在管道中,必须利用 limit 之类的操作限制 Stream 大小。
|
||||
*/
|
||||
Random seed = new Random();
|
||||
Supplier<Integer> random = seed::nextInt;
|
||||
System.out.println("生成5个随机数:");
|
||||
Stream.generate(random).limit(5).forEach(System.out::println);
|
||||
System.out.println("生成5正整数的随机数:");
|
||||
IntStream.generate(() -> (int) (System.nanoTime() % 100)).limit(5).forEach(System.out::println);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 一些关联使用
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private static void test3() {
|
||||
|
||||
/*
|
||||
* Optional
|
||||
*/
|
||||
String strA = " abcd ", strB = null;
|
||||
System.out.println("数据校验开始...");
|
||||
print(strA);
|
||||
print("");
|
||||
print(strB);
|
||||
getLength(strA);
|
||||
getLength("");
|
||||
getLength(strB);
|
||||
System.out.println("数据校验结束...");
|
||||
|
||||
/*
|
||||
* reduce 主要作用是把 Stream 元素组合起来。
|
||||
*/
|
||||
// 字符串连接,concat = "ABCD"
|
||||
String concat = Stream.of("A", "B", "C", "D").reduce("", String::concat);
|
||||
System.out.println("字符串拼接:" + concat);
|
||||
// 求最小值,minValue = -3.0
|
||||
double minValue = Stream.of(-1.5, 1.0, -3.0, -2.0).reduce(Double.MAX_VALUE, Double::min);
|
||||
System.out.println("最小值:" + minValue);
|
||||
// 求和,sumValue = 10, 有起始值
|
||||
int sumValue = Stream.of(1, 2, 3, 4).reduce(0, Integer::sum);
|
||||
System.out.println("求和:" + sumValue);
|
||||
// 求和,sumValue = 10, 无起始值
|
||||
sumValue = Stream.of(1, 2, 3, 4).reduce(Integer::sum).get();
|
||||
System.out.println("求和:" + sumValue);
|
||||
// 过滤,字符串连接,concat = "ace"
|
||||
concat = Stream.of("a", "B", "c", "D", "e", "F").filter(x -> x.compareTo("Z") > 0).reduce("", String::concat);
|
||||
System.out.println("过滤和字符串连接:" + concat);
|
||||
|
||||
/*
|
||||
* iterate iterate 跟 reduce 操作很像,接受一个种子值,和一个 UnaryOperator(例如 f)。
|
||||
* 然后种子值成为 Stream 的第一个元素,f(seed) 为第二个,f(f(seed)) 第三个,以此类推。 在 iterate
|
||||
* 时候管道必须有 limit 这样的操作来限制 Stream 大小。
|
||||
*/
|
||||
// 生成一个等差队列
|
||||
Stream.iterate(0, n -> n + 3).limit(10).forEach(x -> System.out.print(x + " "));
|
||||
|
||||
/*
|
||||
* 分组排序 groupingBy/partitioningBy
|
||||
*/
|
||||
// 通过id进行排序
|
||||
System.out.println("通过id进行分组排序:");
|
||||
Map<Integer, List<User>> personGroups = Stream.generate(new UserSupplier2()).limit(5)
|
||||
.collect(Collectors.groupingBy(User::getId));
|
||||
Iterator it = personGroups.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry<Integer, List<User>> persons = (Map.Entry) it.next();
|
||||
System.out.println("id " + persons.getKey() + " = " + persons.getValue());
|
||||
}
|
||||
|
||||
//通过年龄排序
|
||||
System.out.println("进行分区排序:");
|
||||
Map<Boolean, List<User>> children = Stream.generate(new UserSupplier2()).limit(5)
|
||||
.collect(Collectors.partitioningBy(p -> p.getId() < 18));
|
||||
|
||||
System.out.println("小孩: " + children.get(true));
|
||||
System.out.println("成年人: " + children.get(false));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义流
|
||||
*/
|
||||
private static void test4() {
|
||||
|
||||
/*
|
||||
* 自定义一个流 然后进行输出
|
||||
*/
|
||||
Stream.generate(new UserSupplier()).limit(2).forEach(u -> System.out.println(u.getId() + ", " + u.getName()));
|
||||
|
||||
}
|
||||
|
||||
public static void print(String text) {
|
||||
// jdk1.8之前的写法
|
||||
// if (text != null) {
|
||||
// System.out.println(text);
|
||||
// }
|
||||
// jdk1.8的写法
|
||||
Optional.ofNullable(text).ifPresent(System.out::println);
|
||||
}
|
||||
|
||||
public static void getLength(String text) {
|
||||
// jdk1.8之前的写法
|
||||
// return if (text != null) ? text.length() : -1;
|
||||
// jdk1.8的写法
|
||||
int i = Optional.ofNullable(text).map(String::length).orElse(-1);
|
||||
System.out.println("数据:" + i);
|
||||
};
|
||||
}
|
||||
|
||||
class UserSupplier implements Supplier<User> {
|
||||
private int index = 10;
|
||||
private Random random = new Random();
|
||||
|
||||
@Override
|
||||
public User get() {
|
||||
return new User(index++, "pancm" + random.nextInt(10));
|
||||
}
|
||||
}
|
||||
|
||||
class UserSupplier2 implements Supplier<User> {
|
||||
private int index = 10;
|
||||
private Random random = new Random();
|
||||
|
||||
@Override
|
||||
public User get() {
|
||||
return new User(index % 2 == 0 ? index++ : index, "pancm" + random.nextInt(10));
|
||||
}
|
||||
}
|
||||
116
src/main/java/com/pancm/jdk8/TimeTest.java
Normal file
116
src/main/java/com/pancm/jdk8/TimeTest.java
Normal file
@ -0,0 +1,116 @@
|
||||
package com.pancm.jdk8;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.Month;
|
||||
import java.time.Period;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
|
||||
/**
|
||||
* @Title: TimeTest
|
||||
* @Description:
|
||||
* 时间测试
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年6月21日
|
||||
*/
|
||||
public class TimeTest {
|
||||
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
test();
|
||||
test2();
|
||||
test3();
|
||||
test4();
|
||||
}
|
||||
|
||||
/**
|
||||
* 时间测试
|
||||
*/
|
||||
private static void test(){
|
||||
//获取当前的时间,包括毫秒
|
||||
LocalDateTime ldt = LocalDateTime.now();
|
||||
// String time="2018-06-29 09:19:45.498";
|
||||
String time2="2018-01-04T09:19:29.499";
|
||||
//格式化时间
|
||||
LocalDateTime ldt2=LocalDateTime.parse(time2);
|
||||
System.out.println("当前年:"+ldt.getYear()); //2018
|
||||
System.out.println("当前年份天数:"+ldt.getDayOfYear());//172
|
||||
System.out.println("当前月:"+ldt.getMonthValue());
|
||||
System.out.println("当前时:"+ldt.getHour());
|
||||
System.out.println("当前分:"+ldt.getMinute());
|
||||
System.out.println("当前时间:"+ldt.toString());
|
||||
System.out.println("格式化时间:"+ ldt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")));
|
||||
System.out.println("前5天时间:"+ldt.minusDays(5).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); //2018-06-16
|
||||
System.out.println("后5天时间:"+ldt.plusDays(5));
|
||||
System.out.println("指定2099年的当前时间:"+ldt.withYear(2099)); //2099-06-21T15:07:39.506
|
||||
|
||||
System.out.println("前一个月的时间:"+ldt2.minusMonths(1).format(DateTimeFormatter.ofPattern("yyyyMM"))); //2018-06-16
|
||||
System.out.println("后一个月的时间:"+ldt2.plusMonths(1)); //2018-06-16
|
||||
System.out.println("得到的时间:"+ldt2.toString());
|
||||
System.out.println("格式化时间:"+ldt2.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static void test2(){
|
||||
LocalDate ld=LocalDate.parse("2017-11-17");
|
||||
LocalDate ld2=LocalDate.parse("2018-01-05");
|
||||
|
||||
LocalDate ld3=LocalDate.of(2017, 11, 01);
|
||||
LocalDate ld4=LocalDate.of(2018, 01, 01);
|
||||
//jdk1.8的类,用于比较时间
|
||||
//可以得到相差年、月、日
|
||||
Period p=Period.between(ld, ld2);
|
||||
System.out.println("相差年: "+p.getYears()+" 相差月 :"+p.getMonths() +" 相差天:"+p.getDays());
|
||||
System.out.println("增加2个月: "+ld.plusMonths(2));
|
||||
// 相差年: 0 相差月 :1 相差天:19
|
||||
|
||||
Period p2=Period.between(ld3, ld4);
|
||||
System.out.println("相差年: "+p2.getYears()+" 相差月 :"+p2.getMonths() +" 相差天:"+p2.getDays()+"--"+p2.toTotalMonths());
|
||||
//相差年: 0 相差月 :2 相差天:0
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static void test3(){
|
||||
Instant inst1 = Instant.now();
|
||||
System.out.println("Inst1 : " + inst1);
|
||||
Instant inst2 = inst1.plus(Duration.ofSeconds(10));
|
||||
System.out.println("Inst2 : " + inst2);
|
||||
|
||||
System.out.println("相差毫秒 : " + Duration.between(inst1, inst2).toMillis());
|
||||
|
||||
System.out.println("相毫秒 : " + Duration.between(inst1, inst2).getSeconds());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 单个时间单位内测量一段时间
|
||||
*/
|
||||
private static void test4(){
|
||||
//2017-11-19
|
||||
LocalDate startDate = LocalDate.of(2017, Month.NOVEMBER, 01);
|
||||
System.out.println("开始时间 : " + startDate);
|
||||
|
||||
//2018-1-16
|
||||
LocalDate endDate = LocalDate.of(2018, Month.JANUARY, 01);
|
||||
System.out.println("结束时间 : " + endDate);
|
||||
|
||||
System.out.println("相差月份:"+ChronoUnit.MONTHS.between(startDate, endDate));
|
||||
long daysDiff = ChronoUnit.DAYS.between(startDate, endDate);
|
||||
System.out.println("两天之间的差在天数 : " + daysDiff);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
12
src/main/java/com/pancm/jdk8/package-info.java
Normal file
12
src/main/java/com/pancm/jdk8/package-info.java
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* @Title: package-info
|
||||
* @Description:
|
||||
* jdk1.8测试用例
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年5月14日
|
||||
*/
|
||||
package com.pancm.jdk8;
|
||||
83
src/main/java/com/pancm/mq/kafka/KafkaProducerTest.java
Normal file
83
src/main/java/com/pancm/mq/kafka/KafkaProducerTest.java
Normal file
@ -0,0 +1,83 @@
|
||||
package com.pancm.mq.kafka;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.kafka.clients.producer.KafkaProducer;
|
||||
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||
import org.apache.kafka.common.serialization.StringSerializer;
|
||||
|
||||
/**
|
||||
*
|
||||
* Title: kafkaTest
|
||||
* Description:
|
||||
* kafka测试
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年1月11日
|
||||
*/
|
||||
public class KafkaProducerTest {
|
||||
|
||||
private static KafkaProducer<String, String> producer;
|
||||
private final String topic;
|
||||
private int k=10;
|
||||
|
||||
/**
|
||||
* @param topic 消息名称
|
||||
* @param
|
||||
*/
|
||||
public KafkaProducerTest(String topic) {
|
||||
Properties props = new Properties();
|
||||
props.put("bootstrap.servers", "master:9092,slave1:9092,slave2:9092");
|
||||
props.put("acks", "all");
|
||||
props.put("retries", 0);
|
||||
props.put("batch.size", 16384);
|
||||
props.put("linger.ms", 1);
|
||||
props.put("buffer.memory", 33554432);
|
||||
props.put("key.serializer", StringSerializer.class.getName());
|
||||
props.put("value.serializer", StringSerializer.class.getName());
|
||||
this.producer = new KafkaProducer<String, String>(props);
|
||||
this.topic = topic;
|
||||
}
|
||||
|
||||
|
||||
private void start(){
|
||||
int messageNo = 0;
|
||||
try {
|
||||
while (true) {
|
||||
String messageStr = "insert into t_user(name,age) values ('李四',"+messageNo*10+1+")" ;
|
||||
// StringBuffer sb=new StringBuffer();
|
||||
// for(int i=1;i<=k;i++){
|
||||
// int count=k*messageNo+i;
|
||||
// messageStr="insert into t_user(id,name,age) values ("+count+",'李四',"+count+10+")" ;
|
||||
// sb.append(messageStr);
|
||||
// sb.append(";");
|
||||
// }
|
||||
// sb.deleteCharAt(sb.lastIndexOf(";"));
|
||||
// producer.send(new ProducerRecord<String, String>(topic, "Message", sb.toString()));
|
||||
producer.send(new ProducerRecord<String, String>(topic, "Message", messageStr));
|
||||
messageNo++;
|
||||
//生产了100条就打印
|
||||
if(messageNo%100==0){
|
||||
System.out.println("Send:" + messageStr);
|
||||
}
|
||||
//生产100条就退出
|
||||
if(messageNo%100==0){
|
||||
System.out.println("成功发送了"+messageNo+"条");
|
||||
break;
|
||||
}
|
||||
// Utils.sleep(1);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
producer.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
KafkaProducerTest test =new KafkaProducerTest("INSERT_TOPIC11");
|
||||
test.start();
|
||||
}
|
||||
|
||||
}
|
||||
64
src/main/java/com/pancm/mq/kafka/examples/Consumer.java
Normal file
64
src/main/java/com/pancm/mq/kafka/examples/Consumer.java
Normal file
@ -0,0 +1,64 @@
|
||||
package com.pancm.mq.kafka.examples;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecords;
|
||||
import org.apache.kafka.clients.consumer.KafkaConsumer;
|
||||
import org.apache.kafka.common.serialization.StringDeserializer;
|
||||
|
||||
/**
|
||||
*
|
||||
* Title: Consumer
|
||||
* Description: kafka消费者
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2017年12月29日
|
||||
*/
|
||||
public class Consumer extends Thread {
|
||||
|
||||
private final KafkaConsumer<String, String> consumer;
|
||||
private final String topic;
|
||||
private static final String GROUPID = "test-consumer-group";
|
||||
|
||||
public Consumer(String kafkaStr, String topic) {
|
||||
Properties props = new Properties();
|
||||
props.put("bootstrap.servers", kafkaStr);
|
||||
props.put("group.id", GROUPID);
|
||||
props.put("enable.auto.commit", "true");
|
||||
props.put("auto.commit.interval.ms", "1000");
|
||||
props.put("session.timeout.ms", "30000");
|
||||
props.put("key.deserializer", StringDeserializer.class.getName());
|
||||
props.put("value.deserializer", StringDeserializer.class.getName());
|
||||
this.consumer = new KafkaConsumer<String, String>(props);
|
||||
this.topic = topic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
this.consumer.subscribe(Arrays.asList(topic));
|
||||
int messageNo = 1;
|
||||
System.out.println("消费开始---------");
|
||||
try {
|
||||
while (true) {
|
||||
ConsumerRecords<String, String> records = consumer.poll(100);
|
||||
for (ConsumerRecord<String, String> record : records) {
|
||||
//消费100条就打印
|
||||
//打印的数据不一定是这个规律的
|
||||
if(messageNo%100==0){
|
||||
System.out.println("receive: key = " + record.key() + ", value = " + record.value());
|
||||
}
|
||||
}
|
||||
//当消费了1000条就退出
|
||||
if(messageNo%1000==0){
|
||||
break;
|
||||
}
|
||||
messageNo++;
|
||||
}
|
||||
} finally {
|
||||
consumer.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
70
src/main/java/com/pancm/mq/kafka/examples/DataProducer.java
Normal file
70
src/main/java/com/pancm/mq/kafka/examples/DataProducer.java
Normal file
@ -0,0 +1,70 @@
|
||||
package com.pancm.mq.kafka.examples;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
|
||||
import org.apache.kafka.clients.producer.KafkaProducer;
|
||||
import org.apache.kafka.clients.producer.Producer;
|
||||
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||
|
||||
public class DataProducer {
|
||||
private static Random random = new Random(93285);
|
||||
private static Producer<String, String> producer;
|
||||
|
||||
public static void main(String args[]) {
|
||||
Properties props = new Properties();
|
||||
props.put("bootstrap.servers", "192.168.125.172:9092");
|
||||
props.put("acks", "all");
|
||||
props.put("retries", 0);
|
||||
props.put("batch.size", 16384);
|
||||
props.put("linger.ms", 1);
|
||||
props.put("buffer.memory", 33554432);
|
||||
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
|
||||
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
|
||||
producer = new KafkaProducer<>(props);
|
||||
int count = 0;
|
||||
long startTime = System.nanoTime(); // 获取开始时间
|
||||
int tdata = 0;
|
||||
double hdata = 0.0;
|
||||
while (true) {
|
||||
int choise = 0 + random.nextInt(10000);
|
||||
switch (choise) {
|
||||
case 0:
|
||||
tdata = createRandom(-30, -20);
|
||||
hdata = createRandom(0.0, 4.9);
|
||||
break;
|
||||
case 9999:
|
||||
tdata = createRandom(60, 70);
|
||||
hdata = createRandom(96.0, 100.0);
|
||||
break;
|
||||
default:
|
||||
tdata = createRandom(-19, 59);
|
||||
hdata = createRandom(5.0, 95.9);
|
||||
break;
|
||||
}
|
||||
producer.send(new ProducerRecord<String, String>(args[0], "temper:" + tdata + "," + "humi:" + hdata));
|
||||
long endTime = System.nanoTime();
|
||||
count++;
|
||||
int a = (int) ((endTime - startTime) * Math.pow(10, -9));
|
||||
if (a == 1) {
|
||||
System.out.println(args[0] + "每秒发送:" + count + "条数据");
|
||||
count = 0;
|
||||
startTime = System.nanoTime();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static int createRandom(int min, int max) {
|
||||
return min + random.nextInt(max - min);
|
||||
}
|
||||
|
||||
private static double createRandom(double min, double max) {
|
||||
if (min == 0) {
|
||||
return max - random.nextDouble();
|
||||
}
|
||||
return max - random.nextDouble() * min;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.pancm.mq.kafka.examples;
|
||||
|
||||
public class KafkaProducerConsumerDemo {
|
||||
|
||||
public static final String KAFKASTR = "master:9092";
|
||||
|
||||
public static void main(String[] args) {
|
||||
new Producer(KAFKASTR, "pcm_test1").start(); // args[0] 为要发送的 topic
|
||||
// new Consumer(KAFKASTR, "pcm_test1").start(); // args[0] 为要接收的 topic
|
||||
}
|
||||
}
|
||||
67
src/main/java/com/pancm/mq/kafka/examples/Producer.java
Normal file
67
src/main/java/com/pancm/mq/kafka/examples/Producer.java
Normal file
@ -0,0 +1,67 @@
|
||||
package com.pancm.mq.kafka.examples;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.kafka.clients.producer.KafkaProducer;
|
||||
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||
import org.apache.kafka.common.serialization.StringSerializer;
|
||||
|
||||
/**
|
||||
*
|
||||
* Title: Producer
|
||||
* Description: kafka生产者 由于生产消息
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2017年12月29日
|
||||
*/
|
||||
public class Producer extends Thread {
|
||||
|
||||
private final KafkaProducer<String, String> producer;
|
||||
private final String topic;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param kafkaStr kafka地址
|
||||
* @param topic 消息名称
|
||||
* @param
|
||||
*/
|
||||
public Producer(String kafkaStr, String topic) {
|
||||
Properties props = new Properties();
|
||||
props.put("bootstrap.servers", kafkaStr);
|
||||
props.put("acks", "all");
|
||||
props.put("retries", 0);
|
||||
props.put("batch.size", 16384);
|
||||
props.put("linger.ms", 1);
|
||||
props.put("buffer.memory", 33554432);
|
||||
props.put("key.serializer", StringSerializer.class.getName());
|
||||
props.put("value.serializer", StringSerializer.class.getName());
|
||||
this.producer = new KafkaProducer<String, String>(props);
|
||||
this.topic = topic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
int messageNo = 1;
|
||||
try {
|
||||
while (true) {
|
||||
String messageStr = "Message_" + messageNo;
|
||||
//生产了100条就打印
|
||||
if(messageNo%100==0){
|
||||
System.out.println("Send:" + messageStr);
|
||||
}
|
||||
//生产1000条就退出
|
||||
// if(messageNo%1000==0){
|
||||
// break;
|
||||
// }
|
||||
producer.send(new ProducerRecord<String, String>(topic, "Message", messageStr));
|
||||
messageNo++;
|
||||
sleep(10);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
producer.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
88
src/main/java/com/pancm/mq/kafka/examples/WordCountDemo.java
Normal file
88
src/main/java/com/pancm/mq/kafka/examples/WordCountDemo.java
Normal file
@ -0,0 +1,88 @@
|
||||
package com.pancm.mq.kafka.examples;
|
||||
|
||||
import org.apache.kafka.clients.consumer.ConsumerConfig;
|
||||
import org.apache.kafka.common.serialization.Serdes;
|
||||
import org.apache.kafka.streams.KafkaStreams;
|
||||
import org.apache.kafka.streams.StreamsBuilder;
|
||||
import org.apache.kafka.streams.StreamsConfig;
|
||||
import org.apache.kafka.streams.kstream.KStream;
|
||||
import org.apache.kafka.streams.kstream.KTable;
|
||||
import org.apache.kafka.streams.kstream.KeyValueMapper;
|
||||
import org.apache.kafka.streams.kstream.Produced;
|
||||
import org.apache.kafka.streams.kstream.ValueMapper;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
/**
|
||||
* Demonstrates, using the high-level KStream DSL, how to implement the WordCount program
|
||||
* that computes a simple word occurrence histogram from an input text.
|
||||
*
|
||||
* In this example, the input stream reads from a topic named "streams-plaintext-input", where the values of messages
|
||||
* represent lines of text; and the histogram output is written to topic "streams-wordcount-output" where each record
|
||||
* is an updated count of a single word.
|
||||
*
|
||||
* Before running this example you must create the input topic and the output topic (e.g. via
|
||||
* bin/kafka-topics.sh --create ...), and write some data to the input topic (e.g. via
|
||||
* bin/kafka-console-producer.sh). Otherwise you won't see any data arriving in the output topic.
|
||||
*/
|
||||
public class WordCountDemo {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Properties props = new Properties();
|
||||
props.put(StreamsConfig.APPLICATION_ID_CONFIG, "streams-wordcount");
|
||||
props.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "192.169.0.23:9092");
|
||||
props.put(StreamsConfig.CACHE_MAX_BYTES_BUFFERING_CONFIG, 0);
|
||||
props.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName());
|
||||
props.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName());
|
||||
|
||||
// setting offset reset to earliest so that we can re-run the demo code with the same pre-loaded data
|
||||
// Note: To re-run the demo, you need to use the offset reset tool:
|
||||
// https://cwiki.apache.org/confluence/display/KAFKA/Kafka+Streams+Application+Reset+Tool
|
||||
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
|
||||
|
||||
StreamsBuilder builder = new StreamsBuilder();
|
||||
|
||||
KStream<String, String> source = builder.stream("streams-plaintext-input");
|
||||
|
||||
KTable<String, Long> counts = source
|
||||
.flatMapValues(new ValueMapper<String, Iterable<String>>() {
|
||||
@Override
|
||||
public Iterable<String> apply(String value) {
|
||||
return Arrays.asList(value.toLowerCase(Locale.getDefault()).split(" "));
|
||||
}
|
||||
})
|
||||
.groupBy(new KeyValueMapper<String, String, String>() {
|
||||
@Override
|
||||
public String apply(String key, String value) {
|
||||
return value;
|
||||
}
|
||||
})
|
||||
.count();
|
||||
|
||||
// need to override value serde to Long type
|
||||
counts.toStream().to("streams-wordcount-output", Produced.with(Serdes.String(), Serdes.Long()));
|
||||
|
||||
final KafkaStreams streams = new KafkaStreams(builder.build(), props);
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
// attach shutdown handler to catch control-c
|
||||
Runtime.getRuntime().addShutdownHook(new Thread("streams-wordcount-shutdown-hook") {
|
||||
@Override
|
||||
public void run() {
|
||||
streams.close();
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
streams.start();
|
||||
latch.await();
|
||||
} catch (Throwable e) {
|
||||
System.exit(1);
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
11
src/main/java/com/pancm/mq/kafka/examples/package-info.java
Normal file
11
src/main/java/com/pancm/mq/kafka/examples/package-info.java
Normal file
@ -0,0 +1,11 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* Title: package-info
|
||||
* Description:
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2017年12月29日
|
||||
*/
|
||||
package com.pancm.mq.kafka.examples;
|
||||
43
src/main/java/com/pancm/mq/kafka/others/TestConsumer.java
Normal file
43
src/main/java/com/pancm/mq/kafka/others/TestConsumer.java
Normal file
@ -0,0 +1,43 @@
|
||||
package com.pancm.mq.kafka.others;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecords;
|
||||
import org.apache.kafka.clients.consumer.KafkaConsumer;
|
||||
|
||||
public class TestConsumer {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Properties props = new Properties();
|
||||
|
||||
props.put("bootstrap.servers", "192.169.0.23:9092");
|
||||
System.out.println("this is the group part test 1");
|
||||
//消费者的组id
|
||||
props.put("group.id", "GroupA");//这里是GroupA或者GroupB
|
||||
|
||||
props.put("enable.auto.commit", "true");
|
||||
props.put("auto.commit.interval.ms", "1000");
|
||||
|
||||
//从poll(拉)的回话处理时长
|
||||
props.put("session.timeout.ms", "30000");
|
||||
//poll的数量限制
|
||||
//props.put("max.poll.records", "100");
|
||||
|
||||
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
|
||||
|
||||
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
|
||||
|
||||
KafkaConsumer<String, String> consumer = new KafkaConsumer<String, String>(props);
|
||||
//订阅主题列表topic
|
||||
consumer.subscribe(Arrays.asList("foo"));
|
||||
while (true) {
|
||||
ConsumerRecords<String, String> records =consumer.poll(100);
|
||||
for (ConsumerRecord<String, String> record : records)
|
||||
// 正常这里应该使用线程池处理,不应该在这里处理
|
||||
System.out.printf("offset = %d, key = %s, value = %s", record.offset(), record.key(), record.value()+"\n");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
46
src/main/java/com/pancm/mq/kafka/others/TestProducer.java
Normal file
46
src/main/java/com/pancm/mq/kafka/others/TestProducer.java
Normal file
@ -0,0 +1,46 @@
|
||||
package com.pancm.mq.kafka.others;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.kafka.clients.producer.KafkaProducer;
|
||||
import org.apache.kafka.clients.producer.Producer;
|
||||
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||
|
||||
public class TestProducer {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("开始...");
|
||||
Properties props = new Properties();
|
||||
props.put("bootstrap.servers", "192.169.0.23:9092");
|
||||
//The "all" setting we have specified will result in blocking on the full commit of the record, the slowest but most durable setting.
|
||||
//“所有”设置将导致记录的完整提交阻塞,最慢的,但最持久的设置。
|
||||
props.put("acks", "all");
|
||||
//如果请求失败,生产者也会自动重试,即使设置成0 the producer can automatically retry.
|
||||
props.put("retries", 0);
|
||||
|
||||
//The producer maintains buffers of unsent records for each partition.
|
||||
props.put("batch.size", 16384);
|
||||
//默认立即发送,这里这是延时毫秒数
|
||||
props.put("linger.ms", 1);
|
||||
//生产者缓冲大小,当缓冲区耗尽后,额外的发送调用将被阻塞。时间超过max.block.ms将抛出TimeoutException
|
||||
props.put("buffer.memory", 33554432);
|
||||
//The key.serializer and value.serializer instruct how to turn the key and value objects the user provides with their ProducerRecord into bytes.
|
||||
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
|
||||
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
|
||||
|
||||
//创建kafka的生产者类
|
||||
Producer<String, String> producer = new KafkaProducer<String, String>(props);
|
||||
long startTime=System.currentTimeMillis();
|
||||
producer.send(new ProducerRecord<String, String>("test1",1,startTime,"a","b"));
|
||||
producer.close();
|
||||
//生产者的主要方法
|
||||
// close();//Close this producer.
|
||||
// close(long timeout, TimeUnit timeUnit); //This method waits up to timeout for the producer to complete the sending of all incomplete requests.
|
||||
// flush() ;所有缓存记录被立刻发送
|
||||
// for(int i = 0; i < 100; i++){
|
||||
// //这里平均写入4个分区
|
||||
// producer.send(new ProducerRecord<String, String>("foo",i%4, Integer.toString(i), Integer.toString(i)));
|
||||
// producer.close();
|
||||
// }
|
||||
System.out.println("结束");
|
||||
}
|
||||
}
|
||||
11
src/main/java/com/pancm/mq/kafka/others/package-info.java
Normal file
11
src/main/java/com/pancm/mq/kafka/others/package-info.java
Normal file
@ -0,0 +1,11 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* Title: package-info
|
||||
* Description:
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2017年12月29日
|
||||
*/
|
||||
package com.pancm.mq.kafka.others;
|
||||
8
src/main/java/com/pancm/mq/kafka/package-info.java
Normal file
8
src/main/java/com/pancm/mq/kafka/package-info.java
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Title: package-info
|
||||
* Description: kafka的相关代码
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年1月11日
|
||||
*/
|
||||
package com.pancm.mq.kafka;
|
||||
@ -0,0 +1,95 @@
|
||||
package com.pancm.mq.kafka.test1;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecords;
|
||||
import org.apache.kafka.clients.consumer.KafkaConsumer;
|
||||
import org.apache.kafka.common.serialization.StringDeserializer;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Title: KafkaConsumerTest
|
||||
* Description:
|
||||
* kafka消费者 demo
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年1月26日
|
||||
*/
|
||||
public class KafkaConsumerTest implements Runnable {
|
||||
|
||||
private final KafkaConsumer<String, String> consumer;
|
||||
private ConsumerRecords<String, String> msgList;
|
||||
private String topic;
|
||||
private static final String GROUPID = "groupA";
|
||||
|
||||
|
||||
|
||||
public KafkaConsumerTest(String topicName) {
|
||||
Properties props = new Properties();
|
||||
//kafka消费的的地址
|
||||
props.put("bootstrap.servers", "master:9092,slave1:9092,slave2:9092");
|
||||
//组名 不同组名可以重复消费
|
||||
props.put("group.id", GROUPID);
|
||||
//是否自动提交
|
||||
props.put("enable.auto.commit", "true");
|
||||
//从poll(拉)的回话处理时长
|
||||
props.put("auto.commit.interval.ms", "1000");
|
||||
//超时时间
|
||||
props.put("session.timeout.ms", "30000");
|
||||
//一次最大拉取的条数
|
||||
props.put("max.poll.records", 1000);
|
||||
// earliest当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,从头开始消费
|
||||
// latest
|
||||
// 当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,消费新产生的该分区下的数据
|
||||
// none
|
||||
// topic各分区都存在已提交的offset时,从offset后开始消费;只要有一个分区不存在已提交的offset,则抛出异常
|
||||
props.put("auto.offset.reset", "earliest");
|
||||
//序列化
|
||||
props.put("key.deserializer", StringDeserializer.class.getName());
|
||||
props.put("value.deserializer", StringDeserializer.class.getName());
|
||||
this.consumer = new KafkaConsumer<String, String>(props);
|
||||
this.topic = topicName;
|
||||
//订阅主题列表topic
|
||||
this.consumer.subscribe(Arrays.asList(topic));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
int messageNo = 1;
|
||||
System.out.println("---------开始消费---------");
|
||||
try {
|
||||
for (;;) {
|
||||
msgList = consumer.poll(100);
|
||||
if(null!=msgList&&msgList.count()>0){
|
||||
for (ConsumerRecord<String, String> record : msgList) {
|
||||
//消费100条就打印 ,但打印的数据不一定是这个规律的
|
||||
if(messageNo%100==0){
|
||||
System.out.println(messageNo+"=======receive: key = " + record.key() + ", value = " + record.value()+" offset==="+record.offset());
|
||||
}
|
||||
//当消费了1000条就退出
|
||||
if(messageNo%1000==0){
|
||||
break;
|
||||
}
|
||||
messageNo++;
|
||||
}
|
||||
}else{
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
consumer.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
KafkaConsumerTest test1 = new KafkaConsumerTest("KAFKA_TEST");
|
||||
Thread thread1 = new Thread(test1);
|
||||
thread1.start();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,75 @@
|
||||
package com.pancm.mq.kafka.test1;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.kafka.clients.producer.KafkaProducer;
|
||||
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||
import org.apache.kafka.common.serialization.StringSerializer;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Title: KafkaProducerTest
|
||||
* Description:
|
||||
* kafka 生产者demo
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年1月26日
|
||||
*/
|
||||
public class KafkaProducerTest implements Runnable {
|
||||
|
||||
private final KafkaProducer<String, String> producer;
|
||||
private final String topic;
|
||||
|
||||
|
||||
public KafkaProducerTest(String topicName) {
|
||||
Properties props = new Properties();
|
||||
props.put("bootstrap.servers", "master:9092,slave1:9092,slave2:9092");
|
||||
//acks=0:如果设置为0,生产者不会等待kafka的响应。
|
||||
//acks=1:这个配置意味着kafka会把这条消息写到本地日志文件中,但是不会等待集群中其他机器的成功响应。
|
||||
//acks=all:这个配置意味着leader会等待所有的follower同步完成。这个确保消息不会丢失,除非kafka集群中所有机器挂掉。这是最强的可用性保证。
|
||||
props.put("acks", "all");
|
||||
//配置为大于0的值的话,客户端会在消息发送失败时重新发送。
|
||||
props.put("retries", 0);
|
||||
//当多条消息需要发送到同一个分区时,生产者会尝试合并网络请求。这会提高client和生产者的效率
|
||||
props.put("batch.size", 16384);
|
||||
props.put("key.serializer", StringSerializer.class.getName());
|
||||
props.put("value.serializer", StringSerializer.class.getName());
|
||||
this.producer = new KafkaProducer<String, String>(props);
|
||||
this.topic = topicName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
int messageNo = 1;
|
||||
try {
|
||||
for(;;) {
|
||||
String messageStr="你好,这是第"+messageNo+"条数据";
|
||||
producer.send(new ProducerRecord<String, String>(topic, "Message", messageStr));
|
||||
//生产了100条就打印
|
||||
if(messageNo%100==0){
|
||||
System.out.println("发送的信息:" + messageStr);
|
||||
}
|
||||
//生产1000条就退出
|
||||
if(messageNo%1000==0){
|
||||
System.out.println("成功发送了"+messageNo+"条");
|
||||
break;
|
||||
}
|
||||
messageNo++;
|
||||
// Utils.sleep(1);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
producer.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
KafkaProducerTest test = new KafkaProducerTest("KAFKA_TEST");
|
||||
Thread thread = new Thread(test);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
12
src/main/java/com/pancm/mq/kafka/test1/package-info.java
Normal file
12
src/main/java/com/pancm/mq/kafka/test1/package-info.java
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* Title: package-info
|
||||
* Description:
|
||||
* kafka demo
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年2月9日
|
||||
*/
|
||||
package com.pancm.mq.kafka.test1;
|
||||
112
src/main/java/com/pancm/mq/kafka/test2/KafkaConsumerTest.java
Normal file
112
src/main/java/com/pancm/mq/kafka/test2/KafkaConsumerTest.java
Normal file
@ -0,0 +1,112 @@
|
||||
package com.pancm.mq.kafka.test2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecords;
|
||||
import org.apache.kafka.clients.consumer.KafkaConsumer;
|
||||
import org.apache.kafka.common.serialization.StringDeserializer;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Title: KafkaConsumerTest
|
||||
* Description:
|
||||
* kafka消费者 demo
|
||||
* 手动提交测试
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年1月26日
|
||||
*/
|
||||
public class KafkaConsumerTest implements Runnable {
|
||||
|
||||
private KafkaConsumer<String, String> consumer;
|
||||
private ConsumerRecords<String, String> msgList;
|
||||
private String topic;
|
||||
private static final String GROUPID = "groupE4";
|
||||
|
||||
|
||||
|
||||
public KafkaConsumerTest(String topicName) {
|
||||
this.topic = topicName;
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println("---------开始消费---------");
|
||||
int messageNo = 1;
|
||||
List<String> list=new ArrayList<String>();
|
||||
List<Long> list2=new ArrayList<Long>();
|
||||
try {
|
||||
for (;;) {
|
||||
msgList = consumer.poll(100);
|
||||
if(null!=msgList&&msgList.count()>0){
|
||||
for (ConsumerRecord<String, String> record : msgList) {
|
||||
if(messageNo%10==0){
|
||||
System.out.println(messageNo+"=======receive: key = " + record.key() + ", value = " + record.value()+" offset==="+record.offset());
|
||||
}
|
||||
list.add(record.value());
|
||||
list2.add(record.offset());
|
||||
messageNo++;
|
||||
}
|
||||
if(list.size()==50){
|
||||
// 手动提交
|
||||
consumer.commitSync();
|
||||
System.out.println("成功提交"+list.size()+"条,此时的offset为:"+list2.get(49));
|
||||
}else if(list.size()>50){
|
||||
consumer.close();
|
||||
init();
|
||||
list.clear();
|
||||
list2.clear();
|
||||
}
|
||||
}else{
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
consumer.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
Properties props = new Properties();
|
||||
//kafka消费的的地址
|
||||
props.put("bootstrap.servers", "master:9092,slave1:9092,slave2:9092");
|
||||
//组名 不同组名可以重复消费
|
||||
props.put("group.id", GROUPID);
|
||||
//是否自动提交
|
||||
props.put("enable.auto.commit", "false");
|
||||
//超时时间
|
||||
props.put("session.timeout.ms", "30000");
|
||||
//一次最大拉取的条数
|
||||
props.put("max.poll.records", 10);
|
||||
// earliest当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,从头开始消费
|
||||
// latest
|
||||
// 当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,消费新产生的该分区下的数据
|
||||
// none
|
||||
// topic各分区都存在已提交的offset时,从offset后开始消费;只要有一个分区不存在已提交的offset,则抛出异常
|
||||
props.put("auto.offset.reset", "earliest");
|
||||
//序列化
|
||||
props.put("key.deserializer", StringDeserializer.class.getName());
|
||||
props.put("value.deserializer", StringDeserializer.class.getName());
|
||||
this.consumer = new KafkaConsumer<String, String>(props);
|
||||
//订阅主题列表topic
|
||||
this.consumer.subscribe(Arrays.asList(topic));
|
||||
|
||||
System.out.println("初始化!");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void main(String args[]) {
|
||||
KafkaConsumerTest test1 = new KafkaConsumerTest("KAFKA_TEST2");
|
||||
Thread thread1 = new Thread(test1);
|
||||
thread1.start();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,75 @@
|
||||
package com.pancm.mq.kafka.test2;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.kafka.clients.producer.KafkaProducer;
|
||||
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||
import org.apache.kafka.common.serialization.StringSerializer;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Title: KafkaProducerTest
|
||||
* Description:
|
||||
* kafka 生产者demo
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年1月26日
|
||||
*/
|
||||
public class KafkaProducerTest implements Runnable {
|
||||
|
||||
private final KafkaProducer<String, String> producer;
|
||||
private final String topic;
|
||||
|
||||
|
||||
public KafkaProducerTest(String topicName) {
|
||||
Properties props = new Properties();
|
||||
props.put("bootstrap.servers", "master:9092,slave1:9092,slave2:9092");
|
||||
//acks=0:如果设置为0,生产者不会等待kafka的响应。
|
||||
//acks=1:这个配置意味着kafka会把这条消息写到本地日志文件中,但是不会等待集群中其他机器的成功响应。
|
||||
//acks=all:这个配置意味着leader会等待所有的follower同步完成。这个确保消息不会丢失,除非kafka集群中所有机器挂掉。这是最强的可用性保证。
|
||||
props.put("acks", "all");
|
||||
//配置为大于0的值的话,客户端会在消息发送失败时重新发送。
|
||||
props.put("retries", 0);
|
||||
//当多条消息需要发送到同一个分区时,生产者会尝试合并网络请求。这会提高client和生产者的效率
|
||||
props.put("batch.size", 16384);
|
||||
props.put("key.serializer", StringSerializer.class.getName());
|
||||
props.put("value.serializer", StringSerializer.class.getName());
|
||||
this.producer = new KafkaProducer<String, String>(props);
|
||||
this.topic = topicName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
int messageNo = 1;
|
||||
try {
|
||||
for(;;) {
|
||||
String messageStr="你好,这是第"+messageNo+"条数据";
|
||||
producer.send(new ProducerRecord<String, String>(topic, "Message", messageStr));
|
||||
//生产了10条就打印
|
||||
if(messageNo%10==0){
|
||||
System.out.println("发送的信息:" + messageStr);
|
||||
}
|
||||
//生产100条就退出
|
||||
if(messageNo%100==0){
|
||||
System.out.println("成功发送了"+messageNo+"条");
|
||||
break;
|
||||
}
|
||||
messageNo++;
|
||||
// Utils.sleep(1);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
producer.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
KafkaProducerTest test = new KafkaProducerTest("KAFKA_TEST2");
|
||||
Thread thread = new Thread(test);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
12
src/main/java/com/pancm/mq/kafka/test2/package-info.java
Normal file
12
src/main/java/com/pancm/mq/kafka/test2/package-info.java
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* Title: package-info
|
||||
* Description:
|
||||
* kafka消费者
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年2月9日
|
||||
*/
|
||||
package com.pancm.mq.kafka.test2;
|
||||
106
src/main/java/com/pancm/mq/kafka/test3/KafkaConsumerTest.java
Normal file
106
src/main/java/com/pancm/mq/kafka/test3/KafkaConsumerTest.java
Normal file
@ -0,0 +1,106 @@
|
||||
package com.pancm.mq.kafka.test3;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecords;
|
||||
import org.apache.kafka.clients.consumer.KafkaConsumer;
|
||||
import org.apache.kafka.common.serialization.StringDeserializer;
|
||||
|
||||
/**
|
||||
*
|
||||
* Title: KafkaConsumerTest
|
||||
* Description:
|
||||
* kafka消费者
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2017年12月29日
|
||||
*/
|
||||
public class KafkaConsumerTest extends Thread {
|
||||
|
||||
private final KafkaConsumer<String, String> consumer;
|
||||
private ConsumerRecords<String, String> msgList;
|
||||
private final String topic;
|
||||
private static final String GROUPID = "groupA1";
|
||||
private final String servers="master:9092,slave1:9092,slave2:9092";
|
||||
|
||||
public KafkaConsumerTest(String topicName) {
|
||||
Properties props = new Properties();
|
||||
//kafka消费的的地址
|
||||
props.put("bootstrap.servers", servers);
|
||||
//组名 不同组名可以重复消费
|
||||
props.put("group.id", GROUPID);
|
||||
//是否自动提交
|
||||
props.put("enable.auto.commit", "false");
|
||||
//从poll(拉)的回话处理时长
|
||||
props.put("auto.commit.interval.ms", "1000");
|
||||
//超时时间
|
||||
props.put("session.timeout.ms", "30000");
|
||||
props.put("max.poll.records", "1000");
|
||||
// earliest当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,从头开始消费
|
||||
// latest
|
||||
// 当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,消费新产生的该分区下的数据
|
||||
// none
|
||||
// topic各分区都存在已提交的offset时,从offset后开始消费;只要有一个分区不存在已提交的offset,则抛出异常
|
||||
props.put("auto.offset.reset", "earliest");
|
||||
//序列化
|
||||
props.put("key.deserializer", StringDeserializer.class.getName());
|
||||
props.put("value.deserializer", StringDeserializer.class.getName());
|
||||
this.consumer = new KafkaConsumer<String, String>(props);
|
||||
this.topic = topicName;
|
||||
//订阅者主题
|
||||
this.consumer.subscribe(Arrays.asList(topic));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
int messageNo = 0;
|
||||
System.out.println("---------开始消费---------");
|
||||
try {
|
||||
for (;;) {
|
||||
msgList = consumer.poll(100);
|
||||
if(null!=msgList&&msgList.count()>0){
|
||||
// System.out.println("msgList:"+msgList.count());
|
||||
for (ConsumerRecord<String, String> record : msgList) {
|
||||
//消费100条就打印 ,但打印的数据不一定是这个规律的
|
||||
if(messageNo%100==0){
|
||||
System.out.println(topic+" "+ "=======receive: key = " + record.key() + ", value = " + record.value()+" offset==="+record.offset());
|
||||
// consumer.commitAsync();
|
||||
}
|
||||
|
||||
// if(messageNo==101){
|
||||
// System.out.println("=======receive: key = " + record.key() + ", value = " + record.value()+" offset==="+record.offset());
|
||||
// break;
|
||||
// }
|
||||
// //当消费了1000条就退出
|
||||
// if(messageNo%1000==0){
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
messageNo++;
|
||||
}else{
|
||||
Thread.sleep(1000);
|
||||
System.out.println("休眠中...");
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
consumer.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
KafkaConsumerTest test1 = new KafkaConsumerTest("TEST_INSERT");
|
||||
KafkaConsumerTest test2 = new KafkaConsumerTest("1001_INSERT");
|
||||
KafkaConsumerTest test3 = new KafkaConsumerTest("1002_INSERT");
|
||||
Thread thread1 = new Thread(test1);
|
||||
Thread thread2 = new Thread(test2);
|
||||
Thread thread3 = new Thread(test3);
|
||||
thread1.start();
|
||||
// thread2.start();
|
||||
// thread3.start();
|
||||
}
|
||||
}
|
||||
132
src/main/java/com/pancm/mq/kafka/test3/KafkaConsumerTest3.java
Normal file
132
src/main/java/com/pancm/mq/kafka/test3/KafkaConsumerTest3.java
Normal file
@ -0,0 +1,132 @@
|
||||
package com.pancm.mq.kafka.test3;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecords;
|
||||
import org.apache.kafka.clients.consumer.KafkaConsumer;
|
||||
import org.apache.kafka.common.TopicPartition;
|
||||
import org.apache.kafka.common.serialization.StringDeserializer;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Title: KafkaConsumerTest
|
||||
* Description:
|
||||
* kafka消费者 demo
|
||||
* 手动提交测试 指定分区和offset
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年1月26日
|
||||
*/
|
||||
public class KafkaConsumerTest3 implements Runnable {
|
||||
|
||||
private KafkaConsumer<String, String> consumer;
|
||||
private ConsumerRecords<String, String> msgList;
|
||||
private String topic;
|
||||
private static final String GROUPID = "groupF";
|
||||
|
||||
/**用于存放 分区所对应的offset */
|
||||
private ConcurrentHashMap<Integer, Long> map=new ConcurrentHashMap<Integer, Long>();
|
||||
|
||||
/**分区编号 */
|
||||
private int partId=0;
|
||||
/**分区个数 */
|
||||
private int partSize=1;
|
||||
private long offset=-1L;
|
||||
|
||||
/**初始化标志*/
|
||||
private boolean flag = true;
|
||||
|
||||
public KafkaConsumerTest3(String topicName) {
|
||||
this.topic = topicName;
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println("---------开始消费---------");
|
||||
int messageNo = 1;
|
||||
List<String> list=new ArrayList<String>();
|
||||
List<Long> list2=new ArrayList<Long>();
|
||||
TopicPartition p = new TopicPartition(topic,0);
|
||||
consumer.assign(Arrays.asList(p));
|
||||
//指定分区和offset进行消费
|
||||
consumer.seek(p, 0);
|
||||
try {
|
||||
for (;;) {
|
||||
msgList = consumer.poll(100);
|
||||
if(null!=msgList&&msgList.count()>0){
|
||||
int tmpPartId=0;
|
||||
for (ConsumerRecord<String, String> record : msgList) {
|
||||
if(messageNo%10==0){
|
||||
System.out.println(messageNo+"=======receive: partId ="+tmpPartId +", key = " + record.key() + ", value = " + record.value()+" offset==="+record.offset());
|
||||
}
|
||||
}
|
||||
// 手动提交
|
||||
// consumer.commitSync();
|
||||
}else{
|
||||
Thread.sleep(1000);
|
||||
System.out.println("...");
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
consumer.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void saveOffset(int partId,long offset) {
|
||||
map.put(partId, offset);
|
||||
}
|
||||
|
||||
|
||||
private long getOffset(int partId) {
|
||||
return map.containsKey(partId)?map.get(partId):offset;
|
||||
}
|
||||
|
||||
private void init() {
|
||||
Properties props = new Properties();
|
||||
//kafka消费的的地址
|
||||
props.put("bootstrap.servers", "master:9092,slave1:9092,slave2:9092");
|
||||
//组名 不同组名可以重复消费
|
||||
props.put("group.id", GROUPID);
|
||||
//是否自动提交
|
||||
props.put("enable.auto.commit", "false");
|
||||
//超时时间
|
||||
props.put("session.timeout.ms", "30000");
|
||||
//一次最大拉取的条数
|
||||
props.put("max.poll.records", 10);
|
||||
// earliest当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,从头开始消费
|
||||
// latest
|
||||
// 当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,消费新产生的该分区下的数据
|
||||
// none
|
||||
// topic各分区都存在已提交的offset时,从offset后开始消费;只要有一个分区不存在已提交的offset,则抛出异常
|
||||
props.put("auto.offset.reset", "earliest");
|
||||
//序列化
|
||||
props.put("key.deserializer", StringDeserializer.class.getName());
|
||||
props.put("value.deserializer", StringDeserializer.class.getName());
|
||||
this.consumer = new KafkaConsumer<String, String>(props);
|
||||
//订阅主题列表topic
|
||||
// this.consumer.subscribe(Arrays.asList(topic));
|
||||
|
||||
if(consumer.partitionsFor(topic)!=null){
|
||||
this.partSize = consumer.partitionsFor(topic).size();
|
||||
}
|
||||
|
||||
System.out.println("初始化!");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void main(String args[]) {
|
||||
KafkaConsumerTest3 test1 = new KafkaConsumerTest3("TEST_INSERT");
|
||||
Thread thread1 = new Thread(test1);
|
||||
thread1.start();
|
||||
}
|
||||
}
|
||||
129
src/main/java/com/pancm/mq/kafka/test3/KafkaProducerTest.java
Normal file
129
src/main/java/com/pancm/mq/kafka/test3/KafkaProducerTest.java
Normal file
@ -0,0 +1,129 @@
|
||||
package com.pancm.mq.kafka.test3;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.kafka.clients.producer.KafkaProducer;
|
||||
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||
import org.apache.kafka.common.serialization.StringSerializer;
|
||||
import org.apache.kafka.common.utils.Utils;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
/**
|
||||
*
|
||||
* Title: KafkaProducerTest
|
||||
* Description: kafka生产者的消息测试
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年1月9日
|
||||
*/
|
||||
public class KafkaProducerTest implements Runnable {
|
||||
|
||||
private final KafkaProducer<String, String> producer;
|
||||
private final String topic;
|
||||
private int k=10;
|
||||
private final String servers="master:9092,slave1:9092,slave2:9092";
|
||||
/**
|
||||
* @param topic 消息名称
|
||||
* @param
|
||||
*/
|
||||
public KafkaProducerTest(String topicName) {
|
||||
Properties props = new Properties();
|
||||
props.put("bootstrap.servers", servers);
|
||||
//acks=0:如果设置为0,生产者不会等待kafka的响应。
|
||||
//acks=1:这个配置意味着kafka会把这条消息写到本地日志文件中,但是不会等待集群中其他机器的成功响应。
|
||||
//acks=all:这个配置意味着leader会等待所有的follower同步完成。这个确保消息不会丢失,除非kafka集群中所有机器挂掉。这是最强的可用性保证。
|
||||
props.put("acks", "all");
|
||||
//配置为大于0的值的话,客户端会在消息发送失败时重新发送。
|
||||
props.put("retries", 0);
|
||||
//当多条消息需要发送到同一个分区时,生产者会尝试合并网络请求。这会提高client和生产者的效率
|
||||
props.put("batch.size", 16384);
|
||||
props.put("linger.ms", 1);
|
||||
props.put("buffer.memory", 33554432);
|
||||
props.put("key.serializer", StringSerializer.class.getName());
|
||||
props.put("value.serializer", StringSerializer.class.getName());
|
||||
this.producer = new KafkaProducer<String, String>(props);
|
||||
this.topic = topicName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
int messageNo = 0;
|
||||
long k=0L;
|
||||
try {
|
||||
while (true) {
|
||||
JSONObject json=new JSONObject();
|
||||
k=239386111508899430L+messageNo;
|
||||
String messageStr="INSERT INTO MT_TASK_HH ( ECID , PTMSGID , USERID , DTTYPE , "
|
||||
+ "MSGTYPE , USERUID , SPMSGID , ERRORCODE , RECVMTTIME , SENDTIME , RECVTIME , "
|
||||
+ "PHONE , SPGATESEND , SPNUMBER , MOBILEAREA , MOBILETYPE , MOBILECOUNTRY , "
|
||||
+ "NEXTGATETYPE , GATEIDBIND , SPGATEBIND , CPNOBIND , CPNO , ORDERCPNO , PROTYPE , "
|
||||
+ "RCHGTYPE , SVRTYPE , FEEFLAG , RETFLAG , PASSTHROUGH , JTYPE , SENDSTATUS , "
|
||||
+ "SENDLEVEL , SENDRESULT , RESENDCNT , TPUDHI , TPPID , PKTOTAL , PKNUMBER , MSGFMT ,"
|
||||
+ " LONGMSGSEQ , SENDERRCODE , GATEIDSEND , SPID , PACKNUM , PACKPOS , NETERRCNT , "
|
||||
+ " ERRRESENDCNT , ERRORCODE2 , RPTEXFLAG , SENDFLAG , SUPPSNDCNT , SENDRPTTIME , "
|
||||
+ "TRANSMTTIME , MTSUBMITTIME , TRANSRPTTIME , MTSENDTIME , SUBMITTIME , DONETIME , "
|
||||
+ " PUSHRPTTIME , PRETRANSMTTM , ENDTRANSRPTTM , SUBMITDATE , DONEDATE , JPTCODE , "
|
||||
+ "PTCODE , LOGINUID , DESTUID , USERMSGID , SUPPMSGID , PREGATENO , LOCALGATENO , "
|
||||
+ " NEXTGATENO , SRCGATENO , NETWORKCODE , NETWORKID , CHARGETYPE , PRICE , CUSTID , "
|
||||
+ " USEREXDATA , USERSVRTYPE , SEQID , AGENTLOGINUID , MSGSRCIP , TMPLID , SPTMPLID ,"
|
||||
+ " MSGTYPE1 , ACCTTYPE , PTRCHGID , CHARGOBJ , CHGRADE , VALIDTM , ERRORCODE3 , "
|
||||
+ " ERRORCODE4 , FIRSTDOWNTM , ENDDOWNTM , RDNRPTOKTM , RDNTRANSRPTTM , RECVRDNRPTTM , "
|
||||
+ " MESSAGE ) VALUES ('101034', '"+k+"', 'qian01', '1', '1', "
|
||||
+ "'100032', '2393861115088994305', 'DELIVRD', '2018-02-02 14:11:16', "
|
||||
+ "'2018-02-02 14:09:49', '2018-02-02 14:09:49', '13475676880', '2017022701', "
|
||||
+ "'20170227011', '30', '0', '86', '0', '901', '2017022701', '1', '', '', '0', "
|
||||
+ "'1', '', '2', '1', '0', '0', '0', '3', '0', '0', '0', '0', '1', '1', '0', '0', '0', "
|
||||
+ "'901', 'qianzi', '1', '1', '0', '0', 'DELIVRD', '0', '0', '0', '2018-02-02 14:11:16', "
|
||||
+ "'2018-02-02 14:09:49', '2018-02-02 14:09:49', '2018-02-02 14:11:16', "
|
||||
+ "'2018-02-02 14:09:49', '2018-02-02 14:11:49', '2018-02-02 14:11:49', "
|
||||
+ "'2018-02-02 14:11:16', '2018-02-02 14:11:16', '2018-02-02 14:09:49', '1802021411', "
|
||||
+ "'1802021411', '1050973', '16', '105692', '104473', '0', '0', '0', '2397', '0', '0', "
|
||||
+ "'0', '0', '0', '0.000000', '', '', '', '128', '105692', '192.169.1.32:2232', '0', '',"
|
||||
+ " '0', '0', '0', '0', '0', '4', '', '', '2000-01-01 00:00:00', '2000-01-01 00:00:00', "
|
||||
+ "'2000-01-01 00:00:00', '2000-01-01 00:00:00', '2000-01-01 00:00:00', 'AGEAcwBkAGEAcwBkAGEAcwBkAGEAcwBkAGEAcwBkAFsAbwBlAGUAcgBd');";
|
||||
|
||||
// String messageStr="222222222222222222222222222222222222222222222222222222222222222222";
|
||||
json.put("SQL", messageStr);
|
||||
json.put("TIME", System.currentTimeMillis());
|
||||
json.put("PTMSGID", messageNo);
|
||||
|
||||
producer.send(new ProducerRecord<String, String>(topic, "Message"+messageNo, json.toJSONString()));
|
||||
messageNo++;
|
||||
//生产了100条就打印
|
||||
if(messageNo%10000==0){
|
||||
// System.out.println("Send:" + messageStr);
|
||||
}
|
||||
//生产100条就退出
|
||||
if(messageNo%500000==0){
|
||||
System.out.println(topic+"成功发送了"+messageNo+"条");
|
||||
break;
|
||||
}
|
||||
// Utils.sleep(1);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
producer.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
KafkaProducerTest test = new KafkaProducerTest("1002_INSERT");
|
||||
KafkaProducerTest test1 = new KafkaProducerTest("1005_INSERT");
|
||||
KafkaProducerTest test2 = new KafkaProducerTest("1001_INSERT");
|
||||
KafkaProducerTest testd = new KafkaProducerTest("TEST_INSERT1");
|
||||
Thread thread = new Thread(test);
|
||||
Thread thread1 = new Thread(test1);
|
||||
Thread thread2 = new Thread(test2);
|
||||
Thread threadD = new Thread(testd);
|
||||
thread.start();
|
||||
// Utils.sleep(100);
|
||||
// thread1.start();
|
||||
// Utils.sleep(100);
|
||||
// thread2.start();
|
||||
// threadD.start();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
11
src/main/java/com/pancm/mq/kafka/test3/package-info.java
Normal file
11
src/main/java/com/pancm/mq/kafka/test3/package-info.java
Normal file
@ -0,0 +1,11 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* Title: package-info
|
||||
* Description:
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年3月15日
|
||||
*/
|
||||
package com.pancm.mq.kafka.test3;
|
||||
8
src/main/java/com/pancm/mq/package-info.java
Normal file
8
src/main/java/com/pancm/mq/package-info.java
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @Title: package-info
|
||||
* @Description: 消息中间件的一些类
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年9月20日
|
||||
*/
|
||||
package com.pancm.mq;
|
||||
36
src/main/java/com/pancm/mq/rabbitmq/demo/C.java
Normal file
36
src/main/java/com/pancm/mq/rabbitmq/demo/C.java
Normal file
@ -0,0 +1,36 @@
|
||||
package com.pancm.mq.rabbitmq.demo;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.rabbitmq.client.*;
|
||||
|
||||
|
||||
//消费者
|
||||
public class C {
|
||||
|
||||
private final static String QUEUE_NAME = "RabbitMQ_Hello"; //消息队列名
|
||||
|
||||
public static void main(String[] argv) throws Exception {
|
||||
// 创建连接工厂
|
||||
ConnectionFactory factory = new ConnectionFactory();
|
||||
// 设置RabbitMQ地址
|
||||
factory.setHost("127.0.0.1");
|
||||
// 创建一个新的连接
|
||||
Connection connection = factory.newConnection();
|
||||
// 创建一个频道
|
||||
Channel channel = connection.createChannel();
|
||||
// 声明要关注的队列 -- 在RabbitMQ中,队列声明是幂等性的(一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同),也就是说,如果不存在,就创建,如果存在,不会对已经存在的队列产生任何影响。
|
||||
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
|
||||
System.out.println("C [*] Waiting for messages. To exit press CTRL+C");
|
||||
// DefaultConsumer类实现了Consumer接口,通过传入一个频道,告诉服务器我们需要那个频道的消息,如果频道中有消息,就会执行回调函数handleDelivery
|
||||
Consumer consumer = new DefaultConsumer(channel) {
|
||||
@Override
|
||||
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
|
||||
String message = new String(body, "UTF-8");
|
||||
System.out.println("C [x] Received '" + message + "'");
|
||||
}
|
||||
};
|
||||
// 自动回复队列应答 -- RabbitMQ中的消息确认机制
|
||||
channel.basicConsume(QUEUE_NAME, true, consumer);
|
||||
}
|
||||
}
|
||||
35
src/main/java/com/pancm/mq/rabbitmq/demo/RabbitConsumer.java
Normal file
35
src/main/java/com/pancm/mq/rabbitmq/demo/RabbitConsumer.java
Normal file
@ -0,0 +1,35 @@
|
||||
package com.pancm.mq.rabbitmq.demo;
|
||||
|
||||
import com.rabbitmq.client.Channel;
|
||||
import com.rabbitmq.client.Connection;
|
||||
import com.rabbitmq.client.ConnectionFactory;
|
||||
import com.rabbitmq.client.QueueingConsumer;
|
||||
|
||||
//消费者
|
||||
public class RabbitConsumer {
|
||||
|
||||
private final static String QUEUE_NAME = "RabbitMQ_Hello"; //消息队列名
|
||||
|
||||
public static void main(String[] argv) throws Exception {
|
||||
|
||||
ConnectionFactory factory = new ConnectionFactory();
|
||||
factory.setHost("127.0.0.1");
|
||||
// 打开连接和创建频道,与发送端一样
|
||||
Connection connection = factory.newConnection();
|
||||
Channel channel = connection.createChannel();
|
||||
// 声明队列,主要为了防止消息接收者先运行此程序,队列还不存在时创建队列。
|
||||
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
|
||||
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
|
||||
// 创建队列消费者
|
||||
QueueingConsumer consumer = new QueueingConsumer(channel);
|
||||
// 指定消费队列
|
||||
channel.basicConsume(QUEUE_NAME, true, consumer);
|
||||
while (true) { //消费者程序运行开着 如果生产者新增了数据会自动获取
|
||||
Thread.sleep(500);
|
||||
// nextDelivery是一个阻塞方法(内部实现其实是阻塞队列的take方法)
|
||||
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
|
||||
String message = new String(delivery.getBody());
|
||||
System.out.println("'[x] Received '" + message );
|
||||
}
|
||||
}
|
||||
}
|
||||
46
src/main/java/com/pancm/mq/rabbitmq/demo/RabbitProducer.java
Normal file
46
src/main/java/com/pancm/mq/rabbitmq/demo/RabbitProducer.java
Normal file
@ -0,0 +1,46 @@
|
||||
package com.pancm.mq.rabbitmq.demo;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.rabbitmq.client.ConnectionFactory;
|
||||
import com.rabbitmq.client.Connection;
|
||||
import com.rabbitmq.client.Channel;
|
||||
|
||||
//生产者
|
||||
public class RabbitProducer {
|
||||
private final static String QUEUE_NAME = "RabbitMQ_Hello"; //消息队列名
|
||||
|
||||
public static void main(String[] argv) throws Exception {
|
||||
//创建连接连接到RabbitMQ
|
||||
ConnectionFactory factory = new ConnectionFactory();
|
||||
// 设置ip
|
||||
factory.setHost("127.0.0.1");
|
||||
/* //设置端口
|
||||
factory.setPort(15672);
|
||||
//设置用户名
|
||||
factory.setUsername("guest");
|
||||
//设置密码
|
||||
factory.setPassword("guest");
|
||||
//设置url(包括ip、端口、用户名、密码)
|
||||
factory.setUri("amqp://guest:guest@localhost:15672");
|
||||
*/
|
||||
// 创建一个连接
|
||||
Connection connection = factory.newConnection();
|
||||
// 创建一个频道
|
||||
Channel channel = connection.createChannel();
|
||||
// 指定一个队列
|
||||
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
|
||||
Map<String,Object> map=new HashMap<String,Object>();
|
||||
map.put("java", "hello");
|
||||
map.put("RabbitMQ", "Hello");
|
||||
//发送的消息
|
||||
String message = JSON.toJSONString(map);
|
||||
// 往队列中发出一条消息
|
||||
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
|
||||
System.out.println(" [x] Sent '" + message + "'");
|
||||
// 关闭频道和连接
|
||||
channel.close();
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
58
src/main/java/com/pancm/mq/rabbitmq/one2more/NewTask.java
Normal file
58
src/main/java/com/pancm/mq/rabbitmq/one2more/NewTask.java
Normal file
@ -0,0 +1,58 @@
|
||||
package com.pancm.mq.rabbitmq.one2more;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.rabbitmq.client.ConnectionFactory;
|
||||
import com.rabbitmq.client.Connection;
|
||||
import com.rabbitmq.client.Channel;
|
||||
import com.rabbitmq.client.MessageProperties;
|
||||
|
||||
//生产者 ( Producer:数据的发送方)
|
||||
//单发送多接收 Worker.java和NewTask.java
|
||||
public class NewTask {
|
||||
|
||||
private static final String TASK_QUEUE_NAME = "task_queue";
|
||||
|
||||
public static void main(String[] argv) throws Exception {
|
||||
// 创建工厂类
|
||||
ConnectionFactory factory = new ConnectionFactory();
|
||||
//factory.setHost("localhost");
|
||||
factory.setUri("amqp://guest:guest@172.26.129.3:5672");
|
||||
Connection connection = factory.newConnection();
|
||||
Channel channel = connection.createChannel();
|
||||
|
||||
channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null);
|
||||
Map map=new HashMap();
|
||||
map.put("aa", 11);
|
||||
map.put("bb", 22);
|
||||
map.put("cc", 33);
|
||||
String message = getMessage(argv);
|
||||
|
||||
channel.basicPublish("", TASK_QUEUE_NAME,
|
||||
MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());
|
||||
System.out.println(" [x] Sent '" + message + "'");
|
||||
|
||||
channel.close();
|
||||
connection.close();
|
||||
}
|
||||
|
||||
private static String getMessage(String[] strings) {
|
||||
if (strings.length < 1) {
|
||||
return "Hello!";
|
||||
}
|
||||
return joinStrings(strings, " ");
|
||||
}
|
||||
|
||||
private static String joinStrings(String[] strings, String delimiter) {
|
||||
int length = strings.length;
|
||||
if (length == 0) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder words = new StringBuilder(strings[0]);
|
||||
for (int i = 1; i < length; i++) {
|
||||
words.append(delimiter).append(strings[i]);
|
||||
}
|
||||
return words.toString();
|
||||
}
|
||||
}
|
||||
49
src/main/java/com/pancm/mq/rabbitmq/one2more/Worker.java
Normal file
49
src/main/java/com/pancm/mq/rabbitmq/one2more/Worker.java
Normal file
@ -0,0 +1,49 @@
|
||||
package com.pancm.mq.rabbitmq.one2more;
|
||||
import com.rabbitmq.client.Channel;
|
||||
import com.rabbitmq.client.Connection;
|
||||
import com.rabbitmq.client.ConnectionFactory;
|
||||
import com.rabbitmq.client.QueueingConsumer;
|
||||
//消费者 (Consumer:数据的接收方)
|
||||
//单发送多接收 Worker.java和NewTask.java
|
||||
public class Worker {
|
||||
|
||||
private static final String TASK_QUEUE_NAME = "task_queue";
|
||||
// private static final String TASK_QUEUE_NAME = "tsk.hybris.productbrand.tsk";
|
||||
|
||||
public static void main(String[] argv) throws Exception {
|
||||
|
||||
ConnectionFactory factory = new ConnectionFactory();
|
||||
//factory.setHost("localhost");
|
||||
factory.setUri("amqp://guest:guest@172.26.129.3:5672");
|
||||
Connection connection = factory.newConnection();
|
||||
Channel channel = connection.createChannel();
|
||||
|
||||
channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null);//queue的持久化需要在声明时指定durable=True
|
||||
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
|
||||
//保证在接收端一个消息没有处理完时不会接收另一个消息
|
||||
channel.basicQos(1);
|
||||
// channel.basicQos(0, 1, false); //这样RabbitMQ就会使得每个Consumer在同一个时间点最多处理一个Message。换句话说,在接收到该Consumer的ack前,他它不会将新的Message分发给它。
|
||||
|
||||
QueueingConsumer consumer = new QueueingConsumer(channel);
|
||||
channel.basicConsume(TASK_QUEUE_NAME, false, consumer);
|
||||
|
||||
while (true) {
|
||||
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
|
||||
String message = new String(delivery.getBody());
|
||||
|
||||
System.out.println(" [x] Received '" + message + "'");
|
||||
doWork(message);
|
||||
System.out.println(" [x] Done");
|
||||
|
||||
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void doWork(String task) throws InterruptedException {
|
||||
for (char ch: task.toCharArray()) {
|
||||
if (ch == '.') {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
package com.pancm.mq.rabbitmq.one2one;
|
||||
import java.net.URISyntaxException;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import com.rabbitmq.client.ConnectionFactory;
|
||||
import com.rabbitmq.client.Connection;
|
||||
import com.rabbitmq.client.Channel;
|
||||
import com.rabbitmq.client.QueueingConsumer;
|
||||
public class ClientReceive1 {
|
||||
public static final String queue_name="my_queue";
|
||||
public static final boolean autoAck=false;
|
||||
public static final boolean durable=true;
|
||||
public static void main(String[] args)
|
||||
throws java.io.IOException,java.lang.InterruptedException, TimeoutException, KeyManagementException, NoSuchAlgorithmException, URISyntaxException{
|
||||
ConnectionFactory factory=new ConnectionFactory();
|
||||
// factory.setHost("localhost");
|
||||
// factory.setVirtualHost("my_mq");
|
||||
// factory.setUsername("zhxia");
|
||||
// factory.setPassword("123456");
|
||||
factory.setUri("amqp://guest:guest@172.26.129.3:5672");//获取url
|
||||
Connection connection=factory.newConnection();
|
||||
Channel channel=connection.createChannel();
|
||||
channel.queueDeclare(queue_name, durable, false, false, null);
|
||||
System.out.println("Wait for message");
|
||||
channel.basicQos(1); //消息分发处理
|
||||
QueueingConsumer consumer=new QueueingConsumer(channel);
|
||||
channel.basicConsume(queue_name, autoAck, consumer);
|
||||
while(true){
|
||||
Thread.sleep(500);
|
||||
QueueingConsumer.Delivery deliver=consumer.nextDelivery();
|
||||
String message=new String(deliver.getBody());
|
||||
System.out.println("Message received:"+message);
|
||||
channel.basicAck(deliver.getEnvelope().getDeliveryTag(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
33
src/main/java/com/pancm/mq/rabbitmq/one2one/ClientSend1.java
Normal file
33
src/main/java/com/pancm/mq/rabbitmq/one2one/ClientSend1.java
Normal file
@ -0,0 +1,33 @@
|
||||
package com.pancm.mq.rabbitmq.one2one;
|
||||
import java.net.URISyntaxException;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import com.rabbitmq.client.ConnectionFactory;
|
||||
import com.rabbitmq.client.Connection;
|
||||
import com.rabbitmq.client.Channel;
|
||||
import com.rabbitmq.client.MessageProperties;
|
||||
public class ClientSend1 {
|
||||
public static final String queue_name="my_queue";
|
||||
public static final boolean durable=true; //消息队列持久化
|
||||
public static void main(String[] args)
|
||||
throws java.io.IOException, TimeoutException, KeyManagementException, NoSuchAlgorithmException, URISyntaxException{
|
||||
ConnectionFactory factory=new ConnectionFactory(); //创建连接工厂
|
||||
// factory.setHost("localhost");
|
||||
// factory.setVirtualHost("my_mq");
|
||||
// factory.setUsername("zhxia");
|
||||
// factory.setPassword("123456");
|
||||
factory.setUri("amqp://guest:guest@172.26.129.3:5672");//获取url
|
||||
Connection connection=factory.newConnection(); //创建连接
|
||||
Channel channel=connection.createChannel();//创建信道
|
||||
channel.queueDeclare(queue_name, durable, false, false, null); //声明消息队列,且为可持久化的
|
||||
String message="Hello world"+Math.random();
|
||||
//将队列设置为持久化之后,还需要将消息也设为可持久化的,MessageProperties.PERSISTENT_TEXT_PLAIN
|
||||
channel.basicPublish("", queue_name, MessageProperties.PERSISTENT_TEXT_PLAIN,message.getBytes());
|
||||
System.out.println("Send message:"+message);
|
||||
channel.close();
|
||||
connection.close();
|
||||
}
|
||||
|
||||
}
|
||||
44
src/main/java/com/pancm/mq/rabbitmq/one2one/Recv.java
Normal file
44
src/main/java/com/pancm/mq/rabbitmq/one2one/Recv.java
Normal file
@ -0,0 +1,44 @@
|
||||
package com.pancm.mq.rabbitmq.one2one;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.rabbitmq.client.Channel;
|
||||
import com.rabbitmq.client.Connection;
|
||||
import com.rabbitmq.client.ConnectionFactory;
|
||||
import com.rabbitmq.client.QueueingConsumer;
|
||||
|
||||
|
||||
//消费者 (Consumer:数据的接收方)
|
||||
//单发送单接收 Send.java和Recv.java类
|
||||
public class Recv {
|
||||
|
||||
private final static String QUEUE_NAME = "header_exchange";
|
||||
|
||||
public static void main(String[] argv) throws Exception {
|
||||
|
||||
ConnectionFactory factory = new ConnectionFactory();
|
||||
// factory.setHost("localhost");
|
||||
// factory.setHost("127.0.0.1");
|
||||
factory.setUri("amqp://guest:guest@172.26.129.3:5672");//获取url
|
||||
// 打开连接和创建频道,与发送端一样
|
||||
Connection connection = factory.newConnection();
|
||||
Channel channel = connection.createChannel();
|
||||
// 声明队列,主要为了防止消息接收者先运行此程序,队列还不存在时创建队列。
|
||||
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
|
||||
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
|
||||
// 创建队列消费者
|
||||
QueueingConsumer consumer = new QueueingConsumer(channel);
|
||||
// 指定消费队列
|
||||
channel.basicConsume(QUEUE_NAME, true, consumer);
|
||||
while (true) { //消费者程序运行开着 如果生产者新增了数据会自动获取
|
||||
Thread.sleep(500);
|
||||
List aa=new ArrayList();
|
||||
// nextDelivery是一个阻塞方法(内部实现其实是阻塞队列的take方法)
|
||||
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
|
||||
String message = new String(delivery.getBody());
|
||||
aa.add(message);
|
||||
System.out.println("你好吗!"+" [x] Received '" + message + "'"+aa);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
49
src/main/java/com/pancm/mq/rabbitmq/one2one/Send.java
Normal file
49
src/main/java/com/pancm/mq/rabbitmq/one2one/Send.java
Normal file
@ -0,0 +1,49 @@
|
||||
package com.pancm.mq.rabbitmq.one2one;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.rabbitmq.client.ConnectionFactory;
|
||||
import com.rabbitmq.client.Connection;
|
||||
import com.rabbitmq.client.Channel;
|
||||
//生产者 ( Producer:数据的发送方)
|
||||
//单发送单接收 //单发送单接收 Send.java和Recv.java类
|
||||
|
||||
public class Send {
|
||||
|
||||
private final static String QUEUE_NAME = "header_exchange"; //消息队列名
|
||||
|
||||
public static void main(String[] argv) throws Exception {
|
||||
Map map=new HashMap();
|
||||
map.put("aa", 11);
|
||||
map.put("bb", 22);
|
||||
map.put("cc", 33);
|
||||
map.put("dd", 44);
|
||||
map.put("ff", 1);
|
||||
System.out.println("你好啊!");
|
||||
//创建连接连接到MabbitMQ
|
||||
ConnectionFactory factory = new ConnectionFactory();
|
||||
// 设置MabbitMQ所在主机ip或者主机名
|
||||
// factory.setHost("localhost");
|
||||
//factory.setHost("127.0.0.1");
|
||||
|
||||
factory.setUri("amqp://guest:guest@172.26.129.3:5672");//获取url
|
||||
// 创建一个连接
|
||||
Connection connection = factory.newConnection();
|
||||
// 创建一个频道
|
||||
Channel channel = connection.createChannel();
|
||||
// 指定一个队列
|
||||
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
|
||||
//发送的消息
|
||||
String message = JSON.toJSONString(map);
|
||||
// 往队列中发出一条消息
|
||||
channel.basicPublish("", QUEUE_NAME, null, message.getBytes()); //发送
|
||||
System.out.println(" [x] Sent '" + message + "'");
|
||||
// 关闭频道和连接
|
||||
channel.close();
|
||||
connection.close();
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
11
src/main/java/com/pancm/mq/rabbitmq/package-info.java
Normal file
11
src/main/java/com/pancm/mq/rabbitmq/package-info.java
Normal file
@ -0,0 +1,11 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* Title: package-info
|
||||
* Description: rabbitMq 消息队列测试
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2017年11月7日
|
||||
*/
|
||||
package com.pancm.mq.rabbitmq;
|
||||
39
src/main/java/com/pancm/pojo/Student.java
Normal file
39
src/main/java/com/pancm/pojo/Student.java
Normal file
@ -0,0 +1,39 @@
|
||||
package com.pancm.pojo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import lombok.extern.log4j.Log4j;
|
||||
|
||||
/**
|
||||
*
|
||||
* Title: Class
|
||||
* Description:
|
||||
* 学生信息表
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年1月11日
|
||||
*/
|
||||
/*@Data :注解在类上;提供类所有属性的 getting 和 setting 方法,此外还提供了equals、canEqual、hashCode、toString 方法
|
||||
@Setter:注解在属性上;为属性提供 setting 方法
|
||||
@Getter:注解在属性上;为属性提供 getting 方法
|
||||
@Log4j :注解在类上;为类提供一个 属性名为log 的 log4j 日志对象
|
||||
@NoArgsConstructor:注解在类上;为类提供一个无参的构造方法
|
||||
@AllArgsConstructor:注解在类上;为类提供一个全参的构造方法*/
|
||||
@Data
|
||||
@Log4j
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@ToString(exclude = {"id","name"})
|
||||
@SuppressWarnings("unused")
|
||||
public class Student {
|
||||
/** 学生id */
|
||||
private int id;
|
||||
/** 学生姓名 */
|
||||
private String name;
|
||||
/** 班级ID */
|
||||
private int classId;
|
||||
}
|
||||
88
src/main/java/com/pancm/pojo/User.java
Normal file
88
src/main/java/com/pancm/pojo/User.java
Normal file
@ -0,0 +1,88 @@
|
||||
package com.pancm.pojo;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.pancm.utils.MyTools;
|
||||
|
||||
/**
|
||||
*
|
||||
* Title: User Description:用户pojo类 Version:1.0.0
|
||||
*
|
||||
* @author pancm
|
||||
* @date 2017年9月26日
|
||||
*/
|
||||
public class User {
|
||||
|
||||
/** 编号 */
|
||||
private int id;
|
||||
/** 姓名 */
|
||||
private String name;
|
||||
|
||||
public User() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
*
|
||||
* @param id
|
||||
* 编号
|
||||
* @param name
|
||||
* 姓名
|
||||
*/
|
||||
public User(int id, String name) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取编号
|
||||
*
|
||||
* @return id
|
||||
*/
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置编号
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取姓名
|
||||
*
|
||||
* @return name
|
||||
*/
|
||||
public String getName() {
|
||||
System.out.println("姓名:"+name);
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置姓名
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public Map toMap() {
|
||||
return MyTools.toMap(toString());
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return MyTools.toString(this);
|
||||
}
|
||||
|
||||
}
|
||||
8
src/main/java/com/pancm/pojo/package-info.java
Normal file
8
src/main/java/com/pancm/pojo/package-info.java
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @Title: package-info
|
||||
* @Description: 一些pojo类
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2017年11月7日
|
||||
*/
|
||||
package com.pancm.pojo;
|
||||
@ -0,0 +1,34 @@
|
||||
package com.pancm.thread.concurrent.liveLock;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
public class Consumer implements Runnable {
|
||||
private Drop drop;
|
||||
|
||||
public Consumer(Drop drop) {
|
||||
this.drop = drop;
|
||||
}
|
||||
public void run() {
|
||||
Random random = new Random();
|
||||
// String message="";
|
||||
// do{
|
||||
// message= drop.take();
|
||||
// System.out.format("MESSAGE RECEIVED: %s%n", message);
|
||||
// try {
|
||||
// Thread.sleep(random.nextInt(1000));
|
||||
// } catch (InterruptedException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// } while(!message.equals("DONE"));
|
||||
|
||||
for (String message = drop.take(); !message.equals("DONE"); message = drop.take()) {
|
||||
System.out.format("MESSAGE RECEIVED: %s%n", message);
|
||||
try {
|
||||
Thread.sleep(random.nextInt(1000));
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
50
src/main/java/com/pancm/thread/concurrent/liveLock/Drop.java
Normal file
50
src/main/java/com/pancm/thread/concurrent/liveLock/Drop.java
Normal file
@ -0,0 +1,50 @@
|
||||
package com.pancm.thread.concurrent.liveLock;
|
||||
|
||||
/**
|
||||
*
|
||||
* Title: Drop
|
||||
* Description:
|
||||
* 数据协同
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年3月8日
|
||||
*/
|
||||
public class Drop {
|
||||
// 发送的消息
|
||||
private String message;
|
||||
//true 表示消费者应该等待生产者发送消息
|
||||
// flase 表示生产者应该等待消费者获取消息
|
||||
private boolean empty = true;
|
||||
|
||||
public synchronized String take() {
|
||||
// 等待消息可用
|
||||
while (empty) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
// 改变状态
|
||||
empty = true;
|
||||
// 通知消费者状态改变
|
||||
notifyAll();
|
||||
return message;
|
||||
}
|
||||
|
||||
public synchronized void put(String message) {
|
||||
//等待消息被检索到
|
||||
while (!empty) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
// 改变状态
|
||||
empty = false;
|
||||
this.message = message;
|
||||
// 通知消费者状态改变
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package com.pancm.thread.concurrent.liveLock;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
*
|
||||
* Title: Producer
|
||||
* Description:
|
||||
* 消息生产者
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年3月8日
|
||||
*/
|
||||
public class Producer implements Runnable {
|
||||
private Drop drop;
|
||||
public Producer(Drop drop) {
|
||||
this.drop = drop;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
String importantInfo[] = { "第一条数据", "第二条数据", "第三条数据",
|
||||
"第四条数据" };
|
||||
Random random = new Random();
|
||||
for (int i = 0; i < importantInfo.length; i++) {
|
||||
drop.put(importantInfo[i]);
|
||||
try {
|
||||
Thread.sleep(random.nextInt(1000));
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
//表示已经发送完
|
||||
drop.put("DONE");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* Title: package-info
|
||||
* Description:
|
||||
* 活锁测试
|
||||
* 一个线程常常处于响应另一个线程的动作,如果其他线程也常常处于该线程的动作,那么就可能出现活锁。
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年3月8日
|
||||
*/
|
||||
package com.pancm.thread.concurrent.liveLock;
|
||||
21
src/main/java/com/pancm/thread/concurrent/liveLock/test.java
Normal file
21
src/main/java/com/pancm/thread/concurrent/liveLock/test.java
Normal file
@ -0,0 +1,21 @@
|
||||
package com.pancm.thread.concurrent.liveLock;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Title:
|
||||
* Description:
|
||||
* 多线程共享测试
|
||||
* Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年3月8日
|
||||
*/
|
||||
public class test{
|
||||
|
||||
public static void main(String[] args) {
|
||||
Drop drop=new Drop();
|
||||
(new Thread(new Producer(drop))).start();
|
||||
(new Thread(new Consumer(drop))).start();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @Title: package-info
|
||||
* @Description: 并发相关的类
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年9月20日
|
||||
*/
|
||||
package com.pancm.thread.concurrent;
|
||||
52
src/main/java/com/pancm/thread/test/JoinTest.java
Normal file
52
src/main/java/com/pancm/thread/test/JoinTest.java
Normal file
@ -0,0 +1,52 @@
|
||||
package com.pancm.thread.test;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @Title: JoinTest
|
||||
* @Description:
|
||||
* join方法测试
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年5月22日
|
||||
*/
|
||||
public class JoinTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(Thread.currentThread().getName()+ "主线程开始运行!");
|
||||
Test2 t1=new Test2("A");
|
||||
Test2 t2=new Test2("B");
|
||||
t1.start();
|
||||
t2.start();
|
||||
try {
|
||||
t1.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
t2.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println(Thread.currentThread().getName()+ "主线程运行结束!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Test2 extends Thread{
|
||||
public Test2(String name) {
|
||||
super(name);
|
||||
}
|
||||
public void run() {
|
||||
System.out.println(this.getName() + " 线程运行开始!");
|
||||
for (int i = 0; i < 5; i++) {
|
||||
System.out.println("子线程"+this.getName() + "运行 : " + i);
|
||||
try {
|
||||
sleep(new Random().nextInt(10));
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
System.out.println(this.getName() + " 线程运行结束!");
|
||||
}
|
||||
}
|
||||
44
src/main/java/com/pancm/thread/test/MyRunnable.java
Normal file
44
src/main/java/com/pancm/thread/test/MyRunnable.java
Normal file
@ -0,0 +1,44 @@
|
||||
package com.pancm.thread.test;
|
||||
/**
|
||||
* @author ZERO
|
||||
* @Data 2017-5-24 下午2:29:39
|
||||
* @Description
|
||||
*/
|
||||
public class MyRunnable implements Runnable{
|
||||
private int i = 0;
|
||||
private boolean stop=false;
|
||||
public void set(boolean falg) throws InterruptedException{
|
||||
if(!falg){
|
||||
synchronized (this) {
|
||||
this.notify();
|
||||
stop=true;
|
||||
System.out.println("启动的线程:"+Thread.currentThread().getId());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (;;) {
|
||||
synchronized (this) {
|
||||
if(stop){
|
||||
try {
|
||||
this.wait();
|
||||
System.out.println("暂停的线程:"+Thread.currentThread().getId());
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
i++;
|
||||
System.out.println("MyRunnable:"+Thread.currentThread().getName() + "第" + i+ "次");
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
21
src/main/java/com/pancm/thread/test/MyThread.java
Normal file
21
src/main/java/com/pancm/thread/test/MyThread.java
Normal file
@ -0,0 +1,21 @@
|
||||
package com.pancm.thread.test;
|
||||
/**
|
||||
* @author ZERO
|
||||
* @Data 2017-5-24 下午2:20:29
|
||||
* @Description
|
||||
*/
|
||||
public class MyThread extends Thread{
|
||||
|
||||
private int i = 0;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (i = 0; i < 10; i++) {
|
||||
System.out.println("MyThread:"+Thread.currentThread().getName() + "第" + i+ "次");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
53
src/main/java/com/pancm/thread/test/NotifyTest.java
Normal file
53
src/main/java/com/pancm/thread/test/NotifyTest.java
Normal file
@ -0,0 +1,53 @@
|
||||
package com.pancm.thread.test;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @Title: NotifyTest
|
||||
* @Description:
|
||||
* wait 和 notify测试
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年5月22日
|
||||
*/
|
||||
public class NotifyTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Test4 t1 = new Test4("张三");
|
||||
Test4 t2 = new Test4("李四");
|
||||
t1.start();
|
||||
t2.start();
|
||||
}
|
||||
}
|
||||
|
||||
class Test4 extends Thread {
|
||||
private String name;
|
||||
public Test4(String name) {
|
||||
super(name);
|
||||
this.name=name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println(this.getName() + " 线程运行开始!");
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
System.out.println("子线程" + this.getName() + "运行 : " + i);
|
||||
try {
|
||||
sleep(new Random().nextInt(100));
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
if("李四".equals(this.getName())){
|
||||
this.getName().wait();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.getName().notify();
|
||||
|
||||
}
|
||||
System.out.println(this.getName() + " 线程运行结束!");
|
||||
}
|
||||
}
|
||||
43
src/main/java/com/pancm/thread/test/PriorityTest.java
Normal file
43
src/main/java/com/pancm/thread/test/PriorityTest.java
Normal file
@ -0,0 +1,43 @@
|
||||
package com.pancm.thread.test;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @Title: PriorityTest
|
||||
* @Description:
|
||||
* 线程优先级测试
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年5月27日
|
||||
*/
|
||||
public class PriorityTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Test3 t1 = new Test3("张三");
|
||||
Test3 t2 = new Test3("李四");
|
||||
t1.setPriority(Thread.MIN_PRIORITY);
|
||||
t2.setPriority(Thread.MAX_PRIORITY);
|
||||
t1.start();
|
||||
t2.start();
|
||||
}
|
||||
}
|
||||
|
||||
class Test3 extends Thread {
|
||||
public Test3(String name) {
|
||||
super(name);
|
||||
}
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println(this.getName() + " 线程运行开始!");
|
||||
for (int i = 1; i <= 5; i++) {
|
||||
System.out.println("子线程"+this.getName() + "运行 : " + i);
|
||||
try {
|
||||
sleep(new Random().nextInt(10));
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
System.out.println(this.getName() + " 线程运行结束!");
|
||||
}
|
||||
}
|
||||
|
||||
95
src/main/java/com/pancm/thread/test/Test.java
Normal file
95
src/main/java/com/pancm/thread/test/Test.java
Normal file
@ -0,0 +1,95 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package com.pancm.thread.test;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
/**
|
||||
* @Title: Test
|
||||
* @Description:
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年5月17日
|
||||
*/
|
||||
public class Test {
|
||||
|
||||
public static void main(String[] args) {
|
||||
ThreadTest threadTest=new ThreadTest();
|
||||
threadTest.setPriority(1);
|
||||
threadTest.start();
|
||||
|
||||
RunalbeTest runalbeTest=new RunalbeTest();
|
||||
Thread thread=new Thread(runalbeTest);
|
||||
thread.setPriority(10);
|
||||
thread.start();
|
||||
|
||||
CallableTest callableTest=new CallableTest();
|
||||
FutureTask<Integer> ft = new FutureTask<Integer>(callableTest);
|
||||
Thread thread2=new Thread(ft);
|
||||
thread2.setPriority(5);
|
||||
thread2.start();
|
||||
try {
|
||||
System.out.println("返回值:"+ft.get());
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class ThreadTest extends Thread{
|
||||
@Override
|
||||
public void run() {
|
||||
for(int i=1;i<5;i++){
|
||||
System.out.println("这是一个Thread的线程!"+i);
|
||||
try {
|
||||
sleep(50);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
System.out.println("Thread的线程执行完了!");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class RunalbeTest implements Runnable{
|
||||
@Override
|
||||
public void run() {
|
||||
for(int i=1;i<5;i++){
|
||||
System.out.println("这是一个Runnable的线程!"+i);
|
||||
try {
|
||||
Thread.sleep(50);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
System.out.println("Runnable的线程执行完了!");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class CallableTest implements Callable<Integer>{
|
||||
|
||||
@Override
|
||||
public Integer call() throws Exception {
|
||||
for(int i=1;i<5;i++){
|
||||
System.out.println("这是一个Callable的线程!"+i);
|
||||
try {
|
||||
Thread.sleep(50);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
System.out.println("Callable的线程执行完了!");
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
42
src/main/java/com/pancm/thread/test/Test22.java
Normal file
42
src/main/java/com/pancm/thread/test/Test22.java
Normal file
@ -0,0 +1,42 @@
|
||||
package com.pancm.thread.test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class Test22 {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Map<Integer,Integer> map=new HashMap<Integer,Integer>();
|
||||
map.put(0, 0);
|
||||
map.put(1, 1);
|
||||
for(Integer type:map.keySet()){
|
||||
Thread3 t3=new Thread3(type);
|
||||
t3.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Thread3 extends Thread{
|
||||
|
||||
private int type;
|
||||
|
||||
public Thread3(int type){
|
||||
this.type=type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if(type==0){
|
||||
//连接mysql
|
||||
System.out.println("线程ID:"+getId()+"连接mysql");
|
||||
}else if(type==1){
|
||||
//连接oracle
|
||||
System.out.println("线程ID:"+getId()+"连接oracle");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
28
src/main/java/com/pancm/thread/test/TheadTest3.java
Normal file
28
src/main/java/com/pancm/thread/test/TheadTest3.java
Normal file
@ -0,0 +1,28 @@
|
||||
package com.pancm.thread.test;
|
||||
|
||||
public class TheadTest3 {
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
MyRunnable myRunnable=new MyRunnable();
|
||||
for(int i=1;i<=5;i++){
|
||||
Thread thread=new Thread(myRunnable);
|
||||
thread.setName("myRunnable-"+i);
|
||||
thread.start();
|
||||
}
|
||||
Thread.sleep(2000);
|
||||
myRunnable.set(true);
|
||||
Thread.sleep(3000);
|
||||
myRunnable.set(false);
|
||||
for(int i=1;i<=5;i++){
|
||||
MyThread myThread=new MyThread();
|
||||
myThread.setName("myThread-"+i);
|
||||
myThread.start();
|
||||
}
|
||||
|
||||
|
||||
System.out.println("结束...");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
204
src/main/java/com/pancm/thread/test/ThreadPoolTest.java
Normal file
204
src/main/java/com/pancm/thread/test/ThreadPoolTest.java
Normal file
@ -0,0 +1,204 @@
|
||||
package com.pancm.thread.test;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
*
|
||||
* @Title: ThreadPoolTest
|
||||
* @Description:
|
||||
* 线程池测试
|
||||
* @Version:1.0.0
|
||||
* @author pancm
|
||||
* @date 2018年3月1日
|
||||
*/
|
||||
public class ThreadPoolTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// cachedThreadPool();
|
||||
// fixedThreadPool();
|
||||
// newSingleThreadExecutor();
|
||||
// newScheduledThreadPool();
|
||||
// newScheduledThreadPool2();
|
||||
threadPoolExecutor();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个可缓存的线程池,如果当前线程池的规模超出了处理需求,将回收空的线程;当需求增加时,会增加线程数量;线程池规模无限制。
|
||||
*/
|
||||
private static void cachedThreadPool() {
|
||||
ExecutorService exec=Executors.newCachedThreadPool();
|
||||
for(int i=0;i<10;i++){
|
||||
exec.execute(new MyThread2(String.valueOf(i)));
|
||||
}
|
||||
//执行到此处并不会马上关闭线程池,执行完成之后才会关闭 但之后不能再往线程池中加线程,否则会报错
|
||||
exec.shutdown();
|
||||
System.out.println("运行结束!");
|
||||
/**
|
||||
* 1、主线程的执行与线程池里的线程分开,有可能主线程结束了,但是线程池还在运行
|
||||
* 2、放入线程池的线程并不一定会按其放入的先后而顺序执行
|
||||
*
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个固定长度的线程池,当到达线程最大数量时,线程池的规模将不再变化。
|
||||
*/
|
||||
private static void fixedThreadPool() {
|
||||
ExecutorService exec = Executors.newFixedThreadPool(5);
|
||||
for(int i = 0; i < 10; i++) {
|
||||
exec.execute(new MyThread2(String.valueOf(i)));
|
||||
}
|
||||
exec.shutdown(); //执行到此处并不会马上关闭线程池
|
||||
System.out.println("运行结束!");
|
||||
/**
|
||||
* 1线程开始运行,时间2018-03-01 11:50:33 170
|
||||
4线程开始运行,时间2018-03-01 11:50:33 170
|
||||
3线程开始运行,时间2018-03-01 11:50:33 170
|
||||
2线程开始运行,时间2018-03-01 11:50:33 170
|
||||
0线程开始运行,时间2018-03-01 11:50:33 170
|
||||
4线程运行结束,时间2018-03-01 11:50:34 171
|
||||
3线程运行结束,时间2018-03-01 11:50:34 171
|
||||
2线程运行结束,时间2018-03-01 11:50:34 171
|
||||
5线程开始运行,时间2018-03-01 11:50:34 172
|
||||
6线程开始运行,时间2018-03-01 11:50:34 172
|
||||
7线程开始运行,时间2018-03-01 11:50:34 172
|
||||
1线程运行结束,时间2018-03-01 11:50:34 172
|
||||
0线程运行结束,时间2018-03-01 11:50:34 172
|
||||
8线程开始运行,时间2018-03-01 11:50:34 172
|
||||
9线程开始运行,时间2018-03-01 11:50:34 172
|
||||
8线程运行结束,时间2018-03-01 11:50:35 181
|
||||
6线程运行结束,时间2018-03-01 11:50:35 181
|
||||
9线程运行结束,时间2018-03-01 11:50:35 181
|
||||
7线程运行结束,时间2018-03-01 11:50:35 181
|
||||
5线程运行结束,时间2018-03-01 11:50:35 181
|
||||
|
||||
结论:1,FixedThreadPool模式会使用一个优先固定数目的线程来处理若干数目的任务。
|
||||
2,FixedThreadPool模式下最多 的线程数目是一定的。
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个单线程的Executor,确保任务对了,串行执行
|
||||
*/
|
||||
private static void newSingleThreadExecutor() {
|
||||
ExecutorService exec = Executors.newSingleThreadExecutor(); //创建大小为1的固定线程池
|
||||
for(int i = 0; i < 10; i++) {
|
||||
exec.execute(new MyThread2(String.valueOf(i)));
|
||||
}
|
||||
exec.shutdown(); //执行到此处并不会马上关闭线程池
|
||||
System.out.println("运行结束!");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建一个固定长度的线程池,而且以延迟或者定时的方式来执行,类似Timer;
|
||||
*/
|
||||
private static void newScheduledThreadPool() {
|
||||
ScheduledThreadPoolExecutor exec = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(10); //创建大小为10的线程池
|
||||
for(int i = 0; i < 10; i++) {
|
||||
exec.schedule(new MyThread2(String.valueOf(i)), 2, TimeUnit.SECONDS);//延迟2秒执行
|
||||
}
|
||||
//如果任务都完成了则返回true
|
||||
while(!exec.isTerminated()){
|
||||
//wait for all tasks to finish
|
||||
// System.out.println("正在运行中...");
|
||||
}
|
||||
System.out.println("运行结束!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置固定时间执行
|
||||
*/
|
||||
private static void newScheduledThreadPool2() {
|
||||
ScheduledThreadPoolExecutor exec = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(10); //创建大小为10的线程池
|
||||
long oneDay = 24 * 60 * 60 * 1000;
|
||||
long initDelay = getTimeMillis("14:08:00") - System.currentTimeMillis();
|
||||
initDelay = initDelay > 0 ? initDelay : oneDay + initDelay;
|
||||
exec.scheduleAtFixedRate(new MyThread2(String.valueOf(1)), initDelay, oneDay, TimeUnit.MILLISECONDS);
|
||||
System.out.println("运行结束!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定时间对应的毫秒数
|
||||
* @param time "HH:mm:ss"
|
||||
* @return
|
||||
*/
|
||||
private static long getTimeMillis(String time) {
|
||||
try {
|
||||
DateFormat dateFormat = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
|
||||
DateFormat dayFormat = new SimpleDateFormat("yy-MM-dd");
|
||||
Date curDate = dateFormat.parse(dayFormat.format(new Date()) + " " + time);
|
||||
return curDate.getTime();
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ThreadPoolExecutor线程池
|
||||
*/
|
||||
private static void threadPoolExecutor() {
|
||||
int corePoolSize=5;
|
||||
int maximumPoolSize=10;
|
||||
long keepAliveTime=2L;
|
||||
// 线程核心数,最大线程数,线程缓存时间,时间格式,缓存队列 ,线程工厂,拒绝策略
|
||||
ThreadPoolExecutor tpx=new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime,
|
||||
TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3),
|
||||
Executors.defaultThreadFactory(),new ThreadPoolExecutor.DiscardOldestPolicy());
|
||||
|
||||
for (int i = 1; i <= 10; i++) {
|
||||
try {
|
||||
// 产生一个任务,并将其加入到线程池
|
||||
String task = "task@ " + i;
|
||||
// System.out.println("put " + task);
|
||||
tpx.execute(new MyThread2(task));
|
||||
// 便于观察,等待一段时间
|
||||
Thread.sleep(20);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
class MyThread2 implements Runnable{
|
||||
private String name;
|
||||
public MyThread2(String name){
|
||||
this.name=name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println(name+ "线程开始运行,时间:" +getNowTime());
|
||||
pause(1000);
|
||||
System.out.println(name+ "线程运行结束,时间:" +getNowTime());
|
||||
}
|
||||
|
||||
private void pause(long lo) {
|
||||
try {
|
||||
Thread.sleep(lo);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String getNowTime(){
|
||||
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(new Date());
|
||||
}
|
||||
|
||||
}
|
||||
44
src/main/java/com/pancm/thread/test/ThreadTest1.java
Normal file
44
src/main/java/com/pancm/thread/test/ThreadTest1.java
Normal file
@ -0,0 +1,44 @@
|
||||
package com.pancm.thread.test;
|
||||
/**
|
||||
* @author ZERO
|
||||
* @Data 2017-5-24 下午2:22:41
|
||||
* @Description
|
||||
*/
|
||||
public class ThreadTest1 {
|
||||
|
||||
public static void main(String[] args) {
|
||||
myThread();
|
||||
System.out.println("\r\n");
|
||||
myRunnable();
|
||||
}
|
||||
|
||||
|
||||
public static void myThread(){
|
||||
for (int i = 0; i < 10; i++) {
|
||||
System.out.println("myThreadTest:"+Thread.currentThread().getName() + " " + i);
|
||||
if (i == 3) {
|
||||
Thread myThread1 = new MyThread(); // 创建一个新的线程 myThread1 此线程进入新建状态
|
||||
Thread myThread2 = new MyThread(); // 创建一个新的线程 myThread2 此线程进入新建状态
|
||||
myThread1.start(); // 调用start()方法使得线程进入就绪状态
|
||||
myThread2.start(); // 调用start()方法使得线程进入就绪状态
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void myRunnable(){
|
||||
for (int i = 0; i < 10; i++) {
|
||||
System.out.println("myRunnableTest:"+Thread.currentThread().getName() + " " + i);
|
||||
if (i == 3) {
|
||||
Runnable myRunnable = new MyRunnable(); // 创建一个Runnable实现类的对象
|
||||
Thread thread1 = new Thread(myRunnable); // 将myRunnable作为Thread target创建新的线程
|
||||
Thread thread2 = new Thread(myRunnable);
|
||||
thread1.start(); // 调用start()方法使得线程进入就绪状态
|
||||
thread2.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user