├── .mvn └── wrapper │ ├── maven-wrapper.jar │ ├── maven-wrapper.properties │ └── MavenWrapperDownloader.java ├── src ├── main │ ├── resources │ │ ├── banner.jpg │ │ ├── application-sit.properties │ │ ├── META-INF │ │ │ └── spring.factories │ │ ├── beans.xml │ │ └── application.properties │ ├── java │ │ └── com │ │ │ └── zs │ │ │ └── demo │ │ │ ├── dao │ │ │ ├── DepartmentDao.java │ │ │ ├── mapper │ │ │ │ ├── Dept.xml │ │ │ │ └── Emp.xml │ │ │ └── EmployeeDao.java │ │ │ ├── bean │ │ │ ├── Pig.java │ │ │ ├── MsgLog.java │ │ │ ├── Car.java │ │ │ ├── Book.java │ │ │ ├── Article.java │ │ │ ├── Department.java │ │ │ ├── Desk.java │ │ │ ├── User.java │ │ │ └── Employee.java │ │ │ ├── listener │ │ │ ├── HelloApplicationRunner.java │ │ │ ├── HelloCommandLineRunner.java │ │ │ ├── HelloApplicationContextInitializer.java │ │ │ ├── HelloDelegatingApplicationContextInitializer.java │ │ │ └── HelloSpringApplicationRunListener.java │ │ │ ├── repository │ │ │ └── BookRepository.java │ │ │ ├── config │ │ │ ├── MyAMQPConfig.java │ │ │ ├── MyCacheConfig.java │ │ │ ├── MyConfig.java │ │ │ └── MyRedisConfig.java │ │ │ ├── controller │ │ │ ├── HelloController.java │ │ │ ├── DeptController.java │ │ │ └── EmployeeController.java │ │ │ ├── service │ │ │ ├── BookService.java │ │ │ ├── DeptService.java │ │ │ └── EmployeeService.java │ │ │ ├── ag │ │ │ ├── sort │ │ │ │ ├── insertSort.java │ │ │ │ ├── bubbleSort.java │ │ │ │ └── selectSort.java │ │ │ ├── Test_NumberSum.java │ │ │ ├── RobotCountWays.java │ │ │ ├── TriangleSum.java │ │ │ ├── hw │ │ │ │ ├── randomSort.java │ │ │ │ ├── dp.java │ │ │ │ ├── findWordCount.java │ │ │ │ └── lastWordLength.java │ │ │ ├── SpaceReplace.java │ │ │ └── Test_SortNumberOthers.java │ │ │ ├── DemoApplication.java │ │ │ └── ie │ │ │ └── ie.md │ └── webapp │ │ ├── WEB-INF │ │ ├── web.xml │ │ └── test.jsp │ │ └── hello.jsp └── test │ └── java │ └── com │ └── zs │ └── demo │ ├── cache │ └── Springboot01CacheApplicationTests.java │ ├── DemoApplicationTests.java │ ├── rabbit │ └── DemoApplicationTests.java │ └── elastic │ └── Springboot03ElasticApplicationTests.java ├── .gitignore ├── pom.xml └── mvnw /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deserialization/springboot/main/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /src/main/resources/banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deserialization/springboot/main/src/main/resources/banner.jpg -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/dao/DepartmentDao.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.dao; 2 | 3 | import com.zs.demo.bean.Department; 4 | import org.apache.ibatis.annotations.Mapper; 5 | 6 | @Mapper 7 | public interface DepartmentDao { 8 | 9 | 10 | Department deptById(Integer id); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/resources/application-sit.properties: -------------------------------------------------------------------------------- 1 | mycar.brand=YDDD 2 | mycar.price=10000 3 | 4 | debug=true 5 | spring.banner.image.location=banner.jpg 6 | spring.profiles.active=sit 7 | 8 | spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xhwmppre 9 | spring.datasource.username=root 10 | spring.datasource.password=root 11 | 12 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | #org.springframework.context.ApplicationContextInitializer=\ 2 | #com.zs.demo.listener.HelloApplicationContextInitializer 3 | org.springframework.boot.SpringApplicationRunListener=\ 4 | com.zs.demo.listener.HelloSpringApplicationRunListener 5 | org.springframework.context.ApplicationContextInitializer=\ 6 | com.zs.demo.listener.HelloDelegatingApplicationContextInitializer -------------------------------------------------------------------------------- /src/main/webapp/hello.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | Created by IntelliJ IDEA. 3 | User: lfy 4 | Date: 2018/3/2 5 | Time: 19:46 6 | To change this template use File | Settings | File Templates. 7 | --%> 8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 9 | 10 | 11 | Title 12 | 13 | 14 |

Hello JSP

15 | abc 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/bean/Pig.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.bean; 2 | 3 | /** 4 | * @author 么么么哒 5 | * @create 2021/1/9 6 | */ 7 | public class Pig { 8 | private String name; 9 | 10 | public Pig(String name) { 11 | this.name = name; 12 | } 13 | 14 | public Pig() { 15 | 16 | } 17 | 18 | public String getName() { 19 | return name; 20 | } 21 | 22 | public void setName(String name) { 23 | this.name = name; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/test.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | Created by IntelliJ IDEA. 3 | User: lfy 4 | Date: 2018/3/2 5 | Time: 19:47 6 | To change this template use File | Settings | File Templates. 7 | --%> 8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 9 | 10 | 11 | Title 12 | 13 | 14 |

Hel

15 |

Hello JSP

16 | abc 17 |

${msg}

18 |

SUCCESS2

19 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/listener/HelloApplicationRunner.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.listener; 2 | 3 | import org.springframework.boot.ApplicationArguments; 4 | import org.springframework.boot.ApplicationRunner; 5 | import org.springframework.stereotype.Component; 6 | 7 | @Component 8 | public class HelloApplicationRunner implements ApplicationRunner { 9 | @Override 10 | public void run(ApplicationArguments args) throws Exception { 11 | System.out.println("ApplicationRunner...run...."); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/repository/BookRepository.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.repository; 2 | 3 | import com.zs.demo.bean.Desk; 4 | import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; 5 | 6 | import java.util.List; 7 | 8 | 9 | public interface BookRepository extends ElasticsearchRepository { 10 | 11 | //参照 12 | // https://docs.spring.io/spring-data/elasticsearch/docs/3.0.6.RELEASE/reference/html/ 13 | public List findByBookNameLike(String bookName); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/config/MyAMQPConfig.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.config; 2 | 3 | import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; 4 | import org.springframework.amqp.support.converter.MessageConverter; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | @Configuration 9 | public class MyAMQPConfig { 10 | 11 | @Bean 12 | public MessageConverter messageConverter(){ 13 | return new Jackson2JsonMessageConverter(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/controller/HelloController.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.controller; 2 | 3 | import org.springframework.ui.Model; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | /** 8 | * @author 么么么哒 9 | * @create 2021/1/9 10 | */ 11 | @RestController 12 | public class HelloController { 13 | 14 | @RequestMapping("/hello") 15 | public String hello(Model model){ 16 | model.addAttribute("msg","你好"); 17 | return "test"; 18 | } 19 | 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/listener/HelloCommandLineRunner.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.listener; 2 | 3 | import org.springframework.boot.CommandLineRunner; 4 | import org.springframework.core.annotation.Order; 5 | import org.springframework.stereotype.Component; 6 | 7 | import java.util.Arrays; 8 | 9 | 10 | @Order 11 | @Component 12 | public class HelloCommandLineRunner implements CommandLineRunner { 13 | @Override 14 | public void run(String... args) throws Exception { 15 | System.out.println("CommandLineRunner...run..."+ Arrays.asList(args)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/listener/HelloApplicationContextInitializer.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.listener; 2 | 3 | import org.springframework.context.ApplicationContextInitializer; 4 | import org.springframework.context.ConfigurableApplicationContext; 5 | 6 | public class HelloApplicationContextInitializer implements ApplicationContextInitializer { 7 | @Override 8 | public void initialize(ConfigurableApplicationContext applicationContext) { 9 | System.out.println("ApplicationContextInitializer...initialize..."+applicationContext); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/listener/HelloDelegatingApplicationContextInitializer.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.listener; 2 | 3 | import org.springframework.context.ApplicationContextInitializer; 4 | import org.springframework.context.ConfigurableApplicationContext; 5 | 6 | public class HelloDelegatingApplicationContextInitializer implements ApplicationContextInitializer { 7 | @Override 8 | public void initialize(ConfigurableApplicationContext applicationContext) { 9 | System.out.println("HelloDelegatingApplicationContextInitializer...initialize..."+applicationContext); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/bean/MsgLog.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.bean; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | import java.util.Date; 9 | 10 | /** 11 | * @author 么么么哒 12 | * @create 2021/1/21 13 | */ 14 | @Data 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class MsgLog implements Serializable { 18 | private static final long serialVersionUID = 4985305866762231111L; 19 | private int id; 20 | private String type; 21 | private int type1; 22 | private String kind; 23 | private Date date; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/resources/beans.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/dao/mapper/Dept.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/service/BookService.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.service; 2 | 3 | import com.zs.demo.bean.Book; 4 | import org.springframework.amqp.core.Message; 5 | import org.springframework.amqp.rabbit.annotation.RabbitListener; 6 | import org.springframework.stereotype.Service; 7 | 8 | @Service 9 | public class BookService { 10 | 11 | @RabbitListener(queues = "atguigu.news") 12 | public void receive(Book book){ 13 | System.out.println("收到消息:"+book); 14 | } 15 | 16 | @RabbitListener(queues = "atguigu") 17 | public void receive02(Message message){ 18 | System.out.println(message.getBody()); 19 | System.out.println(message.getMessageProperties()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/controller/DeptController.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.controller; 2 | 3 | import com.zs.demo.bean.Department; 4 | import com.zs.demo.service.DeptService; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.PathVariable; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | @RestController 11 | public class DeptController { 12 | 13 | @Autowired 14 | DeptService deptService; 15 | 16 | @GetMapping("/dept/{id}") 17 | public Department getDept(@PathVariable("id") Integer id){ 18 | return deptService.getDeptById(id); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/config/MyCacheConfig.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.config; 2 | 3 | import org.springframework.cache.interceptor.KeyGenerator; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | import java.lang.reflect.Field; 8 | import java.lang.reflect.Method; 9 | import java.util.Arrays; 10 | 11 | @Configuration 12 | public class MyCacheConfig { 13 | 14 | @Bean("myKeyGenerator") 15 | public KeyGenerator keyGenerator(){ 16 | return new KeyGenerator(){ 17 | 18 | @Override 19 | public Object generate(Object target, Method method, Object... params) { 20 | 21 | return method.getName()+"["+ Arrays.asList(params).toString()+"]"; 22 | 23 | } 24 | }; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/dao/EmployeeDao.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.dao; 2 | 3 | import com.zs.demo.bean.Employee; 4 | import org.apache.ibatis.annotations.*; 5 | 6 | @Mapper 7 | public interface EmployeeDao { 8 | 9 | public Employee getEmpById(Integer id); 10 | 11 | @Update("UPDATE employee SET lastName=#{lastName},email=#{email},gender=#{gender},d_id=#{dId} WHERE id=#{id}") 12 | public void updateEmp(Employee employee); 13 | 14 | @Delete("DELETE FROM employee WHERE id=#{id}") 15 | public void deleteEmpById(Integer id); 16 | 17 | @Insert("INSERT INTO employee(lastName,email,gender,d_id) VALUES(#{lastName},#{email},#{gender},#{dId})") 18 | public void insertEmployee(Employee employee); 19 | 20 | @Select("SELECT * FROM employee WHERE lastName = #{lastName}") 21 | Employee getEmpByLastName(String lastName); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/ag/sort/insertSort.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.ag.sort; 2 | 3 | public class insertSort { 4 | public static void main(String[] args) { 5 | 6 | int[] array = {3, 4, 1, 5, 2}; 7 | for (int i = 1; i < array.length; i++) { 8 | for (int j = i; j > 0; j--) { 9 | if (array[j] < array[j - 1]) { 10 | swap(array, j, j - 1); 11 | } 12 | } 13 | } 14 | print(array); 15 | } 16 | 17 | private static void swap(int[] array, int i, int minPos) { 18 | int temp = array[minPos]; 19 | array[minPos] = array[i]; 20 | array[i] = temp; 21 | } 22 | 23 | private static void print(int[] array) { 24 | for (int i = 0; i < array.length; i++) { 25 | System.out.print(array[i] + " "); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/ag/sort/bubbleSort.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.ag.sort; 2 | 3 | public class bubbleSort { 4 | public static void main(String[] args) { 5 | int[] array = {3, 4, 1, 5, 2}; 6 | 7 | for (int i = array.length; i > 0; i--) { 8 | for (int j = 0; j < i - 1; j++) { 9 | if (array[j] > array[j + 1]) { 10 | swap(array, j, j + 1); 11 | } 12 | } 13 | } 14 | print(array); 15 | 16 | } 17 | 18 | private static void swap(int[] array, int i, int minPos) { 19 | int temp = array[minPos]; 20 | array[minPos] = array[i]; 21 | array[i] = temp; 22 | } 23 | 24 | private static void print(int[] array) { 25 | for (int i = 0; i < array.length; i++) { 26 | System.out.print(array[i] + " "); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/dao/mapper/Emp.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 18 | 19 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/ag/Test_NumberSum.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.ag; 2 | 3 | 4 | import java.util.Scanner; 5 | 6 | /** 7 | *

8 | * 数列的第一项为n,以后各项为前一项的平方根,求数列的前m项的和。 9 | * 输入描述: 10 | * 输入数据有多组,每组占一行,由两个整数n(n < 10000)和m(m < 1000)组成,n和m的含义如前所述。 11 | *

12 | *

13 | * 输出描述: 14 | * 对于每组输入数据,输出该数列的和,每个测试实例占一行,要求精度保留2位小数。 15 | */ 16 | public class Test_NumberSum { 17 | 18 | public static void main(String[] args) { 19 | Scanner scanner = new Scanner(System.in); 20 | while (scanner.hasNext()) { 21 | double m = scanner.nextDouble(); 22 | double n = scanner.nextDouble(); 23 | double sum = 0; 24 | for (int i = 0; i < n; i++) { 25 | sum = sum + m; 26 | m = Math.pow(m, 0.5); 27 | } 28 | System.out.println(String.format("%.2f", sum));//保证小数掉过后两位有效数字 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/bean/Car.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.bean; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | 5 | /** 6 | * @author 么么么哒 7 | * @create 2021/1/9 8 | */ 9 | //@Component 10 | @ConfigurationProperties(prefix = "mycar") 11 | public class Car { 12 | private String brand; 13 | private Integer price; 14 | public String getBrand() { 15 | return brand; 16 | } 17 | 18 | public void setBrand(String brand) { 19 | this.brand = brand; 20 | } 21 | 22 | public Integer getPrice() { 23 | return price; 24 | } 25 | 26 | public void setPrice(Integer price) { 27 | this.price = price; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return "Car{" + 33 | "brand='" + brand + '\'' + 34 | ", price=" + price + 35 | '}'; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/bean/Book.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.bean; 2 | 3 | public class Book { 4 | private String bookName; 5 | private String author; 6 | 7 | public Book() { 8 | } 9 | 10 | public Book(String bookName, String author) { 11 | this.bookName = bookName; 12 | this.author = author; 13 | } 14 | 15 | public String getBookName() { 16 | return bookName; 17 | } 18 | 19 | public void setBookName(String bookName) { 20 | this.bookName = bookName; 21 | } 22 | 23 | public String getAuthor() { 24 | return author; 25 | } 26 | 27 | public void setAuthor(String author) { 28 | this.author = author; 29 | } 30 | 31 | @Override 32 | public String toString() { 33 | return "Book{" + 34 | "bookName='" + bookName + '\'' + 35 | ", author='" + author + '\'' + 36 | '}'; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/config/MyConfig.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.config; 2 | 3 | import com.zs.demo.bean.Car; 4 | import com.zs.demo.bean.Pig; 5 | import com.zs.demo.bean.User; 6 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.ImportResource; 9 | 10 | /** 11 | * @author 么么么哒 12 | * @create 2021/1/9 13 | */ 14 | //@Configuration(proxyBeanMethods = false) 15 | //@ConditionalOnBean(name = "pig1") 16 | @ImportResource("classpath:beans.xml") 17 | @EnableConfigurationProperties(Car.class) 18 | public class MyConfig { 19 | @Bean 20 | public User user1(){ 21 | User user = new User("zs",12); 22 | user.setPig(pig1()); 23 | System.out.println(user.toString()); 24 | return user; 25 | } 26 | 27 | @Bean("pig11") 28 | public Pig pig1(){ 29 | return new Pig("zs"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/bean/Article.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.bean; 2 | 3 | import io.searchbox.annotations.JestId; 4 | 5 | public class Article { 6 | 7 | @JestId 8 | private Integer id; 9 | private String author; 10 | private String title; 11 | private String content; 12 | 13 | public Integer getId() { 14 | return id; 15 | } 16 | 17 | public void setId(Integer id) { 18 | this.id = id; 19 | } 20 | 21 | public String getAuthor() { 22 | return author; 23 | } 24 | 25 | public void setAuthor(String author) { 26 | this.author = author; 27 | } 28 | 29 | public String getTitle() { 30 | return title; 31 | } 32 | 33 | public void setTitle(String title) { 34 | this.title = title; 35 | } 36 | 37 | public String getContent() { 38 | return content; 39 | } 40 | 41 | public void setContent(String content) { 42 | this.content = content; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/ag/sort/selectSort.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.ag.sort; 2 | 3 | public class selectSort { 4 | public static void main(String[] args) { 5 | int[] array = {3, 4, 1, 5, 2}; 6 | 7 | //剩余中找最小的 8 | for (int i = 0; i < array.length; i++) { 9 | //只为了找最小的 10 | int minPos = i; 11 | for (int j = i + 1; j < array.length; j++) { 12 | if (array[j] < array[minPos]) { 13 | minPos = j; 14 | } 15 | } 16 | swap(array, i, minPos); 17 | } 18 | print(array); 19 | } 20 | 21 | private static void swap(int[] array, int i, int minPos) { 22 | int temp = array[minPos]; 23 | array[minPos] = array[i]; 24 | array[i] = temp; 25 | } 26 | 27 | private static void print(int[] array) { 28 | for (int i = 0; i < array.length; i++) { 29 | System.out.print(array[i] + " "); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/bean/Department.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.bean; 2 | 3 | 4 | import lombok.Data; 5 | 6 | import java.io.Serializable; 7 | 8 | @Data 9 | public class Department implements Serializable { 10 | 11 | private static final long serialVersionUID = -9002515762089328752L; 12 | private Integer id; 13 | private String departmentName; 14 | 15 | 16 | public Department() { 17 | super(); 18 | // TODO Auto-generated constructor stub 19 | } 20 | public Department(Integer id, String departmentName) { 21 | super(); 22 | this.id = id; 23 | this.departmentName = departmentName; 24 | } 25 | public Integer getId() { 26 | return id; 27 | } 28 | public void setId(Integer id) { 29 | this.id = id; 30 | } 31 | public String getDepartmentName() { 32 | return departmentName; 33 | } 34 | public void setDepartmentName(String departmentName) { 35 | this.departmentName = departmentName; 36 | } 37 | @Override 38 | public String toString() { 39 | return "Department [id=" + id + ", departmentName=" + departmentName + "]"; 40 | } 41 | 42 | 43 | 44 | 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/bean/Desk.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.bean; 2 | 3 | import org.springframework.data.elasticsearch.annotations.Document; 4 | 5 | @Document(indexName = "atguigu",type = "book") 6 | public class Desk { 7 | private Integer id; 8 | private String bookName; 9 | private String author; 10 | 11 | public Integer getId() { 12 | return id; 13 | } 14 | 15 | public void setId(Integer id) { 16 | this.id = id; 17 | } 18 | 19 | public String getBookName() { 20 | return bookName; 21 | } 22 | 23 | public void setBookName(String bookName) { 24 | this.bookName = bookName; 25 | } 26 | 27 | public String getAuthor() { 28 | return author; 29 | } 30 | 31 | public void setAuthor(String author) { 32 | this.author = author; 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return "Book{" + 38 | "id=" + id + 39 | ", bookName='" + bookName + '\'' + 40 | ", author='" + author + '\'' + 41 | '}'; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/bean/User.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.bean; 2 | 3 | /** 4 | * @author 么么么哒 5 | * @create 2021/1/9 6 | */ 7 | public class User { 8 | public String name; 9 | private Integer age; 10 | 11 | private Pig pig; 12 | 13 | public User(String name, Integer age) { 14 | this.name = name; 15 | this.age = age; 16 | } 17 | 18 | public User() { 19 | 20 | } 21 | 22 | public String getName() { 23 | return name; 24 | } 25 | 26 | public void setName(String name) { 27 | this.name = name; 28 | } 29 | 30 | public Integer getAge() { 31 | return age; 32 | } 33 | 34 | public void setAge(Integer age) { 35 | this.age = age; 36 | } 37 | 38 | public Pig getPig() { 39 | return pig; 40 | } 41 | 42 | public void setPig(Pig pig) { 43 | this.pig = pig; 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return "User{" + 49 | "name='" + name + '\'' + 50 | ", age=" + age + 51 | ", pig=" + pig + 52 | '}'; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/ag/RobotCountWays.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.ag; 2 | 3 | import java.util.Scanner; 4 | 5 | public class RobotCountWays { 6 | public static void main(String[] args) { 7 | Scanner scanner = new Scanner(System.in); 8 | while (scanner.hasNext()) { 9 | int x = scanner.nextInt(); 10 | int y = scanner.nextInt(); 11 | System.out.println(countWays1(x, y)); 12 | } 13 | } 14 | 15 | private static int countWays(int x, int y) { 16 | int[][] dp = new int[x][y]; 17 | for (int i = 1; i < y; i++) 18 | dp[0][i] = 1; 19 | for (int i = 1; i < x; i++) 20 | dp[i][0] = 1; 21 | for (int i = 1; i < x; i++) 22 | for (int j = 1; j < y; j++) 23 | dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; 24 | return dp[x - 1][y - 1]; 25 | } 26 | 27 | 28 | public static int countWays1(int x, int y) { 29 | if (x == 1 || y == 1) 30 | return 1; 31 | System.out.println(x); 32 | System.out.println(y); 33 | return countWays1(x - 1, y) + countWays1(x, y - 1); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/ag/TriangleSum.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.ag; 2 | 3 | import java.util.Scanner; 4 | 5 | /** 6 | * 5 7 | * 7 8 | * 3 8 9 | * 8 1 0 10 | * 2 7 4 4 11 | * 4 5 2 6 5 12 | */ 13 | public class TriangleSum { 14 | static int n = 0; 15 | static int[][] array = null; 16 | static int[][] maxSum = null; 17 | public static void main(String[] args) { 18 | while(true){ 19 | Scanner scanner = new Scanner(System.in); 20 | n = scanner.nextInt(); 21 | array = new int[n + 1][n + 1]; 22 | maxSum = new int[n + 1][n + 1]; 23 | for (int i = 1; i <= n; i++) { 24 | for (int j = 1; j <= i; j++) { 25 | array[i][j] = scanner.nextInt(); 26 | maxSum[i][j] = -1; 27 | } 28 | } 29 | System.out.println(maxSum(1,1)); 30 | } 31 | } 32 | 33 | private static int maxSum(int x, int y) { 34 | if(maxSum[x][y] != -1) return maxSum[x][y]; 35 | if (x == n) 36 | return array[x][y]; 37 | else 38 | return Math.max(maxSum(x + 1,y),maxSum(x + 1,y + 1)) + array[x][y]; 39 | } 40 | 41 | } -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/ag/hw/randomSort.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.ag.hw; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.InputStreamReader; 5 | import java.util.TreeSet; 6 | import java.util.Scanner; 7 | import java.util.TreeSet; 8 | 9 | public class randomSort { 10 | /** 11 | * 明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性, 12 | * 他先用计算机生成了N个1到1000之间的随机整数(N≤1000) 13 | * ,对于其中重复的数字,只保留一个,把其余相同的数去掉, 14 | * 不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。 15 | * 请你协助明明完成“去重”与“排序”的工作(同一个测试用例里可能会有多组数据,希望大家能正确处理)。 16 | */ 17 | 18 | public static void main(String[] args)throws Exception{ 19 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 20 | String str; 21 | 22 | while ((str = br.readLine()) != null) { 23 | boolean[] flags = new boolean[1001]; 24 | StringBuilder sb = new StringBuilder(); 25 | int n = Integer.valueOf(str); 26 | for (int i = 0; i < n; i++) 27 | flags[Integer.valueOf(br.readLine())]=true; 28 | 29 | for(int i=1;i<1001;i++){ 30 | if(flags[i]) 31 | sb.append(i).append("\n"); 32 | } 33 | sb.deleteCharAt(sb.length() - 1); 34 | System.out.println(sb.toString()); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/ag/SpaceReplace.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.ag; 2 | 3 | 4 | public class SpaceReplace { 5 | public static void main(String[] args) { 6 | StringBuffer stringBuffer = new StringBuffer("we are lucky"); 7 | System.out.println(spaceReplace(stringBuffer)); 8 | } 9 | 10 | private static String spaceReplace(StringBuffer stringBuffer) { 11 | int numSpace = 0; 12 | for (int i = 0; i < stringBuffer.length(); i++) { 13 | if (stringBuffer.charAt(i) == ' ') { 14 | numSpace++; 15 | } 16 | } 17 | int oldIndex = stringBuffer.length() - 1; 18 | int stringLength = stringBuffer.length() + numSpace * 2; 19 | int newIndex = stringLength - 1; 20 | stringBuffer.setLength(stringLength); 21 | for (; oldIndex >= 0 && oldIndex < stringLength; --oldIndex) { 22 | if (stringBuffer.charAt(oldIndex) == ' ') { 23 | stringBuffer.setCharAt(newIndex--, '%'); 24 | stringBuffer.setCharAt(newIndex--, '2'); 25 | stringBuffer.setCharAt(newIndex--, '0'); 26 | } else { 27 | stringBuffer.setCharAt(newIndex--, stringBuffer.charAt(oldIndex)); 28 | } 29 | } 30 | return stringBuffer.toString(); 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/controller/EmployeeController.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.controller; 2 | 3 | import com.zs.demo.bean.Employee; 4 | import com.zs.demo.service.EmployeeService; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.PathVariable; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | @RestController 11 | public class EmployeeController { 12 | 13 | @Autowired 14 | EmployeeService employeeService; 15 | 16 | @GetMapping("/emp/{id}") 17 | public Employee getEmployee(@PathVariable("id") Integer id){ 18 | Employee employee = employeeService.getEmp(id); 19 | return employee; 20 | } 21 | 22 | @GetMapping("/emp") 23 | public Employee update(Employee employee){ 24 | Employee emp = employeeService.updateEmp(employee); 25 | 26 | return emp; 27 | } 28 | 29 | @GetMapping("/delemp") 30 | public String deleteEmp(Integer id){ 31 | employeeService.deleteEmp(id); 32 | return "success"; 33 | } 34 | 35 | @GetMapping("/emp/lastname/{lastName}") 36 | public Employee getEmpByLastName(@PathVariable("lastName") String lastName){ 37 | return employeeService.getEmpByLastName(lastName); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | mycar.brand=YDDD 2 | mycar.price=10000 3 | 4 | debug=true 5 | spring.banner.image.location=banner.jpg 6 | spring.profiles.active=dev 7 | 8 | spring.datasource.url=jdbc:mysql://10.47.128.129:3306/xhwmppre 9 | spring.datasource.username=fabu 10 | spring.datasource.password=73R4_h8td6fE 11 | 12 | spring.mvc.view.prefix=/WEB-INF/ 13 | spring.mvc.view.suffix=.jsp 14 | 15 | 16 | # ���������õ����Զ�����Դ��������ܵ�properties�� 17 | server.servlet.encoding.enabled=true 18 | server.spring.http.encoding.charset=utf-8 19 | server.spring.http.encoding.force=true 20 | 21 | #mybatis.mapperLocations=classpath*:com/example/demo/mapper/*.xml 22 | #mybatis.configuration.map-underscore-to-camel-case=true 23 | 24 | # ָ��ȫ�������ļ�λ�� Ҳ����ָ��ӳ���ļ�λ�� 25 | mybatis.mapper-locations=classpath*:com/zs/demo/dao/mapper/*.xml 26 | mybatis.configuration.map-underscore-to-camel-case=true 27 | 28 | 29 | spring.redis.host=127.0.0.1 30 | 31 | logging.level.com.zs.demo.dao.mapper=debug 32 | 33 | #spring.rabbitmq.virtual-host= 34 | spring.rabbitmq.host=127.0.0.1 35 | spring.rabbitmq.username=guest 36 | spring.rabbitmq.password=guest 37 | 38 | #spring.kafka.bootstrap-servers=127.0.0.1:9092 39 | 40 | spring.elasticsearch.jest.uris=http://127.0.0.1:9200 41 | spring.data.elasticsearch.cluster-name=elasticsearch 42 | spring.data.elasticsearch.repositories.enabled = true 43 | spring.data.elasticsearch.cluster-nodes =127.0.0.1:9300 -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/service/DeptService.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.service; 2 | 3 | import com.zs.demo.bean.Department; 4 | import com.zs.demo.dao.DepartmentDao; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.beans.factory.annotation.Qualifier; 7 | import org.springframework.cache.Cache; 8 | import org.springframework.cache.annotation.Cacheable; 9 | import org.springframework.data.redis.cache.RedisCacheManager; 10 | import org.springframework.stereotype.Service; 11 | 12 | 13 | @Service 14 | public class DeptService { 15 | 16 | @Autowired 17 | DepartmentDao departmentDao; 18 | 19 | @Qualifier("rManager") 20 | @Autowired 21 | RedisCacheManager deptCacheManager; 22 | 23 | 24 | /** 25 | * 缓存的数据能存入redis; 26 | * 第二次从缓存中查询就不能反序列化回来; 27 | * 存的是dept的json数据;CacheManager默认使用RedisTemplate操作Redis 28 | * @param id 29 | * @return 30 | */ 31 | 32 | // 使用缓存管理器得到缓存,进行api调用 33 | @Cacheable(cacheNames = "dept",cacheManager = "deptCacheManager") 34 | //@Cacheable(cacheNames = "dept",key = "#root.methodName+'['+#id+']'") 35 | public Department getDeptById(Integer id){ 36 | Department department = departmentDao.deptById(id); 37 | 38 | //获取某个缓存 39 | Cache dept = deptCacheManager.getCache("dept"); 40 | dept.put("dept:1",department); 41 | 42 | return department; 43 | } 44 | 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/bean/Employee.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.bean; 2 | 3 | import java.io.Serializable; 4 | 5 | 6 | /** 7 | * @author 么么么哒 8 | */ 9 | public class Employee implements Serializable { 10 | 11 | private static final long serialVersionUID = 7427456985825117634L; 12 | private Integer id; 13 | private String lastName; 14 | private String email; 15 | private Integer gender; //性别 1男 0女 16 | private Integer dId; 17 | 18 | 19 | public Employee() { 20 | super(); 21 | } 22 | 23 | 24 | public Employee(Integer id, String lastName, String email, Integer gender, Integer dId) { 25 | super(); 26 | this.id = id; 27 | this.lastName = lastName; 28 | this.email = email; 29 | this.gender = gender; 30 | this.dId = dId; 31 | } 32 | 33 | public Integer getId() { 34 | return id; 35 | } 36 | public void setId(Integer id) { 37 | this.id = id; 38 | } 39 | public String getLastName() { 40 | return lastName; 41 | } 42 | public void setLastName(String lastName) { 43 | this.lastName = lastName; 44 | } 45 | public String getEmail() { 46 | return email; 47 | } 48 | public void setEmail(String email) { 49 | this.email = email; 50 | } 51 | public Integer getGender() { 52 | return gender; 53 | } 54 | public void setGender(Integer gender) { 55 | this.gender = gender; 56 | } 57 | public Integer getdId() { 58 | return dId; 59 | } 60 | public void setdId(Integer dId) { 61 | this.dId = dId; 62 | } 63 | @Override 64 | public String toString() { 65 | return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + ", dId=" 66 | + dId + "]"; 67 | } 68 | 69 | 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/config/MyRedisConfig.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.config; 2 | 3 | 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.context.annotation.Primary; 7 | import org.springframework.data.redis.cache.RedisCacheConfiguration; 8 | import org.springframework.data.redis.cache.RedisCacheManager; 9 | import org.springframework.data.redis.cache.RedisCacheWriter; 10 | import org.springframework.data.redis.connection.RedisConnectionFactory; 11 | import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; 12 | import org.springframework.data.redis.serializer.RedisSerializationContext; 13 | import org.springframework.data.redis.serializer.RedisSerializer; 14 | 15 | import java.time.Duration; 16 | 17 | @Configuration 18 | public class MyRedisConfig { 19 | 20 | 21 | //CacheManagerCustomizers可以来定制缓存的一些规则 22 | @Primary //将某个缓存管理器作为默认的 23 | @Bean 24 | public RedisCacheManager rManager(RedisConnectionFactory redisConnectionFactory) { 25 | //初始化一个RedisCacheWriter 26 | //设置CacheManager的值序列化方式为json序列化 27 | RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory); 28 | RedisSerializer jsonSerializer = new GenericJackson2JsonRedisSerializer(); 29 | RedisSerializationContext.SerializationPair pair = RedisSerializationContext.SerializationPair 30 | .fromSerializer(jsonSerializer); 31 | RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig() 32 | .serializeValuesWith(pair); 33 | //设置默认超过期时间是50秒 34 | defaultCacheConfig.entryTtl(Duration.ofSeconds(50)); 35 | //初始化RedisCacheManager 36 | return new RedisCacheManager(redisCacheWriter, defaultCacheConfig); 37 | } 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/listener/HelloSpringApplicationRunListener.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.listener; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.SpringApplicationRunListener; 5 | import org.springframework.context.ConfigurableApplicationContext; 6 | import org.springframework.core.env.ConfigurableEnvironment; 7 | 8 | public class HelloSpringApplicationRunListener implements SpringApplicationRunListener { 9 | 10 | //必须有的构造器 11 | public HelloSpringApplicationRunListener(SpringApplication application, String[] args){ 12 | 13 | } 14 | 15 | @Override 16 | public void starting() { 17 | System.out.println("SpringApplicationRunListener...starting..."); 18 | } 19 | 20 | @Override 21 | public void environmentPrepared(ConfigurableEnvironment environment) { 22 | Object o = environment.getSystemProperties().get("os.name"); 23 | System.out.println("SpringApplicationRunListener...environmentPrepared.."+o); 24 | } 25 | 26 | @Override 27 | public void contextPrepared(ConfigurableApplicationContext context) { 28 | System.out.println("SpringApplicationRunListener...contextPrepared..."); 29 | } 30 | 31 | @Override 32 | public void contextLoaded(ConfigurableApplicationContext context) { 33 | System.out.println("SpringApplicationRunListener...contextLoaded..."); 34 | } 35 | 36 | @Override 37 | public void started(ConfigurableApplicationContext context) { 38 | 39 | } 40 | 41 | @Override 42 | public void running(ConfigurableApplicationContext context) { 43 | 44 | } 45 | 46 | @Override 47 | public void failed(ConfigurableApplicationContext context, Throwable exception) { 48 | 49 | } 50 | 51 | /*@Override 52 | public void finished(ConfigurableApplicationContext context, Throwable exception) { 53 | System.out.println("SpringApplicationRunListener...finished..."); 54 | }*/ 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/com/zs/demo/cache/Springboot01CacheApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.cache; 2 | 3 | import com.zs.demo.bean.Employee; 4 | import com.zs.demo.dao.EmployeeDao; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.data.redis.core.RedisTemplate; 10 | import org.springframework.data.redis.core.StringRedisTemplate; 11 | import org.springframework.test.context.junit4.SpringRunner; 12 | 13 | @RunWith(SpringRunner.class) 14 | @SpringBootTest 15 | public class Springboot01CacheApplicationTests { 16 | @Autowired 17 | EmployeeDao employeeMapper; 18 | 19 | @Autowired 20 | StringRedisTemplate stringRedisTemplate; //操作k-v都是字符串的 21 | 22 | @Autowired 23 | RedisTemplate redisTemplate; //k-v都是对象的 24 | 25 | @Autowired 26 | RedisTemplate empRedisTemplate; 27 | 28 | 29 | /** 30 | * Redis常见的五大数据类型 31 | * String(字符串)、List(列表)、Set(集合)、Hash(散列)、ZSet(有序集合) 32 | * stringRedisTemplate.opsForValue()[String(字符串)] 33 | * stringRedisTemplate.opsForList()[List(列表)] 34 | * stringRedisTemplate.opsForSet()[Set(集合)] 35 | * stringRedisTemplate.opsForHash()[Hash(散列)] 36 | * stringRedisTemplate.opsForZSet()[ZSet(有序集合)] 37 | */ 38 | @Test 39 | public void test01() { 40 | //给redis中保存数据 41 | //stringRedisTemplate.opsForValue().append("msg","hello"); 42 | // String msg = stringRedisTemplate.opsForValue().get("msg"); 43 | // System.out.println(msg); 44 | 45 | // stringRedisTemplate.opsForList().leftPush("mylist","1"); 46 | // stringRedisTemplate.opsForList().leftPush("mylist","2"); 47 | } 48 | 49 | //测试保存对象 50 | @Test 51 | public void test02() { 52 | Employee empById = employeeMapper.getEmpById(1); 53 | //默认如果保存对象,使用jdk序列化机制,序列化后的数据保存到redis中 54 | //redisTemplate.opsForValue().set("emp-01",empById); 55 | //1、将数据以json的方式保存 56 | //(1)自己将对象转为json 57 | //(2)redisTemplate默认的序列化规则;改变默认的序列化规则; 58 | empRedisTemplate.opsForValue().set("emp-01", empById); 59 | } 60 | 61 | 62 | @Test 63 | public void contextLoads() { 64 | 65 | Employee empById = employeeMapper.getEmpById(1); 66 | System.out.println(empById); 67 | 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/test/java/com/zs/demo/DemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo; 2 | 3 | //import org.junit.jupiter.api.Test; 4 | 5 | import com.zs.demo.bean.Book; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.springframework.amqp.core.AmqpAdmin; 9 | import org.springframework.amqp.core.Binding; 10 | import org.springframework.amqp.core.DirectExchange; 11 | import org.springframework.amqp.core.Queue; 12 | import org.springframework.amqp.rabbit.core.RabbitTemplate; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.boot.test.context.SpringBootTest; 15 | import org.springframework.test.context.junit4.SpringRunner; 16 | 17 | import java.util.Arrays; 18 | import java.util.HashMap; 19 | import java.util.Map; 20 | 21 | @SpringBootTest 22 | @RunWith(SpringRunner.class) 23 | 24 | public class DemoApplicationTests { 25 | 26 | @Autowired 27 | RabbitTemplate rabbitTemplate; 28 | 29 | @Autowired 30 | AmqpAdmin amqpAdmin; 31 | 32 | @Test 33 | public void createExchange(){ 34 | 35 | amqpAdmin.declareExchange(new DirectExchange("amqpadmin.exchange")); 36 | System.out.println("创建完成"); 37 | 38 | amqpAdmin.declareQueue(new Queue("amqpadmin.queue",true)); 39 | //创建绑定规则 40 | 41 | amqpAdmin.declareBinding(new Binding("amqpadmin.queue", Binding.DestinationType.QUEUE,"amqpadmin.exchange","amqp.haha",null)); 42 | 43 | } 44 | 45 | /** 46 | * 1、单播(点对点) 47 | */ 48 | @Test 49 | public void contextLoads() { 50 | //Message需要自己构造一个;定义消息体内容和消息头 51 | //rabbitTemplate.send(exchage,routeKey,message); 52 | 53 | //object默认当成消息体,只需要传入要发送的对象,自动序列化发送给rabbitmq; 54 | //rabbitTemplate.convertAndSend(exchage,routeKey,object); 55 | Map map = new HashMap<>(); 56 | map.put("msg","这是第一个消息"); 57 | map.put("data", Arrays.asList("helloworld",123,true)); 58 | //对象被默认序列化以后发送出去 59 | rabbitTemplate.convertAndSend("exchange.direct","atguigu.news",new Book("西游记","吴承恩")); 60 | 61 | } 62 | 63 | //接受数据,如何将数据自动的转为json发送出去 64 | @Test 65 | public void receive(){ 66 | Object o = rabbitTemplate.receiveAndConvert("atguigu.news"); 67 | System.out.println(o.getClass()); 68 | System.out.println(o); 69 | } 70 | 71 | /** 72 | * 广播 73 | */ 74 | @Test 75 | public void sendMsg(){ 76 | rabbitTemplate.convertAndSend("exchange.fanout","",new Book("红楼梦","曹雪芹")); 77 | } 78 | 79 | } 80 | 81 | -------------------------------------------------------------------------------- /src/test/java/com/zs/demo/rabbit/DemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.rabbit; 2 | 3 | //import org.junit.jupiter.api.Test; 4 | 5 | import com.zs.demo.bean.Book; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.springframework.amqp.core.AmqpAdmin; 9 | import org.springframework.amqp.core.Binding; 10 | import org.springframework.amqp.core.DirectExchange; 11 | import org.springframework.amqp.core.Queue; 12 | import org.springframework.amqp.rabbit.core.RabbitTemplate; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.boot.test.context.SpringBootTest; 15 | import org.springframework.test.context.junit4.SpringRunner; 16 | 17 | import java.util.Arrays; 18 | import java.util.HashMap; 19 | import java.util.Map; 20 | 21 | @SpringBootTest 22 | @RunWith(SpringRunner.class) 23 | 24 | public class DemoApplicationTests { 25 | 26 | @Autowired 27 | RabbitTemplate rabbitTemplate; 28 | 29 | @Autowired 30 | AmqpAdmin amqpAdmin; 31 | 32 | @Test 33 | public void createExchange(){ 34 | 35 | amqpAdmin.declareExchange(new DirectExchange("amqpadmin.exchange")); 36 | System.out.println("创建完成"); 37 | 38 | amqpAdmin.declareQueue(new Queue("amqpadmin.queue",true)); 39 | //创建绑定规则 40 | amqpAdmin.declareBinding(new Binding("amqpadmin.queue", Binding.DestinationType.QUEUE,"amqpadmin.exchange","amqp.haha",null)); 41 | 42 | } 43 | 44 | /** 45 | * 1、单播(点对点) 46 | */ 47 | @Test 48 | public void contextLoads() { 49 | //Message需要自己构造一个;定义消息体内容和消息头 50 | //rabbitTemplate.send(exchage,routeKey,message); 51 | 52 | //object默认当成消息体,只需要传入要发送的对象,自动序列化发送给rabbitmq; 53 | //rabbitTemplate.convertAndSend(exchage,routeKey,object); 54 | Map map = new HashMap<>(); 55 | map.put("msg","这是第一个消息"); 56 | map.put("data", Arrays.asList("helloworld",123,true)); 57 | //对象被默认序列化以后发送出去 58 | rabbitTemplate.convertAndSend("exchange.direct","atguigu.news",new Book("动游记","吴承恩")); 59 | 60 | } 61 | 62 | //接受数据,如何将数据自动的转为json发送出去 63 | @Test 64 | public void receive(){ 65 | Object o = rabbitTemplate.receiveAndConvert("atguigu.news"); 66 | System.out.println(o.getClass()); 67 | System.out.println(o); 68 | } 69 | 70 | /** 71 | * 广播 72 | */ 73 | @Test 74 | public void sendMsg(){ 75 | rabbitTemplate.convertAndSend("exchange.fanout","",new Book("梦","曹雪芹")); 76 | } 77 | 78 | } 79 | 80 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/ag/hw/dp.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.ag.hw; 2 | 3 | 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | import java.util.Scanner; 7 | 8 | public class dp { 9 | public static void main(String[] args) { 10 | Scanner scanner = new Scanner(System.in); 11 | // 总钱数 12 | int N = scanner.nextInt(); 13 | // 购买物品个数 14 | int m = scanner.nextInt(); 15 | int[] f = new int[N + 1]; 16 | // 分组,goods[i][0]为主件,goods[i][1]为附件1,goods[i][2]为附件2 17 | Good[][] goods1 = new Good[60][4]; 18 | 19 | for (int i = 1; i <= m; i++) { 20 | int v = scanner.nextInt(); 21 | int p = scanner.nextInt(); 22 | int q = scanner.nextInt(); 23 | 24 | Good t = new Good(v, v * p); 25 | if (q == 0) { 26 | goods1[i][0] = t; 27 | } else { 28 | if (goods1[q][1] == null) { 29 | goods1[q][1] = t; 30 | } else { 31 | goods1[q][2] = t; 32 | } 33 | } 34 | } 35 | 36 | for (int i = 1; i <= m; i++) { 37 | for (int j = N; j >= 0 && goods1[i][0] != null; j--) { 38 | //以下代码从分组中选择价值最大的。共五种情况:不选主件,选主件,选附件1和主件,选附件2和主件,选附件1和附件2和主件 39 | Good master = goods1[i][0]; 40 | int max = f[j]; 41 | if (j >= master.v && max < f[j - master.v] + master.vp) { 42 | max = f[j - master.v] + master.vp; 43 | } 44 | int vt; 45 | if (goods1[i][1] != null) { 46 | if (j >= (vt = master.v + goods1[i][1].v) 47 | && max < f[j - vt] + master.vp + goods1[i][1].vp) { 48 | max = f[j - vt] + master.vp + goods1[i][1].vp; 49 | } 50 | } 51 | if (goods1[i][2] != null) { 52 | if (j >= (vt = master.v + goods1[i][1].v + goods1[i][2].v) 53 | && max < f[j - vt] + master.vp + goods1[i][1].vp + goods1[i][2].vp) { 54 | max = f[j - vt] + master.vp + goods1[i][1].vp + goods1[i][2].vp; 55 | } 56 | } 57 | f[j] = max; 58 | } 59 | } 60 | 61 | System.out.println(f[N]); 62 | } 63 | } 64 | 65 | class Good { 66 | int v; 67 | int vp; 68 | 69 | public Good(int v, int vp) { 70 | this.v = v; 71 | this.vp = vp; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/ag/hw/findWordCount.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.ag.hw; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | import java.util.Scanner; 7 | 8 | public class findWordCount { 9 | /** 10 | * 写出一个程序,接受一个由字母、数字和空格组成的字符串, 11 | * 和一个字母,然后输出输入字符串中该字母的出现次数。不区分大小写。 12 | */ 13 | /*public static void main(String[] args) throws IOException { 14 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 15 | String s1=br.readLine().toLowerCase(); 16 | char c=br.readLine().toLowerCase().charAt(0); 17 | char[] chars = s1.toCharArray(); 18 | int times =0; 19 | for (char ch : chars) { 20 | if (c==ch){ 21 | times++; 22 | } 23 | } 24 | System.out.println(times); 25 | }*/ 26 | public static void main(String[] args) { 27 | String a = "A000B0000"; 28 | 29 | System.out.println(removeZeros(a, 4)); 30 | /*Scanner scanner = new Scanner(System.in); 31 | String str = scanner.nextLine().toUpperCase(); 32 | char target = scanner.nextLine().toUpperCase().toCharArray()[0]; 33 | int n = getCount(str, target); 34 | System.out.println(n);*/ 35 | } 36 | 37 | private static int getCount(String str, char target) { 38 | // TODO Auto-generated method stub 39 | 40 | int count = 0; 41 | if (str != null && str.length() > 0) { 42 | for (int i = 0; i < str.length(); i++) { 43 | if (target == str.charAt(i)) {//遍历string里面的字符就可以找出来 44 | count++; 45 | } 46 | } 47 | } else { 48 | count = 0; 49 | } 50 | return count; 51 | } 52 | 53 | 54 | private static String removeZeros(String str, int k) { 55 | if (str == null || k < 1) { 56 | return str; 57 | } 58 | char[] chas = str.toCharArray(); 59 | int count = 0; 60 | int start = -1; 61 | for (int i = 0; i < chas.length; i++) { 62 | if (chas[i] == '0') { 63 | count++; 64 | start = start == -1 ? i : start; 65 | } else { 66 | count = 0; 67 | start = -1; 68 | 69 | } 70 | if (count == k) { 71 | while (count-- != 0) { 72 | chas[start++] = 0; 73 | } 74 | } 75 | 76 | } 77 | return String.valueOf(chas); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/test/java/com/zs/demo/elastic/Springboot03ElasticApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.elastic; 2 | 3 | 4 | import com.zs.demo.bean.Article; 5 | import com.zs.demo.bean.Desk; 6 | import com.zs.demo.repository.BookRepository; 7 | import io.searchbox.client.JestClient; 8 | import io.searchbox.core.Index; 9 | import io.searchbox.core.Search; 10 | import io.searchbox.core.SearchResult; 11 | import org.junit.Test; 12 | import org.junit.runner.RunWith; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.boot.test.context.SpringBootTest; 15 | import org.springframework.test.context.junit4.SpringRunner; 16 | 17 | import java.io.IOException; 18 | 19 | import java.io.IOException; 20 | 21 | @RunWith(SpringRunner.class) 22 | @SpringBootTest 23 | public class Springboot03ElasticApplicationTests { 24 | 25 | @Autowired 26 | JestClient jestClient; 27 | 28 | @Autowired 29 | BookRepository bookRepository; 30 | 31 | @Test 32 | public void test02(){ 33 | Desk book = new Desk(); 34 | book.setId(1); 35 | book.setBookName("西游记"); 36 | book.setAuthor("吴承恩"); 37 | bookRepository.index(book); 38 | 39 | 40 | for (Desk bk : bookRepository.findByBookNameLike("游")) { 41 | System.out.println(bk); 42 | } 43 | 44 | } 45 | 46 | 47 | 48 | 49 | // 访问地址 http://localhost:9200/atguigu/news/1 50 | // No bean named 'elasticsearchTemplate' available报这个的话就在配置文件中加elasticsearch的配置 51 | @Test 52 | public void contextLoads() { 53 | //1、给Es中索引(保存)一个文档; 54 | Article article = new Article(); 55 | article.setId(1); 56 | article.setTitle("好消息"); 57 | article.setAuthor("zhangsan"); 58 | article.setContent("Hello World"); 59 | 60 | //构建一个索引功能 61 | Index index = new Index.Builder(article).index("atguigu").type("news").build(); 62 | 63 | try { 64 | //执行 65 | jestClient.execute(index); 66 | } catch (IOException e) { 67 | e.printStackTrace(); 68 | } 69 | } 70 | 71 | //测试搜索 72 | @Test 73 | public void search(){ 74 | 75 | //查询表达式 76 | String json ="{\n" + 77 | " \"query\" : {\n" + 78 | " \"match\" : {\n" + 79 | " \"content\" : \"hello\"\n" + 80 | " }\n" + 81 | " }\n" + 82 | "}"; 83 | 84 | //更多操作:https://github.com/searchbox-io/Jest/tree/master/jest 85 | //构建搜索功能 86 | Search search = new Search.Builder(json).addIndex("atguigu").addType("news").build(); 87 | 88 | //执行 89 | try { 90 | SearchResult result = jestClient.execute(search); 91 | System.out.println(result.getJsonString()); 92 | } catch (IOException e) { 93 | e.printStackTrace(); 94 | } 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/DemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo; 2 | 3 | 4 | import org.springframework.amqp.rabbit.annotation.EnableRabbit; 5 | import org.springframework.amqp.rabbit.annotation.RabbitListener; 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | import org.springframework.cache.annotation.EnableCaching; 9 | import org.springframework.context.ConfigurableApplicationContext; 10 | import org.springframework.context.annotation.ComponentScan; 11 | 12 | /** 13 | * 自动配置 14 | * 1、RabbitAutoConfiguration 15 | * 2、有自动配置了连接工厂ConnectionFactory; 16 | * 3、RabbitProperties 封装了 RabbitMQ的配置 17 | * 4、 RabbitTemplate :给RabbitMQ发送和接受消息; 18 | * 5、 AmqpAdmin : RabbitMQ系统管理功能组件; 19 | * AmqpAdmin:创建和删除 Queue,Exchange,Binding 20 | * 6、@EnableRabbit + @RabbitListener 监听消息队列的内容 21 | */ 22 | 23 | /** 24 | * SpringBoot默认支持两种技术来和ES交互; 25 | * 1、Jest(默认不生效) 26 | * 需要导入jest的工具包(io.searchbox.client.JestClient) 27 | * 2、SpringData ElasticSearch【ES版本有可能不合适】 28 | * 版本适配说明:https://github.com/spring-projects/spring-data-elasticsearch 29 | * 如果版本不适配:2.4.6 30 | * 1)、升级SpringBoot版本 31 | * 2)、安装对应版本的ES 32 | * 33 | * 1)、Client 节点信息clusterNodes;clusterName 34 | * 2)、ElasticsearchTemplate 操作es 35 | * 3)、编写一个 ElasticsearchRepository 的子接口来操作ES; 36 | * 两种用法:https://github.com/spring-projects/spring-data-elasticsearch 37 | * 1)、编写一个 ElasticsearchRepository 38 | */ 39 | 40 | @EnableRabbit 41 | @SpringBootApplication 42 | @EnableCaching 43 | @ComponentScan(basePackages = "com.zs.demo.repository.BookRepository") 44 | public class DemoApplication { 45 | 46 | public static void main(String[] args) { 47 | 48 | SpringApplication.run(DemoApplication.class, args); 49 | 50 | } 51 | 52 | private static void m2(String[] args) { 53 | ConfigurableApplicationContext cx = SpringApplication.run(DemoApplication.class, args); 54 | String[] names = cx.getBeanDefinitionNames(); 55 | for (String name : names) { 56 | System.out.println(name); 57 | } 58 | //m1(); 59 | 60 | boolean user1 = cx.containsBean("user1"); 61 | 62 | System.out.println(user1); 63 | boolean pig1 = cx.containsBean("pig1"); 64 | System.out.println(pig1); 65 | 66 | boolean pig11 = cx.containsBean("pig11"); 67 | System.out.println(pig11); 68 | 69 | boolean user01 = cx.containsBean("user01"); 70 | System.out.println(user01); 71 | boolean user02 = cx.containsBean("user02"); 72 | System.out.println(user02); 73 | 74 | int i = cx.getBeanDefinitionCount(); 75 | System.out.println(i); 76 | } 77 | 78 | private static void m1() { 79 | /*Pig p = cx.getBean("pig1",Pig.class); 80 | Pig p2 = cx.getBean("pig1",Pig.class); 81 | System.out.println(p == p2); 82 | 83 | MyConfig m = cx.getBean(MyConfig.class); 84 | System.out.println(m); 85 | 86 | User ca = m.user1(); 87 | User ca1 = m.user1(); 88 | System.out.println(ca == ca1); 89 | 90 | User u1 = cx.getBean("user1",User.class); 91 | Pig p1 = cx.getBean("pig1",Pig.class); 92 | System.out.println(u1.getPig() == p1);*/ 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/ag/Test_SortNumberOthers.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.ag; 2 | 3 | import java.util.Scanner; 4 | 5 | /** 6 | * 继MIUI8推出手机分身功能之后,MIUI9计划推出一个电话号码分身的功能:首先将电话号码中的每个数字加上8取个位,然后使用对应的大写字母代替 ("ZERO", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE"), 然后随机打乱这些字母,所生成的字符串即为电话号码对应的分身。 7 | * 输入描述: 8 | * 第一行是一个整数T(1 ≤ T ≤ 100)表示测试样例数;接下来T行,每行给定一个分身后的电话号码的分身(长度在3到10000之间)。 9 | * 10 | * 11 | * 输出描述: 12 | * 输出T行,分别对应输入中每行字符串对应的分身前的最小电话号码(允许前导0) 13 | * 14 | * 15 | * 0 1 2 3 4 5 6 7 8 9 16 | * 8 8 8 8 8 8 8 8 8 8 17 | * 2 3 4 5 6 7 8 9 0 1 18 | * 0-->hash[2] 依次对应 19 | * 最后直接遍历数组就可以得到对应的分身 20 | */ 21 | 22 | 23 | public class Test_SortNumberOthers { 24 | public static void handle(String str){ 25 | str=str.toLowerCase(); 26 | int[] hash=new int[10]; 27 | StringBuffer sb=new StringBuffer(str); 28 | while(sb.toString().contains("z")){//zero 29 | //2 30 | hash[2]++; 31 | sb.deleteCharAt(sb.indexOf("z")); 32 | sb.deleteCharAt(sb.indexOf("e")); 33 | sb.deleteCharAt(sb.indexOf("r")); 34 | sb.deleteCharAt(sb.indexOf("o")); 35 | } 36 | while(sb.toString().contains("x")){//six 37 | hash[8]++; 38 | sb.deleteCharAt(sb.indexOf("s")); 39 | sb.deleteCharAt(sb.indexOf("i")); 40 | sb.deleteCharAt(sb.indexOf("x")); 41 | } 42 | while(sb.toString().contains("s")){//seven 43 | hash[9]++; 44 | sb.deleteCharAt(sb.indexOf("s")); 45 | sb.deleteCharAt(sb.indexOf("e")); 46 | sb.deleteCharAt(sb.indexOf("v")); 47 | sb.deleteCharAt(sb.indexOf("e")); 48 | sb.deleteCharAt(sb.indexOf("n")); 49 | } 50 | while(sb.toString().contains("u")){//four 51 | hash[6]++; 52 | sb.deleteCharAt(sb.indexOf("f")); 53 | sb.deleteCharAt(sb.indexOf("o")); 54 | sb.deleteCharAt(sb.indexOf("u")); 55 | sb.deleteCharAt(sb.indexOf("r")); 56 | } 57 | while(sb.toString().contains("f")){//five 58 | hash[7]++; 59 | sb.deleteCharAt(sb.indexOf("f")); 60 | sb.deleteCharAt(sb.indexOf("i")); 61 | sb.deleteCharAt(sb.indexOf("v")); 62 | sb.deleteCharAt(sb.indexOf("e")); 63 | } 64 | while(sb.toString().contains("g")){//eight 65 | hash[0]++; 66 | sb.deleteCharAt(sb.indexOf("e")); 67 | sb.deleteCharAt(sb.indexOf("i")); 68 | sb.deleteCharAt(sb.indexOf("g")); 69 | sb.deleteCharAt(sb.indexOf("h")); 70 | sb.deleteCharAt(sb.indexOf("t")); 71 | } 72 | while(sb.toString().contains("w")){//two 73 | hash[4]++; 74 | sb.deleteCharAt(sb.indexOf("t")); 75 | sb.deleteCharAt(sb.indexOf("w")); 76 | sb.deleteCharAt(sb.indexOf("o")); 77 | } 78 | while(sb.toString().contains("h")&&!sb.toString().contains("g")){//three 79 | hash[5]++; 80 | sb.deleteCharAt(sb.indexOf("t")); 81 | sb.deleteCharAt(sb.indexOf("h")); 82 | sb.deleteCharAt(sb.indexOf("r")); 83 | sb.deleteCharAt(sb.indexOf("e")); 84 | sb.deleteCharAt(sb.indexOf("e")); 85 | } 86 | while(sb.toString().contains("o")&&!sb.toString().contains("z")){//one 87 | hash[3]++; 88 | sb.deleteCharAt(sb.indexOf("o")); 89 | sb.deleteCharAt(sb.indexOf("n")); 90 | sb.deleteCharAt(sb.indexOf("e")); 91 | } 92 | while(sb.toString().contains("n")) {//nine 93 | hash[1]++; 94 | sb.deleteCharAt(sb.indexOf("n")); 95 | sb.deleteCharAt(sb.indexOf("i")); 96 | sb.deleteCharAt(sb.indexOf("n")); 97 | sb.deleteCharAt(sb.indexOf("e")); 98 | } 99 | for(int i=0;i<10;i++){ 100 | for(int j=1;j<=hash[i];j++){ 101 | System.out.print(i); 102 | } 103 | } 104 | System.out.println(); 105 | } 106 | public static void main(String[] args) { 107 | Scanner sc=new Scanner(System.in); 108 | while(sc.hasNextInt()){ 109 | int n=sc.nextInt(); 110 | for(int i=0;i 20 | *

21 | *

22 | * 原理: 23 | * 1、自动配置类;CacheAutoConfiguration 24 | * 2、缓存的配置类 25 | * org.springframework.boot.autoconfigure.cache.GenericCacheConfiguration 26 | * org.springframework.boot.autoconfigure.cache.JCacheCacheConfiguration 27 | * org.springframework.boot.autoconfigure.cache.EhCacheCacheConfiguration 28 | * org.springframework.boot.autoconfigure.cache.HazelcastCacheConfiguration 29 | * org.springframework.boot.autoconfigure.cache.InfinispanCacheConfiguration 30 | * org.springframework.boot.autoconfigure.cache.CouchbaseCacheConfiguration 31 | * org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration 32 | * org.springframework.boot.autoconfigure.cache.CaffeineCacheConfiguration 33 | * org.springframework.boot.autoconfigure.cache.GuavaCacheConfiguration 34 | * org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration【默认】 35 | * org.springframework.boot.autoconfigure.cache.NoOpCacheConfiguration 36 | * 3、哪个配置类默认生效:SimpleCacheConfiguration; 37 | *

38 | * 4、给容器中注册了一个CacheManager:ConcurrentMapCacheManager 39 | * 5、可以获取和创建ConcurrentMapCache类型的缓存组件;他的作用将数据保存在ConcurrentMap中; 40 | *

41 | * 运行流程: 42 | * 43 | * @param id 44 | * @return 45 | * @Cacheable: 1、方法运行之前,先去查询Cache(缓存组件),按照cacheNames指定的名字获取; 46 | * (CacheManager先获取相应的缓存),第一次获取缓存如果没有Cache组件会自动创建。 47 | * 2、去Cache中查找缓存的内容,使用一个key,默认就是方法的参数; 48 | * key是按照某种策略生成的;默认是使用keyGenerator生成的,默认使用SimpleKeyGenerator生成key; 49 | * SimpleKeyGenerator生成key的默认策略; 50 | * 如果没有参数;key=new SimpleKey(); 51 | * 如果有一个参数:key=参数的值 52 | * 如果有多个参数:key=new SimpleKey(params); 53 | * 3、没有查到缓存就调用目标方法; 54 | * 4、将目标方法返回的结果,放进缓存中 55 | * @Cacheable标注的方法执行之前先来检查缓存中有没有这个数据,默认按照参数的值作为key去查询缓存, 如果没有就运行方法并将结果放入缓存;以后再来调用就可以直接使用缓存中的数据; 56 | *

57 | * 核心: 58 | * 1)、使用CacheManager【ConcurrentMapCacheManager】按照名字得到Cache【ConcurrentMapCache】组件 59 | * 2)、key使用keyGenerator生成的,默认是SimpleKeyGenerator 60 | *

61 | *

62 | * 几个属性: 63 | * cacheNames/value:指定缓存组件的名字;将方法的返回结果放在哪个缓存中,是数组的方式,可以指定多个缓存; 64 | *

65 | * key:缓存数据使用的key;可以用它来指定。默认是使用方法参数的值 1-方法的返回值 66 | * 编写SpEL; #i d;参数id的值 #a0 #p0 #root.args[0] 67 | * getEmp[2] 68 | *

69 | * keyGenerator:key的生成器;可以自己指定key的生成器的组件id 70 | * key/keyGenerator:二选一使用; 71 | *

72 | *

73 | * cacheManager:指定缓存管理器;或者cacheResolver指定获取解析器 74 | *

75 | * condition:指定符合条件的情况下才缓存; 76 | * ,condition = "#id>0" 77 | * condition = "#a0>1":第一个参数的值》1的时候才进行缓存 78 | *

79 | * unless:否定缓存;当unless指定的条件为true,方法的返回值就不会被缓存;可以获取到结果进行判断 80 | * unless = "#result == null" 81 | * unless = "#a0==2":如果第一个参数的值是2,结果不缓存; 82 | * sync:是否使用异步模式 83 | */ 84 | @Cacheable(value = {"emp"}, keyGenerator = "myKeyGenerator", condition = "#id=1", unless = "#a0==2") 85 | //@Cacheable(value = {"emp"},cacheManager = "employeeCacheManager") 86 | public Employee getEmp(Integer id) { 87 | System.out.println("查询" + id + "号员工"); 88 | Employee emp = employeeMapper.getEmpById(id); 89 | return emp; 90 | } 91 | 92 | /** 93 | * @CachePut:既调用方法,又更新缓存数据;同步更新缓存 修改了数据库的某个数据,同时更新缓存; 94 | * 运行时机: 95 | * 1、先调用目标方法 96 | * 2、将目标方法的结果缓存起来 97 | *

98 | * 测试步骤: 99 | * 1、查询1号员工;查到的结果会放在缓存中; 100 | * key:1 value:lastName:张三 101 | * 2、以后查询还是之前的结果 102 | * 3、更新1号员工;【lastName:zhangsan;gender:0】 103 | * 将方法的返回值也放进缓存了; 104 | * key:传入的employee对象 值:返回的employee对象; 105 | * 4、查询1号员工? 106 | * 应该是更新后的员工; 107 | * key = "#employee.id":使用传入的参数的员工id; 108 | * key = "#result.id":使用返回后的id 109 | * @Cacheable的key是不能用#result 为什么是没更新前的?【1号员工没有在缓存中更新】 110 | */ 111 | //@CachePut(value = "emp",key = "#a0=2") 112 | //@CachePut(value = {"emp"}, keyGenerator = "myKeyGenerator", condition = "#id>0",unless = "#result == null") 113 | //@CachePut(value = {"emp"}, key="#employee.id") 114 | @CachePut(value = {"emp"}, keyGenerator = "myKeyGenerator") 115 | public Employee updateEmp(Employee employee) { 116 | System.out.println("updateEmp:" + employee); 117 | employeeMapper.updateEmp(employee); 118 | return employee; 119 | } 120 | 121 | /** 122 | * @CacheEvict:缓存清除 key:指定要清除的数据 123 | * allEntries = true:指定清除这个缓存中所有的数据 124 | * beforeInvocation = false:缓存的清除是否在方法之前执行 125 | * 默认代表缓存清除操作是在方法执行之后执行;如果出现异常缓存就不会清除 126 | *

127 | * beforeInvocation = true: 128 | * 代表清除缓存操作是在方法运行之前执行,无论方法是否出现异常,缓存都清除 129 | */ 130 | @CacheEvict(value="emp",beforeInvocation = false/*key = "#id",*/) 131 | public void deleteEmp(Integer id) { 132 | System.out.println("deleteEmp:" + id); 133 | employeeMapper.deleteEmpById(id); 134 | //int i = 10 / 0; 135 | } 136 | 137 | //@Caching 定义复杂的缓存规则 138 | @Caching( 139 | cacheable = { 140 | @Cacheable(value="emp",key = "#lastName") 141 | }, 142 | put = { 143 | @CachePut(value="emp",key = "#result.id"), 144 | @CachePut(value="emp",key = "#result.email") 145 | } 146 | ) 147 | public Employee getEmpByLastName(String lastName) { 148 | return employeeMapper.getEmpByLastName(lastName); 149 | } 150 | 151 | 152 | } 153 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.11.RELEASE 9 | 10 | 11 | com.zs 12 | demo 13 | 0.0.1-SNAPSHOT 14 | jar 15 | demo 16 | Demo project for Spring Boot 17 | 18 | 19 | UTF-8 20 | UTF-8 21 | 1.8 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | org.springframework.boot 32 | spring-boot-starter-web 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-cache 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter-test 41 | test 42 | 43 | 44 | org.mybatis.spring.boot 45 | mybatis-spring-boot-starter 46 | 1.3.1 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-starter-data-redis 51 | 52 | 53 | mysql 54 | mysql-connector-java 55 | runtime 56 | 57 | 58 | org.springframework.boot 59 | spring-boot-starter-test 60 | test 61 | 62 | 63 | org.springframework.boot 64 | spring-boot-starter-thymeleaf 65 | 66 | 67 | org.projectlombok 68 | lombok 69 | 1.18.8 70 | provided 71 | 72 | 73 | 74 | org.springframework.boot 75 | spring-boot-starter-amqp 76 | 77 | 78 | com.alibaba 79 | fastjson 80 | 1.2.70 81 | 82 | 83 | 84 | org.springframework.kafka 85 | spring-kafka 86 | 2.2.4.RELEASE 87 | 88 | 89 | 90 | 91 | org.springframework.boot 92 | spring-boot-starter-data-elasticsearch 93 | 94 | 95 | 96 | io.searchbox 97 | jest 98 | 5.3.3 99 | 100 | 101 | 120 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | org.springframework.boot 132 | spring-boot-maven-plugin 133 | 134 | 135 | 136 | 137 | 138 | src/main/resources 139 | true 140 | 141 | **/*.xlsx 142 | static/admin/**/* 143 | 144 | 145 | 146 | src/main/java 147 | false 148 | 149 | **/*.xml 150 | 151 | 152 | 153 | src/main/webapp 154 | false 155 | 156 | 157 | 158 | 159 | 160 | 161 | dev 162 | 163 | dev 164 | sit 165 | 166 | 167 | true 168 | 169 | 170 | 171 | sit 172 | 173 | sit 174 | sit 175 | 176 | 177 | 178 | 179 | 180 | 181 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Mingw, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | fi 118 | 119 | if [ -z "$JAVA_HOME" ]; then 120 | javaExecutable="`which javac`" 121 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 122 | # readlink(1) is not available as standard on Solaris 10. 123 | readLink=`which readlink` 124 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 125 | if $darwin ; then 126 | javaHome="`dirname \"$javaExecutable\"`" 127 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 128 | else 129 | javaExecutable="`readlink -f \"$javaExecutable\"`" 130 | fi 131 | javaHome="`dirname \"$javaExecutable\"`" 132 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 133 | JAVA_HOME="$javaHome" 134 | export JAVA_HOME 135 | fi 136 | fi 137 | fi 138 | 139 | if [ -z "$JAVACMD" ] ; then 140 | if [ -n "$JAVA_HOME" ] ; then 141 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 142 | # IBM's JDK on AIX uses strange locations for the executables 143 | JAVACMD="$JAVA_HOME/jre/sh/java" 144 | else 145 | JAVACMD="$JAVA_HOME/bin/java" 146 | fi 147 | else 148 | JAVACMD="`which java`" 149 | fi 150 | fi 151 | 152 | if [ ! -x "$JAVACMD" ] ; then 153 | echo "Error: JAVA_HOME is not defined correctly." >&2 154 | echo " We cannot execute $JAVACMD" >&2 155 | exit 1 156 | fi 157 | 158 | if [ -z "$JAVA_HOME" ] ; then 159 | echo "Warning: JAVA_HOME environment variable is not set." 160 | fi 161 | 162 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 163 | 164 | # traverses directory structure from process work directory to filesystem root 165 | # first directory with .mvn subdirectory is considered project base directory 166 | find_maven_basedir() { 167 | 168 | if [ -z "$1" ] 169 | then 170 | echo "Path not specified to find_maven_basedir" 171 | return 1 172 | fi 173 | 174 | basedir="$1" 175 | wdir="$1" 176 | while [ "$wdir" != '/' ] ; do 177 | if [ -d "$wdir"/.mvn ] ; then 178 | basedir=$wdir 179 | break 180 | fi 181 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 182 | if [ -d "${wdir}" ]; then 183 | wdir=`cd "$wdir/.."; pwd` 184 | fi 185 | # end of workaround 186 | done 187 | echo "${basedir}" 188 | } 189 | 190 | # concatenates all lines of a file 191 | concat_lines() { 192 | if [ -f "$1" ]; then 193 | echo "$(tr -s '\n' ' ' < "$1")" 194 | fi 195 | } 196 | 197 | BASE_DIR=`find_maven_basedir "$(pwd)"` 198 | if [ -z "$BASE_DIR" ]; then 199 | exit 1; 200 | fi 201 | 202 | ########################################################################################## 203 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 204 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 205 | ########################################################################################## 206 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 207 | if [ "$MVNW_VERBOSE" = true ]; then 208 | echo "Found .mvn/wrapper/maven-wrapper.jar" 209 | fi 210 | else 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 213 | fi 214 | if [ -n "$MVNW_REPOURL" ]; then 215 | jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 216 | else 217 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 218 | fi 219 | while IFS="=" read key value; do 220 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 221 | esac 222 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 223 | if [ "$MVNW_VERBOSE" = true ]; then 224 | echo "Downloading from: $jarUrl" 225 | fi 226 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 227 | if $cygwin; then 228 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 229 | fi 230 | 231 | if command -v wget > /dev/null; then 232 | if [ "$MVNW_VERBOSE" = true ]; then 233 | echo "Found wget ... using wget" 234 | fi 235 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 236 | wget "$jarUrl" -O "$wrapperJarPath" 237 | else 238 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" 239 | fi 240 | elif command -v curl > /dev/null; then 241 | if [ "$MVNW_VERBOSE" = true ]; then 242 | echo "Found curl ... using curl" 243 | fi 244 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 245 | curl -o "$wrapperJarPath" "$jarUrl" -f 246 | else 247 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 248 | fi 249 | 250 | else 251 | if [ "$MVNW_VERBOSE" = true ]; then 252 | echo "Falling back to using Java to download" 253 | fi 254 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 255 | # For Cygwin, switch paths to Windows format before running javac 256 | if $cygwin; then 257 | javaClass=`cygpath --path --windows "$javaClass"` 258 | fi 259 | if [ -e "$javaClass" ]; then 260 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 261 | if [ "$MVNW_VERBOSE" = true ]; then 262 | echo " - Compiling MavenWrapperDownloader.java ..." 263 | fi 264 | # Compiling the Java class 265 | ("$JAVA_HOME/bin/javac" "$javaClass") 266 | fi 267 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 268 | # Running the downloader 269 | if [ "$MVNW_VERBOSE" = true ]; then 270 | echo " - Running MavenWrapperDownloader.java ..." 271 | fi 272 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 273 | fi 274 | fi 275 | fi 276 | fi 277 | ########################################################################################## 278 | # End of extension 279 | ########################################################################################## 280 | 281 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 282 | if [ "$MVNW_VERBOSE" = true ]; then 283 | echo $MAVEN_PROJECTBASEDIR 284 | fi 285 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 286 | 287 | # For Cygwin, switch paths to Windows format before running java 288 | if $cygwin; then 289 | [ -n "$M2_HOME" ] && 290 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 291 | [ -n "$JAVA_HOME" ] && 292 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 293 | [ -n "$CLASSPATH" ] && 294 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 295 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 296 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 297 | fi 298 | 299 | # Provide a "standardized" way to retrieve the CLI args that will 300 | # work with both Windows and non-Windows executions. 301 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 302 | export MAVEN_CMD_LINE_ARGS 303 | 304 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 305 | 306 | exec "$JAVACMD" \ 307 | $MAVEN_OPTS \ 308 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 309 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 310 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 311 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/ie/ie.md: -------------------------------------------------------------------------------- 1 | 1.kafka为啥会这么快 2 | 3 | 写:为了提高读写硬盘的速度,Kafka就是使用顺序I/O 4 | 磁盘顺序读写速度超过内存随机读写 5 | JVM的GC效率低,内存占用大。使用磁盘可以避免这一问题 6 | 系统冷启动后,磁盘缓存依然可用 7 | 8 | 读:sendfile系统调用,文件数据被copy至内核缓冲区 9 | 再从内核缓冲区copy至内核中socket相关的缓冲区 10 | 最后再socket相关的缓冲区copy到协议引擎 11 | 12 | 2.Spring 框架中用到了哪些设计模式: 13 | 14 | 工厂设计模式 : Spring使用工厂模式通过 BeanFactory、ApplicationContext 创建 bean 对象。 15 | 代理设计模式 : Spring AOP 功能的实现。 16 | 单例设计模式 : Spring 中的 Bean 默认都是单例的。 17 | 模板方法模式 : Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。 18 | 包装器设计模式 : 我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。 19 | 观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个应用。 20 | 适配器模式 :Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配 21 | 22 | 3.单例: 23 | 24 | 1. 饿汉模式 25 | public class Singleton { 26 | private static Singleton instance = new Singleton(); 27 | private Singleton (){ 28 | } 29 | public static Singleton getInstance() { 30 | return instance; 31 | } 32 | } 33 | 34 | 这种方式在类加载时就完成了初始化,所以类加载较慢,但获取对象的速度快。 这种方式基于类加载机制避免了多线程的同步问题,但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化instance显然没有达到懒加载的效果。 35 | 36 | 2. 懒汉模式(线程不安全) 37 | public class Singleton { 38 | private static Singleton instance; 39 | private Singleton (){ 40 | } 41 | public static Singleton getInstance() { 42 | if (instance == null) { 43 | instance = new Singleton(); 44 | } 45 | return instance; 46 | } 47 | } 48 | 49 | 50 | 懒汉模式申明了一个静态对象,在用户第一次调用时初始化,虽然节约了资源,但第一次加载时需要实例化,反映稍慢一些,而且在多线程不能正常工作。 51 | 52 | 3. 懒汉模式(线程安全) 53 | 54 | public class Singleton { 55 | private static Singleton instance; 56 | private Singleton (){ 57 | } 58 | public static synchronized Singleton getInstance() { 59 | if (instance == null) { 60 | instance = new Singleton(); 61 | } 62 | return instance; 63 | } 64 | } 65 | 66 | 67 | 这种写法能够在多线程中很好的工作,但是每次调用getInstance方法时都需要进行同步,造成不必要的同步开销,而且大部分时候我们是用不到同步的,所以不建议用这种模式。 68 | 69 | 4. 双重检查模式 (DCL) 70 | 71 | public class Singleton { 72 | private volatile static Singleton singleton; 73 | private Singleton (){ 74 | } 75 | public static Singleton getInstance() { 76 | if (instance== null) { 77 | synchronized (Singleton.class) { 78 | if (instance== null) { 79 | instance= new Singleton(); 80 | } 81 | } 82 | } 83 | return singleton; 84 | } 85 | } 86 | 87 | 88 | 这种写法在getSingleton方法中对singleton进行了两次判空,第一次是为了不必要的同步,第二次是在singleton等于null的情况下才创建实例。在这里用到了volatile关键字,不了解volatile关键字的可以查看Java多线程(三)volatile域这篇文章,在这篇文章我也提到了双重检查模式是正确使用volatile关键字的场景之一。 89 | 在这里使用volatile会或多或少的影响性能,但考虑到程序的正确性,牺牲这点性能还是值得的。 DCL优点是资源利用率高,第一次执行getInstance时单例对象才被实例化,效率高。缺点是第一次加载时反应稍慢一些,在高并发环境下也有一定的缺陷,虽然发生的概率很小。DCL虽然在一定程度解决了资源的消耗和多余的同步,线程安全等问题,但是他还是在某些情况会出现失效的问题,也就是DCL失效,在《Java并发编程实践》一书建议用静态内部类单例模式来替代DCL。 90 | 91 | 5. 静态内部类单例模式 92 | 93 | public class Singleton { 94 | private Singleton(){ 95 | } 96 | public static Singleton getInstance(){ 97 | return SingletonHolder.sInstance; 98 | } 99 | private static class SingletonHolder { 100 | private static final Singleton sInstance = new Singleton(); 101 | } 102 | } 103 | 第一次加载Singleton类时并不会初始化sInstance,只有第一次调用getInstance方法时虚拟机加载SingletonHolder 并初始化sInstance ,这样不仅能确保线程安全也能保证Singleton类的唯一性,所以推荐使用静态内部类单例模式。 104 | 105 | 6. 枚举单例 106 | 107 | public enum Singleton { 108 | INSTANCE; 109 | public void doSomeThing() { 110 | } 111 | } 112 | 113 | 114 | 默认枚举实例的创建是线程安全的,并且在任何情况下都是单例,上述讲的几种单例模式实现中,有一种情况下他们会重新创建对象,那就是反序列化,将一个单例实例对象写到磁盘再读回来,从而获得了一个实例。反序列化操作提供了readResolve方法,这个方法可以让开发人员控制对象的反序列化。在上述的几个方法示例中如果要杜绝单例对象被反序列化是重新生成对象,就必须加入如下方法: 115 | 116 | private Object readResolve() throws ObjectStreamException{ 117 | return singleton; 118 | } 119 | 枚举单例的优点就是简单,但是大部分应用开发很少用枚举,可读性并不是很高,不建议用。 120 | 121 | 7. 使用容器实现单例模式 122 | 123 | public class SingletonManager { 124 |   private static Map objMap = new HashMap(); 125 |   private Singleton() { 126 |   } 127 |   public static void registerService(String key, Objectinstance) { 128 |     if (!objMap.containsKey(key) ) { 129 |       objMap.put(key, instance) ; 130 |     } 131 |   } 132 |   public static ObjectgetService(String key) { 133 |     return objMap.get(key) ; 134 |   } 135 | } 136 | 用SingletonManager 将多种的单例类统一管理,在使用时根据key获取对象对应类型的对象。这种方式使得我们可以管理多种类型的单例,并且在使用时可以通过统一的接口进行获取操作,降低了用户的使用成本,也对用户隐藏了具体实现,降低了耦合度。 137 | 138 | 总结 139 | 到这里七中写法都介绍完了,至于选择用哪种形式的单例模式,取决于你的项目本身,是否是有复杂的并发环境,还是需要控制单例对象的资源消耗。 140 | 141 | 4.静态代理类与动态代理 142 | 143 | 1.静态代理类: 144 | 由程序员创建或由特定工具自动生成源代码,再bai对其编译。在程序运行前,代理类的.class文件就已经存在了。动态代理类:在程序运行时,运用反射机制动态创建而成 145 | 2.动态代理类 146 | 与静态代理类对照的是动态代理类,动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。 147 | 148 | 5.zk实现分布式锁: 149 | 150 | 6.同步异步 阻塞 非阻塞区别 151 | BIO:同步阻塞;一个线程对应一个socket 152 | NIO:同步非阻塞:有个selector(选择器:多路复用,监听多个通道):一个线程有多个socket; 153 | AIO;异步非阻塞:异步通道: 154 | 异步不会阻塞 155 | B阻塞:当前线程暂时没有数据可读的时候、accept或者是read的时候。 156 | N阻塞:thread-->channel-->buffer-->socket. thread不会阻塞 157 | -->channel-->buffer-->socket. 158 | buffer(内存块):读写都可以用flip切换,双向的,除了boolean类型都有。 159 | channel是双向的 160 | selector对应一个线程,会根据不同的事件,切换不同的通道,一个线程对应多个channel, 161 | 每个channel对应一个buffer. 162 | selector:能够检测多个注册的通道是否有事件发生。单线程,多路复用,调用select方法,select方法可以获取到注册上去的selectionkey,遍历selectionkey获取到channel。 163 | selector.select().//阻塞; 164 | 当客户端连接时,会通过ServerSocketChannel 得到 SocketChannel 165 | 将socketChannel注册到Selector上, register(Selector sel, int ops), 一个selector上可以注册多个SocketChannel 166 | 注册后返回一个 SelectionKey, 会和该Selector 关联(集合) 167 | Selector 进行监听 select 方法, 返回有事件发生的通道的个数. 168 | 进一步得到各个 SelectionKey (有事件发生) 169 | 在通过 SelectionKey 反向获取 SocketChannel , 方法 channel() 170 | 可以通过 得到的 channel , 完成业务处理 171 | 代码撑腰。。。 172 | 173 | 174 | 7.单Reactor 单线程/单 Reactor 多线程/主从 Reactor 多线程 175 | Netty 线程模式(Netty 主要基于主从 Reactor 多线程模型做了一定的改进,其中主从 Reactor 多线程模型有多个 Reactor) 176 | I/O 复用结合线程池,就是 Reactor 模式基本设计思想, 177 | Reactor 模式,通过一个或多个输入同时传递给服务处理器的模式(基于事件驱动) 178 | 服务器端程序处理传入的多个请求,并将它们同步分派到相应的处理线程, 因此Reactor模式也叫 Dispatcher模式 179 | Reactor 模式使用IO复用监听事件, 收到事件后,分发给某个线程(进程), 这点就是网络服务器高并发处理关键 180 | 181 | 传统IO流: 182 | 采用阻塞IO模式获取输入的数据 183 | 每个连接都需要独立的线程完成数据的输入,业务处理, 数据返回 184 | 问题分析 185 | 当并发数很大,就会创建大量的线程,占用很大系统资源 186 | 连接创建后,如果当前线程暂时没有数据可读,该线程会阻塞在read 操作,造成线程资源浪费 187 | 解决(Reactor:I/O 复用结合线程池): 188 | 基于I/O复用模型:多个连接共用一个阻塞对象,应用程序只需要在一个阻塞对象等待,无需阻塞等待所有连接。当某个连接有新的数据可以处理时,操作系统通知应用程序,线程从阻塞状态返回,开始进行业务处理 Reactor 对应的叫法: 1. 反应器模式 2. 分发者模式(Dispatcher) 3. 通知者模式(notifier) 189 | (Dispatcher转发)传统的Io没有dispatcher没有转发 190 | 基于线程池复用线程资源:不必再为每个连接创建线程,将连接完成后的业务处理任务分配给线程进行处理,一个线程可以处理多个连接的业务。 191 | (线程重复利用) 192 | 单Reactor 单线程: 193 | 方案说明: 194 | Select 是前面 I/O 复用模型介绍的标准网络编程 API,可以实现应用程序通过一个阻塞对象监听多路连接请求 195 | Reactor 对象通过 Select 监控客户端请求事件,收到事件后通过 Dispatch 进行分发 196 | 如果是建立连接请求事件,则由 Acceptor 通过 Accept 处理连接请求,然后创建一个 Handler 对象处理连接完成后的后续业务处理 197 | 如果不是建立连接事件,则 Reactor 会分发调用连接对应的 Handler 来响应 198 | Handler 会完成 Read→业务处理→Send 的完整业务流程 199 | 方案优缺点分析: 200 | 优点:模型简单,没有多线程、进程通信、竞争的问题,全部都在一个线程中完成 201 | 缺点:性能问题,只有一个线程,无法完全发挥多核 CPU 的性能。Handler 在处理某个连接上的业务时,整个进程无法处理其他连接事件,很容易导致性能瓶颈 202 | 缺点:可靠性问题,线程意外终止,或者进入死循环,会导致整个系统通信模块不可用,不能接收和处理外部消息,造成节点故障 203 | 使用场景:客户端的数量有限,业务处理非常快速,比如 Redis在业务处理的时间复杂度 O(1) 的情况 204 | 单Reactor多线程: 205 | 方案说明 206 | Reactor 对象通过select 监控客户端请求 事件, 收到事件后,通过dispatch进行分发 207 | 如果建立连接请求, 则右Acceptor 通过 accept 处理连接请求, 然后创建一个Handler对象处理完成连接后的各种事件 208 | 如果不是连接请求,则由reactor分发调用连接对应的handler 来处理 209 | handler 只负责响应事件,不做具体的业务处理, 通过read 读取数据后,会分发给后面的worker线程池的某个线程处理业务 210 | worker 线程池会分配独立线程完成真正的业务,并将结果返回给handler 211 | handler收到响应后,通过send 将结果返回给client 212 | 方案优缺点分析: 213 | 优点:可以充分的利用多核cpu 的处理能力 214 | 缺点:多线程数据共享和访问比较复杂, reactor 处理所有的事件的监听和响应,在单线程运行, 在高并发场景容易出现性能瓶颈. 215 | 主从 Reactor 多线程: 216 | 方案说明 217 | Reactor主线程 MainReactor 对象通过select 监听连接事件, 收到事件后,通过Acceptor 处理连接事件 218 | 当 Acceptor 处理连接事件后,MainReactor 将连接分配给SubReactor 219 | subreactor 将连接加入到连接队列进行监听,并创建handler进行各种事件处理 220 | 当有新事件发生时, subreactor 就会调用对应的handler处理 221 | handler 通过read 读取数据,分发给后面的worker 线程处理 222 | worker 线程池分配独立的worker 线程进行业务处理,并返回结果 223 | handler 收到响应的结果后,再通过send 将结果返回给client 224 | Reactor 主线程可以对应多个Reactor 子线程, 即MainRecator 可以关联多个SubReactor 225 | 方案优缺点说明: 226 | 优点:父线程与子线程的数据交互简单职责明确,父线程只需要接收新连接,子线程完成后续的业务处理。 227 | 优点:父线程与子线程的数据交互简单,Reactor 主线程只需要把新连接传给子线程,子线程无需返回数据。 228 | 缺点:编程复杂度较高 229 | 结合实例:这种模型在许多项目中广泛使用,包括 Nginx 主从 Reactor 多进程模型,Memcached 主从多线程,Netty 主从多线程模型的支持 230 | 3 种模式用生活案例来理解 231 | 单 Reactor 单线程,前台接待员和服务员是同一个人,全程为顾客服 232 | 单 Reactor 多线程,1 个前台接待员,多个服务员,接待员只负责接待 233 | 主从 Reactor 多线程,多个前台接待员,多个服务生 234 | 235 | netty(精简版): 236 | BossGroup 线程维护Selector , 只关注Accecpt 237 | 当接收到Accept事件,获取到对应的SocketChannel, 封装成 NIOScoketChannel并注册到Worker 线程(事件循环), 并进行维护 238 | 当Worker线程监听到selector 中通道发生自己感兴趣的事件后,就进行处理(就由handler), 注意handler 已经加入到通道 239 | netty(详细版): 240 | Netty抽象出两组线程池 BossGroup 专门负责接收客户端的连接, WorkerGroup 专门负责网络的读写 241 | BossGroup 和 WorkerGroup 类型都是 NioEventLoopGroup 242 | NioEventLoopGroup 相当于一个事件循环组, 这个组中含有多个事件循环 ,每一个事件循环是 NioEventLoop 243 | NioEventLoop 表示一个不断循环的执行处理任务的线程, 每个NioEventLoop 都有一个selector , 用于监听绑定在其上的socket的网络通讯 244 | NioEventLoopGroup 可以有多个线程, 即可以含有多个NioEventLoop 245 | 每个Boss NioEventLoop 循环执行的步骤有3步 246 | 轮询accept 事件 247 | 处理accept 事件 , 与client建立连接 , 生成NioScocketChannel , 并将其注册到某个worker NIOEventLoop 上的 selector 248 | 处理任务队列的任务 , 即 runAllTasks 249 | 7) 每个 Worker NIOEventLoop 循环执行的步骤 250 | 轮询read, write 事件 251 | 处理i/o事件, 即read , write 事件,在对应NioScocketChannel 处理 252 | 处理任务队列的任务 , 即 runAllTasks 253 | 8) 每个Worker NIOEventLoop 处理业务时,会使用pipeline(管道), pipeline 中包含了 channel , 即通过pipeline 可以获取到对应通道, 管道中维护了很多的 处理器 254 | 255 | Future 说明 256 | 表示异步的执行结果, 可以通过它提供的方法来检测执行是否完成,比如检索计算等等. 257 | ChannelFuture 是一个接口 : public interface ChannelFuture extends Future 我们可以添加监听器,当监听的事件发生时,就会通知到监听器. 案例说明 258 | Netty 框架的目标就是让你的业务逻辑从网络基础应用编码中分离出来、解脱出来 259 | Netty 中所有的 IO 操作都是异步的,不能立刻得知消息是否被正确处理。但是可以过一会等它执行完成或者直接注册一个监听,具体的实现就是通过 Future 和 ChannelFutures,他们可以注册一个监听,当操作执行成功或失败时监听会自动触发注册的监听事件 260 | 261 | 在使用 Netty 进行编程时,拦截操作和转换出入站数据只需要您提供 callback 或利用future 即可。这使得链式操作简单、高效, 并有利于编写可重用的、通用的代码。 262 | public ServerBootstrap childHandler(ChannelHandler childHandler),该方法用来设置业务处理类(自定义的 handler) 263 | childHandle和Handle的区别:Handle给的是Boss自定义的,childHandle是给Work用的。 264 | netty核心组件: 265 | 1.Bootstrap、ServerBootstrap 266 | Bootstrap 意思是引导,一个 Netty 应用通常由一个 Bootstrap 开始,主要作用是配置整个 Netty 程序,串联各个组件,Netty 中 Bootstrap 类是客户端程序的启动引导类,ServerBootstrap 是服务端启动引导类 267 | 2.Future、ChannelFuture 268 | Netty 中所有的 IO 操作都是异步的,不能立刻得知消息是否被正确处理。但是可以过一会等它执行完成或者直接注册一个监听,具体的实现就是通过 Future 和 ChannelFutures,他们可以注册一个监听,当操作执行成功或失败时监听会自动触发注册的监听事件 269 | 3.Channel 270 | Netty 网络通信的组件,能够用于执行网络 I/O 操作。 271 | 通过Channel 可获得当前网络连接的通道的状态 272 | 通过Channel 可获得 网络连接的配置参数 (例如接收缓冲区大小) 273 | Channel 提供异步的网络 I/O 操作(如建立连接,读写,绑定端口),异步调用意味着任何 I/O 调用都将立即返回,并且不保证在调用结束时所请求的 I/O 操作已完成 274 | 调用立即返回一个 ChannelFuture 实例,通过注册监听器到 ChannelFuture 上,可以 I/O 操作成功、失败或取消时回调通知调用方 275 | 支持关联 I/O 操作与对应的处理程序 276 | 不同协议、不同的阻塞类型的连接都有不同的 Channel 类型与之对应,常用的 Channel 类型: 277 | 278 | 4.Selector 279 | Netty 基于 Selector 对象实现 I/O 多路复用,通过 Selector 一个线程可以监听多个连接的 Channel 事件。 280 | 当向一个 Selector 中注册 Channel 后,Selector 内部的机制就可以自动不断地查询(Select) 这些注册的 Channel 是否有已就绪的 I/O 事件(例如可读,可写,网络连接完成等),这样程序就可以很简单地使用一个线程高效地管理多个 Channel 281 | 5.ChannelHandler 及其实现类 282 | ChannelHandler 是一个接口,处理 I/O 事件或拦截 I/O 操作,并将其转发到其 ChannelPipeline(业务处理链)中的下一个处理程序。 283 | ChannelHandler 本身并没有提供很多方法,因为这个接口有许多的方法需要实现,方便使用期间,可以继承它的子类 284 | ChannelHandler 及其实现类一览图(后) 285 | 我们经常需要自定义一个 Handler 类去继承 ChannelInboundHandlerAdapter,然后通过重写相应方法实现业务逻辑,我们接下来看看一般都需要重写哪些方法 286 | 287 | 6.Pipeline 和 ChannelPipeline 288 | ChannelPipeline 是一个 Handler 的集合,它负责处理和拦截 inbound 或者 outbound 的事件和操作,相当于一个贯穿 Netty 的链。(也可以这样理解:ChannelPipeline 是 保存 ChannelHandler 的 List,用于处理或拦截 Channel 的入站事件和出站操作) 289 | ChannelPipeline 实现了一种高级形式的拦截过滤器模式,使用户可以完全控制事件的处理方式,以及 Channel 中各个的 ChannelHandler 如何相互交互 290 | 在 Netty 中每个 Channel 都有且仅有一个 ChannelPipeline 与之对应,它们的组成关系如下 291 | 一个 Channel 包含了一个 ChannelPipeline,而 ChannelPipeline 中又维护了一个由 ChannelHandlerContext 组成的双向链表,并且每个 ChannelHandlerContext 中又关联着一个 ChannelHandler 292 | 入站事件和出站事件在一个双向链表中,入站事件会从链表 head 往后传递到最后一个入站的 handler,出站事件会从链表 tail 往前传递到最前一个出站的 handler,两种类型的 handler 互不干扰 293 | 7.ChannelHandlerContext 294 | 保存 Channel 相关的所有上下文信息,同时关联一个 ChannelHandler 对象 295 | 即ChannelHandlerContext 中 包 含 一 个 具 体 的 事 件 处 理 器 ChannelHandler , 同 时ChannelHandlerContext 中也绑定了对应的 pipeline 和 Channel 的信息,方便对 ChannelHandler进行调用. 296 | 8.ChannelOption 297 | Netty 在创建 Channel 实例后,一般都需要设置 ChannelOption 参数。 298 | ChannelOption 参数如下: 299 | 9.EventLoopGroup 和其实现类 NioEventLoopGroup 300 | EventLoopGroup 是一组 EventLoop 的抽象,Netty 为了更好的利用多核 CPU 资源,一般会有多个 EventLoop 同时工作,每个 EventLoop 维护着一个 Selector 实例。 301 | EventLoopGroup 提供 next 接口,可以从组里面按照一定规则获取其中一个 EventLoop来处理任务。在 Netty 服务器端编程中,我们一般都需要提供两个 EventLoopGroup,例如:BossEventLoopGroup 和 WorkerEventLoopGroup。 302 | 通常一个服务端口即一个 ServerSocketChannel对应一个Selector 和一个EventLoop线程。BossEventLoop 负责接收客户端的连接并将 SocketChannel 交给 WorkerEventLoopGroup 来进行 IO 处理,如下图所示 303 | 10.Unpooled 类 304 | Netty 提供一个专门用来操作缓冲区(即Netty的数据容器)的工具类 305 | 306 | 实例要求: 307 | Http协议是无状态的, 浏览器和服务器间的请求响应一次,下一次会重新创建连接. 308 | 309 | 要求:实现基于webSocket的长连接的全双工的交互 310 | 改变Http协议多次请求的约束,实现长连接了, 服务器可以发送消息给浏览器 311 | 客户端浏览器和服务器端会相互感知,比如服务器关闭了,浏览器会感知,同样浏览器关闭了,服务器会感知 312 | 313 | 编码和解码的基本介绍 314 | 编写网络应用程序时,因为数据在网络中传输的都是二进制字节码数据,在发送数据时就需要编码,接收数据时就需要解码 [示意图] 315 | 316 | codec(编解码器) 的组成部分有两个:decoder(解码器)和 encoder(编码器)。encoder 负责把业务数据转换成字节码数据,decoder 负责把字节码数据转换成业务数据 317 | 318 | Netty 自身提供了一些 codec(编解码器) 319 | Netty 提供的编码器 320 | StringEncoder,对字符串数据进行编码 321 | ObjectEncoder,对 Java 对象进行编码 322 | ... 323 | Netty 提供的解码器 324 | StringDecoder, 对字符串数据进行解码 325 | ObjectDecoder,对 Java 对象进行解码 326 | ... 327 | Netty 本身自带的 ObjectDecoder 和 ObjectEncoder 可以用来实现 POJO 对象或各种业务对象的编码和解码,底层使用的仍是 Java 序列化技术 , 而Java 序列化技术本身效率就不高,存在如下问题 328 | 无法跨语言 329 | 序列化后的体积太大,是二进制编码的 5 倍多。 330 | 序列化性能太低 331 | => 引出 新的解决方案 [Google 的 Protobuf] 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | -------------------------------------------------------------------------------- /src/main/java/com/zs/demo/ag/hw/lastWordLength.java: -------------------------------------------------------------------------------- 1 | package com.zs.demo.ag.hw; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | import java.util.*; 7 | 8 | public class lastWordLength { 9 | 10 | private static int numSum(String str) { 11 | if (str == null) { 12 | return 0; 13 | } 14 | 15 | char[] charArray = str.toCharArray(); 16 | int res = 0; 17 | int num = 0; 18 | boolean posi = true; 19 | int cur = 0; 20 | for (int i = 0; i < charArray.length; i++) { 21 | cur = charArray[i] - '0'; 22 | if (cur < 0 || cur > 9) { 23 | res += num; 24 | num = 0; 25 | if (charArray[i] == '-') { 26 | if (i - 1 > -1 && charArray[i - 1] == '-') { 27 | posi = !posi; 28 | } else { 29 | posi = false; 30 | } 31 | } else { 32 | posi = true; 33 | } 34 | } else { 35 | num = num * 10 + (posi ? cur : -cur); 36 | } 37 | } 38 | 39 | res += num; 40 | return res; 41 | } 42 | 43 | 44 | 45 | public static void main(String[] args) throws Exception { 46 | 47 | System.out.println(numSum("A-1B--200")); 48 | //judgeIp(); 49 | //sub(); 50 | //togetherOne(); 51 | //leftAndRight(); 52 | //findBigChar(); 53 | //replaceProgram(); 54 | //day(); 55 | //pot24(); 56 | //commad(); 57 | //perGC(); 58 | //binaryOne(); 59 | //leastTwo(); 60 | //nextInsert(); 61 | 62 | //substringSix(); 63 | //beautyNum(); 64 | //notDeadRabbit(); 65 | //asicSort(); 66 | 67 | 68 | //prefectReverse(); 69 | //replaceChar(); 70 | //replaceStar(); 71 | //addStar(); 72 | 73 | //endsWith(); 74 | //sum(); 75 | 76 | //quickSort(); 77 | 78 | //dpApple(); 79 | 80 | 81 | //check7(); 82 | //countAction(); 83 | //rabbit(); 84 | //highMeter(); 85 | //brotherWord(); 86 | //systemSort(); 87 | 88 | 89 | //password(); 90 | 91 | //password1(); 92 | 93 | //password2(); 94 | 95 | //drink(); 96 | 97 | //deleteLettleChar(); 98 | //wads(); 99 | //countMemory(); 100 | //sortString(); 101 | //reverseSentence(); 102 | 103 | 104 | //convert(); 105 | //countWords(); 106 | 107 | ///reverseSort(); 108 | //keyAndValue(); 109 | //addAndSub(); 110 | //divNumber(); 111 | //transNum(); 112 | //splitString(); 113 | //lastWordLength(); 114 | //secretPalace(); 115 | 116 | //killChild(); 117 | } 118 | 119 | /** 120 | * 输入一个字符串,返回其最长的数字子串,以及其长度。若有多个最长的数字子串,则将它们全部输出(按原字符串的相对位置) 121 | * 本题含有多组样例输入 122 | */ 123 | private static void sub() { 124 | Scanner in = new Scanner(System.in); 125 | while (in.hasNext()) { 126 | String str = in.nextLine(); 127 | int len = str.length(); 128 | int max = 0; 129 | int dp[] = new int[len]; 130 | int flag = 0; 131 | //动态规划边界 132 | if (str.charAt(0) >= '0' && str.charAt(0) <= '9') { 133 | 134 | dp[0] = 1; 135 | } 136 | for (int i = 1; i < len; i++) { 137 | if (str.charAt(i) >= '0' && str.charAt(i) <= '9') { 138 | dp[i] = dp[i - 1] + 1; 139 | } else { 140 | dp[i] = 0; 141 | } 142 | } 143 | for (int i = 0; i < dp.length; i++) { 144 | if (dp[i] > max) { 145 | max = dp[i]; 146 | flag = i; 147 | } 148 | } 149 | String temp = ""; 150 | for (int i = 0; i < dp.length; i++) { 151 | if (dp[i] == max) { 152 | temp += str.substring(i - max + 1, i + 1); 153 | } 154 | } 155 | //System.out.println(str.substring(flag-max+1,flag+1)+","+max); 156 | System.out.println(temp + "," + max); 157 | } 158 | } 159 | 160 | 161 | /** 162 | * 请计算n*m的棋盘格子(n为横向的格子数,m为竖向的格子数)沿着各自边缘线从左上角走到右下角,总共有多少种走法, 163 | * 要求不能走回头路,即:只能往右和往下走,不能往左和往上走。 164 | * 165 | * @param n 166 | * @param m 167 | * @return 168 | */ 169 | public static int getCount(int n, int m) { 170 | int[][] dp = new int[n + 1][m + 1]; 171 | for (int i = 0; i < n + 1; i++) { 172 | for (int j = 0; j < m + 1; j++) { 173 | if (i == 0 || j == 0) { 174 | // 边上的每一个点的可能性都是1,因为走到边上,就只能顺着边往下走了,可能性只能是1 175 | dp[i][j] = 1; 176 | } else { 177 | // 往后每一个点,都是后面两个点的可能性之和,因为它可以选择任意一个点来走,可能性就是下两个点的可能性相加 178 | dp[i][j] = dp[i][j - 1] + dp[i - 1][j]; 179 | } 180 | } 181 | } 182 | // 最终加到最后一个点,可能性就是所有的路线数量 183 | return dp[n][m]; 184 | } 185 | 186 | private static void judgeIp() throws IOException { 187 | BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); 188 | String str = ""; 189 | while ((str = bf.readLine()) != null) { 190 | 191 | String[] subIP = str.split("\\."); 192 | 193 | for (int i = 0; i < subIP.length; i++) { 194 | Integer intIP = Integer.valueOf(subIP[i]); 195 | if (intIP >= 0 && intIP <= 255) { 196 | if (i == subIP.length - 1) { 197 | System.out.println("YES"); 198 | } 199 | continue; 200 | } else { 201 | System.out.println("NO"); 202 | break; 203 | } 204 | } 205 | } 206 | } 207 | 208 | // 209 | //求一个byte数字对应的二进制数字中1的最大连续数,例如3的二进制为00000011,最大连续2个1 210 | private static void togetherOne() throws IOException { 211 | BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); 212 | String value; 213 | while ((value = bf.readLine()) != null) { 214 | int num = Integer.parseInt(value); 215 | char[] chars = Integer.toBinaryString(num).toCharArray(); 216 | 217 | int[] nums = new int[chars.length]; 218 | for (int index = 0; index < chars.length; index++) { 219 | char chat = chars[index]; 220 | if (chat == '1') { 221 | if (index == 0) 222 | nums[index] = 1; 223 | else { 224 | nums[index] = nums[index - 1] + 1; 225 | nums[index - 1] = 0; 226 | } 227 | } 228 | } 229 | 230 | Arrays.sort(nums); 231 | System.out.println(nums[nums.length - 1]); 232 | } 233 | } 234 | 235 | private static void leftAndRight() throws IOException { 236 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 237 | String str = null; 238 | 239 | while ((str = br.readLine()) != null && str.length() != 0) { 240 | char[] chars = str.toCharArray(); 241 | int n = chars.length; 242 | int max = 1; 243 | 244 | for (int i = 0; i < n - 1; i++) {//奇 245 | int left = i - 1; 246 | int right = i + 1; 247 | int length = 1; 248 | while (left >= 0 && right < n && chars[left] == chars[right]) { 249 | length += 2; 250 | left--; 251 | right++; 252 | } 253 | max = max > length ? max : length; 254 | } 255 | for (int i = 0; i < n - 1; i++) {//偶 256 | int length = 1; 257 | if (chars[i] == chars[i + 1]) { 258 | length = 2; 259 | } else 260 | continue; 261 | 262 | int left = i - 1; 263 | int right = i + 2; 264 | while (left >= 0 && right < n && chars[left] == chars[right]) { 265 | length += 2; 266 | left--; 267 | right++; 268 | } 269 | max = max > length ? max : length; 270 | } 271 | System.out.println(max); 272 | } 273 | } 274 | 275 | private static void findBigChar() throws IOException { 276 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 277 | String str; 278 | while ((str = br.readLine()) != null) { 279 | char[] chars = str.toCharArray(); 280 | int count = 0; 281 | for (int i = 0; i < chars.length; i++) 282 | if (65 <= chars[i] && chars[i] <= 90) count++; 283 | System.out.println(count); 284 | } 285 | } 286 | 287 | /*验证尼科彻斯定理,即:任何一个整数m的立方都可以写成m个连续奇数之和。 288 | 289 | 例如: 290 | 291 | 1^3=1 292 | 293 | 2^3=3+5 294 | 295 | 3^3=7+9+11 296 | 297 | 4^3=13+15+17+1*/ 298 | public static String method(int m) { 299 | int temp1 = m * m * m; 300 | int temp2 = m * m; 301 | StringBuffer sb = new StringBuffer(); 302 | 303 | for (int i = 0; i < m; i++) { 304 | if (m % 2 != 0) { 305 | sb.append(temp2 - 2 * (m / 2) + 2 * i).append("+"); 306 | } else { 307 | sb.append(temp2 - m + 1 + 2 * i).append("+"); 308 | ; 309 | } 310 | } 311 | return sb.substring(0, sb.length() - 1).toString(); 312 | } 313 | 314 | /** 315 | * 给定两个只包含小写字母的字符串,计算两个字符串的最大公共子串的长度。 316 | * 注:子串的定义指一个字符串删掉其部分前缀和后缀(也可以不删)后形成的字符串。 317 | * 318 | * @param c1 319 | * @param c2 320 | * @return 321 | */ 322 | public static int way(char[] c1, char[] c2) { 323 | int max = 0; 324 | for (int i = 0; i < c1.length; i++) { 325 | for (int j = 0; j < c2.length; j++) { 326 | int t1 = i; 327 | int count = 0; 328 | int t2 = j; 329 | while (c1[t1] == c2[t2]) { 330 | count++; 331 | t1++; 332 | t2++; 333 | if (count > max) { 334 | max = count; 335 | } 336 | if (t1 == c1.length || t2 == c2.length) { 337 | break; 338 | } 339 | } 340 | } 341 | } 342 | return max; 343 | } 344 | 345 | private static void replaceProgram() throws IOException { 346 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 347 | String s; 348 | while ((s = br.readLine()) != null) { 349 | char[] chars = s.toCharArray(); 350 | StringBuffer ana = new StringBuffer(); 351 | int flag = 0; 352 | int count = 1; 353 | for (int i = 0; i < chars.length; i++) { 354 | if (chars[i] == '\"') { 355 | flag++; 356 | continue; 357 | } 358 | if (chars[i] != ' ') { 359 | ana.append(chars[i]); 360 | } 361 | if (chars[i] == ' ' && flag % 2 != 0) { 362 | ana.append(chars[i]); 363 | } 364 | if (chars[i] == ' ' && flag % 2 == 0) { 365 | ana.append("\n"); 366 | count++; 367 | } 368 | } 369 | System.out.println(count + "\n" + ana.toString()); 370 | } 371 | } 372 | 373 | private static void day() throws IOException { 374 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 375 | String str = ""; 376 | while ((str = br.readLine()) != null) { 377 | String[] strs = str.split(" "); 378 | int year = Integer.parseInt(strs[0]); 379 | int month = Integer.parseInt(strs[1]); 380 | int day = Integer.parseInt(strs[2]); 381 | int result = day; 382 | for (int i = 1; i < month; i++) { 383 | result += getMonthDays(year, i); 384 | } 385 | System.out.println(result); 386 | } 387 | } 388 | 389 | public static int getMonthDays(int year, int month) { 390 | if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) { 391 | return 31; 392 | } 393 | if (month == 2) { 394 | return year % 4 == 0 ? 29 : 28; 395 | } 396 | return 30; 397 | } 398 | 399 | //买鸡 400 | private static void killChild() { 401 | int x, y; 402 | for (int z = 0; z < 100; z++) { 403 | if (z % 3 == 0) { 404 | if (4 * z / 3 - 100 >= 0 && 200 - 7 * z / 3 <= 100 && 4 * z / 3 - 100 <= 100 && 200 - 7 * z / 3 >= 0) { 405 | x = 4 * z / 3 - 100; 406 | y = 200 - 7 * z / 3; 407 | System.out.println(x + " " + y + " " + z); 408 | } 409 | } 410 | } 411 | } 412 | 413 | private static void pot24() throws IOException { 414 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 415 | String str = ""; 416 | while ((str = br.readLine()) != null) { 417 | String[] arr = str.split(" "); 418 | int[] num = new int[arr.length]; 419 | boolean[] flags = new boolean[arr.length]; 420 | for (int i = 0; i < num.length; i++) { 421 | num[i] = Integer.parseInt(arr[i]); 422 | } 423 | boolean flag = false; 424 | for (int i = 0; i < arr.length; i++) { 425 | flags[i] = true; 426 | flag = dfs(num, flags, num[i]); 427 | flags[i] = false; 428 | if (flag) break; 429 | } 430 | System.out.println(flag); 431 | 432 | 433 | } 434 | } 435 | 436 | public static boolean dfs(int[] arr, boolean[] flags, int c) { 437 | boolean end = true; 438 | for (boolean b : flags) { 439 | if (!b) { 440 | end = false; 441 | break; 442 | } 443 | } 444 | if (end) { 445 | if (c == 24) { 446 | return true; 447 | } else { 448 | return false; 449 | } 450 | } 451 | 452 | for (int i = 0; i < arr.length; i++) { 453 | if (!flags[i]) { 454 | flags[i] = true; 455 | if (dfs(arr, flags, c + arr[i])) return true; 456 | if (dfs(arr, flags, c - arr[i])) return true; 457 | if (dfs(arr, flags, c * arr[i])) return true; 458 | if (c % arr[i] == 0 && dfs(arr, flags, c / arr[i])) return true; 459 | flags[i] = false; 460 | } 461 | } 462 | return false; 463 | } 464 | 465 | /** 466 | * 多行字符串,每行字符串一条命令 467 | * 468 | * @throws IOException 469 | */ 470 | private static void commad() throws IOException { 471 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 472 | 473 | HashMap HMp = new HashMap<>(); 474 | HMp.put("reset", "reset what"); 475 | HMp.put("reset board", "board fault"); 476 | HMp.put("board add", "where to add"); 477 | HMp.put("board delete", "no board at all"); 478 | HMp.put("reboot backplane", "impossible"); 479 | HMp.put("backplane abort", "install first"); 480 | 481 | String input = br.readLine(); 482 | 483 | while (null != input) { 484 | if (HMp.containsKey(input)) { 485 | System.out.println(HMp.get(input)); 486 | } else { 487 | System.out.println("unknown command"); 488 | } 489 | 490 | input = br.readLine(); 491 | } 492 | } 493 | 494 | //找出GC比例最高的子串,如果有多个输出第一个的子串 495 | 496 | /** 497 | * 输入 AACTGTGCACGACCTGA 498 | * 5 499 | * 输出 GCACG 500 | * 501 | * @throws IOException 502 | */ 503 | private static void perGC() throws IOException { 504 | BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); 505 | 506 | 507 | String str = null; 508 | 509 | while ((str = bf.readLine()) != null) { 510 | 511 | int num = Integer.parseInt(bf.readLine()); 512 | int count = 0; 513 | for (int i = 0; i < str.length(); i++) { 514 | char c = str.charAt(i); 515 | if (c == 'G' || c == 'C') 516 | count++; 517 | } 518 | int max = count; 519 | int left = 0; 520 | for (int i = 1; i < str.length() - num; i++) { 521 | char pre = str.charAt(i - 1); 522 | char nex = str.charAt(i + num - 1); 523 | if (pre == 'G' || pre == 'C') 524 | count--; 525 | if (nex == 'G' || nex == 'C') 526 | count++; 527 | if (count > max) { 528 | max = count; 529 | left = i; 530 | } 531 | } 532 | 533 | System.out.println(str.substring(left, left + num)); 534 | 535 | 536 | } 537 | } 538 | 539 | //计算整数二进制中1的个数 540 | private static void binaryOne() { 541 | Scanner scan = new Scanner(System.in); 542 | while (scan.hasNext()) { 543 | int n = scan.nextInt(); 544 | int count = 0; 545 | String str = Integer.toBinaryString(n); 546 | char[] cha = str.toCharArray(); 547 | for (char c : cha) { 548 | if (c == '1') { 549 | count++; 550 | } 551 | } 552 | System.out.println(count); 553 | } 554 | } 555 | 556 | //输入n个整数,输出其中最小的k个。 557 | private static void leastTwo() { 558 | Scanner scanner = new Scanner(System.in); 559 | while (scanner.hasNext()) { 560 | String s = scanner.nextLine(); 561 | String s1 = scanner.nextLine(); 562 | String[] ss = s.split(" "); 563 | String[] s1s = s1.split(" "); 564 | int[] nums = new int[Integer.valueOf(ss[0])]; 565 | for (int i = 0; i < s1s.length; i++) { 566 | nums[i] = Integer.valueOf(s1s[i]); 567 | } 568 | Arrays.sort(nums); 569 | StringBuilder stringBuilder = new StringBuilder(); 570 | for (int i = 0; i < Integer.valueOf(ss[1]); i++) { 571 | stringBuilder.append(nums[i]).append(" "); 572 | } 573 | System.out.println(stringBuilder.toString().trim()); 574 | } 575 | } 576 | 577 | //输入一个单向链表,输出该链表中倒数第k个结点,链表的倒数第1个结点为链表的尾指针 578 | private static void nextInsert() throws IOException { 579 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 580 | String str = null; 581 | while ((str = br.readLine()) != null) { 582 | int num = Integer.parseInt(str); 583 | String[] numStr = br.readLine().split(" "); 584 | 585 | int num2 = Integer.parseInt(br.readLine().trim()); 586 | if (num2 <= 0 || num2 > numStr.length) { 587 | System.out.println(num2); 588 | } else { 589 | System.out.println(numStr[numStr.length - num2]); 590 | } 591 | } 592 | } 593 | 594 | //输入一个字符串和一个整数k,截取字符串的前k个字符并输出 595 | private static void substringSix() throws IOException { 596 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 597 | String str = null; 598 | while ((str = br.readLine()) != null) { 599 | int k = Integer.parseInt(br.readLine()); 600 | System.out.println(str.substring(0, k)); 601 | } 602 | } 603 | 604 | private static void beautyNum() throws IOException { 605 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 606 | String str; 607 | while ((str = br.readLine()) != null) { 608 | int n = Integer.parseInt(str); 609 | for (int i = 0; i < n; i++) { 610 | String s = br.readLine(); 611 | char[] c = s.toCharArray(); 612 | int[] count = new int[150]; 613 | for (int j = 0; j < c.length; j++) { 614 | count[c[j]]++; 615 | } 616 | 617 | Arrays.sort(count); 618 | int a = 26; 619 | int sum = 0; 620 | for (int k = count.length - 1; k >= 0; k--) { 621 | if (count[k] == 0) { 622 | break; 623 | } 624 | sum += count[k] * (a--); 625 | } 626 | System.out.println(sum); 627 | } 628 | } 629 | } 630 | 631 | //迷宫问题 632 | private static void secretPalace() throws IOException { 633 | BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in)); 634 | String x; 635 | while ((x = bfr.readLine()) != null) { 636 | String[] arr = x.split(" "); 637 | int m = Integer.parseInt(arr[0]); 638 | int n = Integer.parseInt(arr[1]); 639 | int[][] a = new int[m][n]; 640 | for (int i = 0; i < m; i++) { 641 | String strr = bfr.readLine(); 642 | String[] b = strr.split(" "); 643 | for (int j = 0; j < n; j++) { 644 | a[i][j] = Integer.parseInt(b[j]); 645 | } 646 | } 647 | 648 | int i = 0; 649 | int j = 0; 650 | for (int k = 0; k < m + n - 1; k++) { 651 | ////打印:当mat[i][j]==0时 652 | if (a[i][j] == 0) { 653 | System.out.println("(" + i + "," + j + ")"); 654 | } 655 | //只能往下走:索引到最大j==n-1||右边mat[i][j+1]==1时,i++ 656 | if (j == n - 1 || a[i][j + 1] == 1) { 657 | i++; 658 | continue; 659 | } 660 | //只能往右走:索引到最大i==m-1||下边mat[i][j+1]==1时,j++ 661 | if (i == m - 1 || a[i][j + 1] == 0) { 662 | j++; 663 | continue; 664 | } 665 | //停止:i==m-1 && j==n-1时,break跳出 666 | if ((i == m - 1) && (j == n - 1)) { 667 | break; 668 | } 669 | } 670 | 671 | 672 | } 673 | } 674 | 675 | 676 | //数字转换成英语 677 | public static String parse(int num) { 678 | String[] numStr = {"zero", "one", "two", "three", "four", "five", 679 | "six", "seven", "eight", "nine", "ten", "eleven", "twelve", 680 | "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", 681 | "eighteen", "ninteen"}; 682 | if (num >= 0 && num < 20) { 683 | return numStr[num]; 684 | } else if (num >= 20 && num < 100) { 685 | int a = num % 10; 686 | if (num < 30) { 687 | return a != 0 ? "twenty " + parse(a) : "twenty"; 688 | } else if (num < 40) { 689 | return a != 0 ? "thirty " + parse(a) : "thirty"; 690 | } else if (num < 50) { 691 | return a != 0 ? "forty " + parse(a) : "forty"; 692 | } else if (num < 60) { 693 | return a != 0 ? "fifty " + parse(a) : "fifty"; 694 | } else if (num < 70) { 695 | return a != 0 ? "sixty " + parse(a) : "sixty"; 696 | } else if (num < 80) { 697 | return a != 0 ? "seventy " + parse(a) : "seventy"; 698 | } else if (num < 90) { 699 | return a != 0 ? "eighty " + parse(a) : "eighty"; 700 | } else if (num < 100) { 701 | return a != 0 ? "ninety " + parse(a) : "ninety"; 702 | } 703 | } else if (num >= 100 && num < 1000) { 704 | int x = num / 100; 705 | int y = num % 100; 706 | if (y != 0) { 707 | return parse(x) + " hundred" + " and " + parse(y); 708 | } else { 709 | return parse(x) + " hundred"; 710 | } 711 | } else if (num >= 1000 && num < 1000000) { 712 | int x = num / 1000; 713 | int y = num % 1000; 714 | if (y != 0) { 715 | return parse(x) + " thousand " + parse(y); 716 | } else { 717 | return parse(x) + " thousand"; 718 | } 719 | } else if (num >= 1000000 && num < 100000000) { 720 | int x = num / 1000000; 721 | int y = num % 1000000; 722 | if (y != 0) { 723 | return parse(x) + " million " + parse(y); 724 | } else { 725 | return parse(x) + " million"; 726 | } 727 | } 728 | return "error"; 729 | } 730 | 731 | //不死兔子 732 | private static void notDeadRabbit() throws IOException { 733 | BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); 734 | String input; 735 | while ((input = bf.readLine()) != null) { 736 | int num = Integer.parseInt(input); 737 | int a = 1; 738 | int b = 1; 739 | if (num == 1 || num == 2) System.out.println(num); 740 | else { 741 | for (int i = 3; i <= num; i++) { 742 | int temp = b; 743 | b = a + b; 744 | a = temp; 745 | } 746 | System.out.println(b); 747 | } 748 | } 749 | } 750 | 751 | //蛇形矩阵是由1开始的自然数依次排列成的一个矩阵上三角形 752 | private static void encode(int key) { 753 | // TODO Auto-generated method stub 754 | int[][] arr = new int[key][key]; 755 | arr[0][0] = 1; 756 | System.out.print(arr[0][0]); 757 | for (int i = 1; i < key; i++) { 758 | arr[0][i] = arr[0][i - 1] + i + 1; 759 | System.out.print(" " + arr[0][i]); 760 | } 761 | for (int i = 1; i < key; i++) { 762 | System.out.println(); 763 | for (int j = 0; j < key - i; j++) { 764 | arr[i][j] = arr[i - 1][j + 1] - 1; 765 | if (j == 0) { 766 | System.out.print(arr[i][j]); 767 | } else { 768 | System.out.print(" " + arr[i][j]); 769 | } 770 | } 771 | } 772 | } 773 | 774 | private static void asicSort() { 775 | Scanner in = new Scanner(System.in); 776 | while (in.hasNext()) { 777 | String s = in.nextLine(); 778 | char[] str = s.toCharArray(); 779 | Arrays.sort(str); 780 | System.out.println(str); 781 | } 782 | } 783 | 784 | private static void getTenToIP(String num) { 785 | String sb = ""; 786 | //把数转化成二进制 787 | String binaryString = Long.toBinaryString(Long.parseLong(num)); 788 | /*System.out.println(binaryString); 789 | System.out.println(binaryString.length()); 790 | System.out.println(addZero32(binaryString)); 791 | System.out.println(addZero32(binaryString).length());*/ 792 | String binnaryNum = addZero32(binaryString); 793 | //然后没8个一组,进行截取 794 | for (int i = 0; i < binnaryNum.length(); i = i + 8) { 795 | //System.out.println(binnaryNum.substring(i, i+8)); 796 | String substring = binnaryNum.substring(i, i + 8); 797 | //转化为十进制数 798 | int parseInt = Integer.parseInt(substring, 2); 799 | sb = sb + parseInt + "."; 800 | 801 | } 802 | System.out.println(sb.substring(0, sb.length() - 1)); 803 | } 804 | 805 | private static String addZero32(String binaryString) { 806 | // TODO Auto-generated method stub 807 | 808 | if (binaryString.length() < 32) { 809 | String sb = ""; 810 | int addLength = 32 - binaryString.length(); 811 | for (int i = 0; i < addLength; i++) { 812 | sb = sb + "0"; 813 | } 814 | return sb + binaryString; 815 | } 816 | return binaryString; 817 | } 818 | 819 | private static void getTenIp(String ip) { 820 | String sb = ""; 821 | String[] sub = ip.split("\\.");//.需要转义字符 822 | for (int i = 0; i < sub.length; i++) { 823 | //System.out.println(sub[i]); 824 | //对每一个字符转换成二进制 825 | String binaryString = Integer.toBinaryString(Integer.parseInt(sub[i])); 826 | //对每一位进行判断,不够8位补零 827 | String addZeroIP = addZero(binaryString); 828 | sb = sb + addZeroIP; 829 | //System.out.println(addZero(binaryString)); 830 | } 831 | //System.out.println(sb.length()); 832 | System.out.println(Long.parseLong(sb, 2));//刚开始就是老师用Integer,位数不够 833 | } 834 | 835 | private static String addZero(String binaryString) { 836 | // TODO Auto-generated method stub 837 | 838 | if (binaryString.length() < 8) { 839 | String sb = ""; 840 | int addLength = 8 - binaryString.length(); 841 | for (int i = 0; i < addLength; i++) { 842 | sb = sb + "0"; 843 | } 844 | return sb + binaryString; 845 | } 846 | return binaryString; 847 | } 848 | 849 | //回文串只有两种类型:偶数型为ABBA型,奇数型为ABA型。。 850 | //依次向后以每个字符为中心,向两侧扩展,判断是偶数型还是奇数型,然后比较偶数型和奇数型回文串的最大长度。。 851 | public static void Dispose(String str) { 852 | int len = str.length();//字符串长度 853 | if (len == 1) { 854 | System.out.println(1); 855 | return; 856 | } 857 | int num = 1;//回文串最大长度,最小为1 858 | for (int i = 1; i < len - 1; i++) { //从第二个字符开始,依次选为中心字符向向两侧扩展 859 | if (str.charAt(i) == str.charAt(i + 1)) { //偶数对为回文串 860 | int cur = 0; //当成为回文串的最大长度,初始化置为0 861 | int start = i; //左侧起始位 862 | int end = i + 1; //右侧起始位 863 | while (start >= 0 && end < len && str.charAt(start) == str.charAt(end)) { //向两侧扩展 864 | start--;//每次扩展一位 865 | end++; 866 | cur += 2;//每次最大回文长度增加两位 867 | } 868 | if (cur >= num) { 869 | num = cur; 870 | } 871 | } 872 | if (str.charAt(i - 1) == str.charAt(i + 1)) { //奇数对为回文串 873 | int cur = 0; 874 | int start = i - 1; //左侧 875 | int end = i + 1; //右侧 876 | while (start >= 0 && end < len && str.charAt(start) == str.charAt(end)) { //向两侧扩展 877 | start--; 878 | end++; 879 | cur += 2; 880 | } 881 | if (cur >= num) { 882 | num = cur + 1;//注意此处加1是为了算上中心字符; 883 | } 884 | } 885 | } 886 | System.out.println(num); 887 | } 888 | 889 | private static void prefectReverse() { 890 | Scanner sc = new Scanner(System.in); 891 | String s = sc.nextLine(); 892 | String ss = s.replaceAll("[^a-zA-Z]+", " ").trim(); 893 | String str[] = ss.split(" "); 894 | for (int i = str.length - 1; i > 0; i--) { 895 | System.out.print(str[i] + " "); 896 | } 897 | System.out.println(str[0]); 898 | } 899 | 900 | private static void drink() { 901 | Scanner sc = new Scanner(System.in); 902 | while (sc.hasNext()) { 903 | int num = sc.nextInt(); 904 | if (num == 0) break; 905 | System.out.println(result(num)); 906 | } 907 | } 908 | 909 | public static int result(int n) { 910 | int result = 0; 911 | int total = n; 912 | while (total > 0) {//不断循环 913 | if (total == 2) {//只剩下两瓶就+1 914 | total++; 915 | } 916 | total = total - 3; 917 | if (total >= 0) {//每减三瓶总数加一瓶,结果也加一 918 | total++; 919 | result++; 920 | } 921 | } 922 | return result; 923 | } 924 | 925 | private static void password2() { 926 | Scanner sc = new Scanner(System.in); 927 | String string = sc.nextLine(); 928 | StringBuilder stringBuilder = new StringBuilder(); 929 | for (int i = 0; i < string.length(); i++) { 930 | char c = string.charAt(i); 931 | stringBuilder.append(password(c)); 932 | } 933 | System.out.println(stringBuilder.toString()); 934 | sc.close(); 935 | } 936 | 937 | public static char password(char c) { 938 | int[] codetable = {2, 2, 2, 3, 3, 3, 4, 4, 4, 939 | 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9}; 940 | if (c <= 'Z' && c >= 'A') { 941 | if (c == 'Z') { 942 | c = 'a'; 943 | } else { 944 | c = Character.toLowerCase(c); 945 | c++; 946 | } 947 | } else if (c <= 'z' && c >= 'a') { 948 | c = (char) (codetable[c - 'a'] + '0'); 949 | } 950 | return c; 951 | } 952 | 953 | private static void password1() throws IOException { 954 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 955 | String input = null; 956 | StringBuffer sb = new StringBuffer(); 957 | 958 | while (null != (input = reader.readLine())) { 959 | 960 | //设置四种类型数据初始为空即false,有数据了就更改为true 961 | boolean[] flag = new boolean[4]; 962 | char[] chars = input.toCharArray(); 963 | 964 | // 第一个条件 965 | if (chars.length < 9) { 966 | sb.append("NG").append("\n"); 967 | continue; 968 | } 969 | 970 | // 第二个条件 971 | for (int i = 0; i < chars.length; i++) { 972 | if ('A' <= chars[i] && chars[i] <= 'Z') { 973 | flag[0] = true; 974 | } else if ('a' <= chars[i] && chars[i] <= 'z') { 975 | flag[1] = true; 976 | } else if ('0' <= chars[i] && chars[i] <= '9') { 977 | flag[2] = true; 978 | } else { 979 | flag[3] = true; 980 | } 981 | } 982 | int count = 0; 983 | for (int i = 0; i < 4; i++) { 984 | if (flag[i]) { 985 | count++; 986 | } 987 | } 988 | 989 | // 第三个条件 990 | boolean sign = true; //不存在两个大于2的子串相同,即!(i=i+3,i+1=i+4,i+2=i+5) 991 | for (int i = 0; i < chars.length - 5; i++) { 992 | for (int j = i + 3; j < chars.length - 2; j++) { 993 | if (chars[i] == chars[j] && chars[i + 1] == chars[j + 1] && chars[i + 2] == chars[j + 2]) { 994 | sign = false; 995 | } 996 | } 997 | } 998 | 999 | if (count >= 3 && sign) { 1000 | sb.append("OK").append("\n"); 1001 | } else { 1002 | sb.append("NG").append("\n"); 1003 | } 1004 | } 1005 | System.out.println(sb.toString()); 1006 | } 1007 | 1008 | private static void password() throws IOException { 1009 | BufferedReader buffer = 1010 | new BufferedReader(new InputStreamReader(System.in)); 1011 | String str; 1012 | LinkedHashMap data = new LinkedHashMap(); 1013 | while ((str = buffer.readLine()) != null) { 1014 | int idx1 = str.lastIndexOf(" "); 1015 | int idx2 = str.lastIndexOf("\\"); 1016 | String key = (idx1 - idx2) > 16 ? str.substring(idx1 - 16) : str.substring(idx2 + 1); 1017 | data.put(key, data.getOrDefault(key, 0) + 1); 1018 | } 1019 | int count = 0; 1020 | for (String key : data.keySet()) { 1021 | count++; 1022 | if (count > (data.size() - 8)) { 1023 | System.out.println(key + " " + data.get(key)); 1024 | } 1025 | } 1026 | } 1027 | 1028 | private static void replaceChar() { 1029 | String s = "?123233?34"; 1030 | char[] chars = s.toCharArray(); 1031 | 1032 | for (int i = 0; i < chars.length; i++) { 1033 | if (chars[i] == '?') { 1034 | //前面一个字符 如果当前是第0个的话 字符就为‘ ’ 1035 | char ahead = i == 0 ? ' ' : chars[i - 1]; 1036 | //后面一个字符 如果当前是最后一个的话 字符就为‘ ’ 1037 | char behind = i == chars.length - 1 ? ' ' : chars[i + 1]; 1038 | //从a开始比较 如果等于前面或者后面的话 就+1 1039 | char temp = 'a'; 1040 | while (temp == ahead || temp == behind) { 1041 | temp++; 1042 | } 1043 | //找到目标字符后 做替换 1044 | chars[i] = temp; 1045 | } 1046 | } 1047 | System.out.println(new String(chars)); 1048 | } 1049 | 1050 | private static void replaceStar() throws IOException { 1051 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 1052 | String str; 1053 | while (null != (str = br.readLine())) { 1054 | char[] strs = str.toCharArray(); 1055 | StringBuilder result = new StringBuilder(); 1056 | int i = 0; 1057 | while (i < strs.length) { 1058 | if ('0' <= strs[i] && strs[i] <= '9') { 1059 | result.append("*"); 1060 | result.append(strs[i]); 1061 | while (++i < strs.length && '0' <= strs[i] && strs[i] <= '9') { 1062 | result.append(strs[i]); 1063 | } 1064 | result.append("*"); 1065 | } else { 1066 | result.append(strs[i]); 1067 | i++; 1068 | } 1069 | } 1070 | System.out.println(result.toString().trim()); 1071 | } 1072 | } 1073 | 1074 | private static void addStar() throws IOException { 1075 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 1076 | String str = ""; 1077 | while ((str = br.readLine()) != null) { 1078 | char[] c = str.toCharArray(); 1079 | StringBuilder sb = new StringBuilder(); 1080 | int i = 0; 1081 | while (i < c.length) { 1082 | if (c[i] >= '0' && c[i] <= '9') { 1083 | sb.append("*"); 1084 | sb.append(c[i]); 1085 | while (++i < c.length && c[i] >= '0' && c[i] <= '9') { 1086 | sb.append(c[i]); 1087 | } 1088 | sb.append("*"); 1089 | } else { 1090 | sb.append(c[i]); 1091 | i++; 1092 | } 1093 | } 1094 | System.out.println(sb.toString()); 1095 | } 1096 | } 1097 | 1098 | private static void endsWith() { 1099 | Scanner sc = new Scanner(System.in); 1100 | while (sc.hasNextInt()) { 1101 | int n = sc.nextInt(); 1102 | int cnt = 0; 1103 | for (int i = 0; i <= n; i++) { 1104 | long end = i * i; 1105 | if (String.valueOf(end).endsWith(String.valueOf(i))) { 1106 | cnt++; 1107 | } 1108 | } 1109 | System.out.println(cnt); 1110 | } 1111 | } 1112 | 1113 | private static void sum() throws IOException { 1114 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 1115 | String str = ""; 1116 | while ((str = br.readLine()) != null) { 1117 | int n = Integer.parseInt(str); 1118 | System.out.println((3 * n * n + n) / 2); 1119 | } 1120 | } 1121 | 1122 | private static void quickSort() throws IOException { 1123 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 1124 | String inputCount; 1125 | 1126 | while ((inputCount = br.readLine()) != null) { 1127 | int count = Integer.parseInt(inputCount); 1128 | String[] input = br.readLine().split(" "); 1129 | int flag = Integer.parseInt(br.readLine()); 1130 | int[] num = new int[input.length]; 1131 | for (int i = 0; i < input.length; i++) { 1132 | num[i] = Integer.parseInt(input[i]); 1133 | } 1134 | quickSort(num, 0, num.length - 1); 1135 | StringBuilder sb = new StringBuilder(); 1136 | if (flag == 0) { 1137 | for (int j = 0; j < num.length; j++) { 1138 | sb.append(num[j]).append(" "); 1139 | } 1140 | } else { 1141 | for (int k = num.length - 1; k >= 0; k--) { 1142 | sb.append(num[k]).append(" "); 1143 | } 1144 | } 1145 | System.out.println(sb.substring(0, sb.length() - 1)); 1146 | } 1147 | } 1148 | 1149 | public static void quickSort(int[] num, int L, int R) { 1150 | if (L >= R) { 1151 | return; 1152 | } 1153 | int p = partition(num, L, R); 1154 | quickSort(num, L, p - 1); 1155 | quickSort(num, p + 1, R); 1156 | } 1157 | 1158 | public static int partition(int[] num, int L, int R) { 1159 | int key = num[L]; 1160 | int pivot = L; 1161 | 1162 | for (int i = L + 1; i <= R; i++) { 1163 | if (num[i] < key) { 1164 | int temp = num[++pivot]; 1165 | num[pivot] = num[i]; 1166 | num[i] = temp; 1167 | } 1168 | } 1169 | int tt = num[pivot]; 1170 | num[pivot] = num[L]; 1171 | num[L] = tt; 1172 | return pivot; 1173 | } 1174 | 1175 | private static void dpApple() throws IOException { 1176 | /* 解题分析: 1177 | 设f(m,n) 为m个苹果,n个盘子的放法数目,则先对n作讨论, 1178 | 当n>m:必定有n-m个盘子永远空着,去掉它们对摆放苹果方法数目不产生影响。即if(n>m) f(m,n) = f(m,m)   1179 | 当n<=m:不同的放法可以分成两类: 1180 | 1、有至少一个盘子空着,即相当于f(m,n) = f(m,n-1); 1181 | 2、所有盘子都有苹果,相当于可以从每个盘子中拿掉一个苹果,不影响不同放法的数目,即f(m,n) = f(m-n,n). 1182 | 而总的放苹果的放法数目等于两者的和,即 f(m,n) =f(m,n-1)+f(m-n,n) 1183 | 递归出口条件说明: 1184 | 当n=1时,所有苹果都必须放在一个盘子里,所以返回1; 1185 | 当没有苹果可放时,定义为1种放法; 1186 | 递归的两条路,第一条n会逐渐减少,终会到达出口n==1; 1187 | 第二条m会逐渐减少,因为n>m时,我们会return f(m,m) 所以终会到达出口m==0. 1188 | */ 1189 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 1190 | String str = " "; 1191 | while ((str = br.readLine()) != null) { 1192 | String[] s = str.split(" "); 1193 | int m = Integer.parseInt(s[0]); 1194 | int n = Integer.parseInt(s[1]); 1195 | System.out.println(count(m, n)); 1196 | } 1197 | } 1198 | 1199 | public static int count(int m, int n) { 1200 | if (n == 1 || m == 0) return 1; 1201 | else if (n > m) return count(m, m); 1202 | else return count(m, n - 1) + count(m - n, n); 1203 | } 1204 | 1205 | private static void check7() throws IOException { 1206 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); 1207 | String input = ""; 1208 | while ((input = bufferedReader.readLine()) != null) { 1209 | int count = 0; 1210 | int num = Integer.parseInt(input); 1211 | for (int i = 7; i <= num; i++) { 1212 | if (i % 7 == 0 || contain7(i)) { 1213 | count++; 1214 | } 1215 | } 1216 | System.out.println(count); 1217 | } 1218 | } 1219 | 1220 | public static boolean contain7(int n) { 1221 | while (n > 0) { 1222 | if (n % 10 == 7) { 1223 | return true; 1224 | } else { 1225 | n /= 10; 1226 | } 1227 | } 1228 | return false; 1229 | } 1230 | 1231 | //输入一行字符,分别统计出包含英文字母、空格、数字和其它字符的个数。 1232 | private static void countAction() { 1233 | Scanner scanner = new Scanner(System.in); 1234 | while (scanner.hasNext()) { 1235 | String string = scanner.nextLine(); 1236 | for (int i = 0; i < 4; i++) { 1237 | System.out.println(getNumbers(string)[i]); 1238 | } 1239 | } 1240 | scanner.close(); 1241 | } 1242 | 1243 | public static int[] getNumbers(String string) { 1244 | int[] n = new int[4]; 1245 | for (int i = 0; i < string.length(); i++) { 1246 | char c = string.charAt(i); 1247 | if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { 1248 | n[0]++; 1249 | } else if (c == ' ') { 1250 | n[1]++; 1251 | } else if (c >= '0' && c <= '9') { 1252 | n[2]++; 1253 | } else { 1254 | n[3]++; 1255 | } 1256 | } 1257 | 1258 | return n; 1259 | } 1260 | 1261 | private static void rabbit() { 1262 | Scanner sc = new Scanner(System.in); 1263 | while (sc.hasNext()) { 1264 | int n = sc.nextInt(); 1265 | //int m = count(n); 1266 | int m = count(n); 1267 | System.out.println(m); 1268 | } 1269 | } 1270 | 1271 | private static int count(int n) { 1272 | if (n == 1 || n == 2) { 1273 | return 1; 1274 | } 1275 | return count(n - 1) + count(n - 2); 1276 | } 1277 | 1278 | //自由落体 1279 | private static void highMeter() { 1280 | Scanner in = new Scanner(System.in); 1281 | while (in.hasNext()) { 1282 | int val = in.nextInt(); 1283 | double current = val, sum = 0; 1284 | for (int i = 0; i < 10; i++) { 1285 | sum += current; 1286 | current = current / 2; 1287 | sum += current; 1288 | } 1289 | sum -= current; 1290 | System.out.println(sum); 1291 | System.out.println(current); 1292 | } 1293 | } 1294 | 1295 | private static double calculate(double high) { 1296 | return high / 2; 1297 | } 1298 | 1299 | private static void brotherWord() throws IOException { 1300 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 1301 | String str; 1302 | while ((str = br.readLine()) != null) { 1303 | char[] arr = str.toCharArray(); 1304 | StringBuilder builder = new StringBuilder(); 1305 | // 英文字母从 A 到 Z 排列,不区分大小写:26 个 1306 | for (int i = 0; i < 26; i++) { 1307 | char c = (char) ('A' + i); 1308 | // 遍历字符串 1309 | for (int j = 0, length = str.length(); j < length; j++) { 1310 | // 不区分大小写 1311 | if (c == arr[j] || c == arr[j] - 'a' + 'A') { 1312 | builder.append(arr[j]); 1313 | } 1314 | } 1315 | } 1316 | // 非英文字母的其它字符保持原来的位置 1317 | for (int i = 0, length = str.length(); i < length; i++) { 1318 | if (!((arr[i] >= 'A' && arr[i] <= 'Z') || (arr[i] >= 'a' && arr[i] <= 'z'))) { 1319 | builder.insert(i, arr[i]); 1320 | } 1321 | } 1322 | System.out.println(builder.toString()); 1323 | } 1324 | } 1325 | 1326 | //加密解密 1327 | private static String en(String s) { 1328 | char[] cs = s.toCharArray(); 1329 | for (int i = 0; i < cs.length; i++) { 1330 | if (cs[i] >= 'A' && cs[i] <= 'Z') { 1331 | if (cs[i] == 'Z') { 1332 | cs[i] = 'a'; 1333 | } else 1334 | cs[i] = (char) (cs[i] + 33); 1335 | } else if (cs[i] >= 'a' && cs[i] <= 'z') { 1336 | if (cs[i] == 'z') { 1337 | cs[i] = 'A'; 1338 | } else 1339 | cs[i] = (char) (cs[i] - 31); 1340 | } else if (cs[i] >= '0' && cs[i] <= '9') { 1341 | if (cs[i] == '9') { 1342 | cs[i] = '0'; 1343 | } else { 1344 | cs[i] = (char) (cs[i] + 1); 1345 | } 1346 | } 1347 | } 1348 | return String.valueOf(cs); 1349 | } 1350 | 1351 | private static String de(String s) { 1352 | char[] cs = s.toCharArray(); 1353 | for (int i = 0; i < cs.length; i++) { 1354 | if (cs[i] >= 'A' && cs[i] <= 'Z') { 1355 | if (cs[i] == 'A') { 1356 | cs[i] = 'z'; 1357 | } else 1358 | cs[i] = (char) (cs[i] + 31); 1359 | } else if (cs[i] >= 'a' && cs[i] <= 'z') { 1360 | if (cs[i] == 'a') { 1361 | cs[i] = 'Z'; 1362 | } else 1363 | cs[i] = (char) (cs[i] - 33); 1364 | } else if (cs[i] >= '0' && cs[i] <= '9') { 1365 | if (cs[i] == '0') { 1366 | cs[i] = '9'; 1367 | } else { 1368 | cs[i] = (char) (cs[i] - 1); 1369 | } 1370 | } 1371 | } 1372 | return String.valueOf(cs); 1373 | } 1374 | 1375 | private static void systemSort() { 1376 | Scanner sca = new Scanner(System.in); 1377 | while (sca.hasNext()) { 1378 | String str = sca.nextLine(); 1379 | char[] cha = str.toCharArray(); 1380 | StringBuffer sb = new StringBuffer(); 1381 | 1382 | for (int i = 0; i < 26; i++) { 1383 | char c = (char) (i + 'A'); 1384 | for (int j = 0; j < str.length(); j++) { 1385 | if (cha[j] == c || cha[j] == (char) (c + 32)) 1386 | sb.append(cha[j]); 1387 | } 1388 | } 1389 | 1390 | for (int k = 0; k < str.length(); k++) { 1391 | if (!(cha[k] >= 'A' && cha[k] <= 'Z' || cha[k] >= 'a' && cha[k] <= 'z')) 1392 | sb.insert(k, cha[k]); 1393 | } 1394 | System.out.println(sb.toString()); 1395 | } 1396 | } 1397 | 1398 | private static void deleteLettleChar() { 1399 | Scanner sc = new Scanner(System.in); 1400 | while (sc.hasNext()) { 1401 | String string = sc.nextLine(); 1402 | char[] A = string.toCharArray(); 1403 | Map m = new LinkedHashMap(); 1404 | 1405 | for (char c : A) { 1406 | if (!m.containsKey(c)) { 1407 | m.put(c, 1); 1408 | } else { 1409 | m.put(c, m.get(c) + 1); 1410 | } 1411 | } 1412 | Collection al = m.values(); 1413 | int index = Collections.min(al); 1414 | StringBuffer sb = new StringBuffer(""); 1415 | for (char c : A) { 1416 | if (m.get(c) != index) 1417 | sb.append(c); 1418 | } 1419 | System.out.println(sb.toString()); 1420 | 1421 | } 1422 | } 1423 | 1424 | /** 1425 | * 上下左右移动 1426 | */ 1427 | private static void wads() { 1428 | try { 1429 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 1430 | String str; 1431 | int x = 0; 1432 | int y = 0; 1433 | while ((str = reader.readLine()) != null) { 1434 | String[] split = str.split(";"); 1435 | for (int i = 0; i < split.length; i++) { 1436 | char[] chars = split[i].toCharArray(); 1437 | int length = 0; 1438 | if (chars.length > 3) { 1439 | continue; 1440 | } 1441 | for (int j = 1; j < chars.length; j++) { 1442 | if (chars[j] >= '0' && chars[j] <= '9') { 1443 | length = length * 10 + chars[j] - '0'; 1444 | } else { 1445 | length = 0; 1446 | break; 1447 | } 1448 | } 1449 | switch (chars[0]) { 1450 | case 'A': 1451 | x -= length; 1452 | break; 1453 | case 'S': 1454 | y -= length; 1455 | break; 1456 | case 'W': 1457 | y += length; 1458 | break; 1459 | case 'D': 1460 | x += length; 1461 | } 1462 | } 1463 | System.out.println(x + "," + y); 1464 | } 1465 | } catch (IOException e) { 1466 | e.printStackTrace(); 1467 | } 1468 | } 1469 | 1470 | /** 1471 | * 输入一个int型的正整数,计算出该int型数据在内存中存储时1的个数。 1472 | */ 1473 | private static void countMemory() { 1474 | Scanner scanner = new Scanner(System.in); 1475 | int j = scanner.nextInt(); 1476 | String string = Integer.toBinaryString(j); 1477 | 1478 | int count = 0; 1479 | for (int i = 0; i < string.length(); i++) { 1480 | if (string.charAt(i) == '1') { 1481 | count++; 1482 | } 1483 | } 1484 | System.out.println(count); 1485 | } 1486 | 1487 | /** 1488 | * 输入第一行为一个正整数n(1≤n≤1000), 1489 | * 下面n行为n个字符串(字符串长度≤100),字符串中只含有大小写字母。 1490 | */ 1491 | private static void sortString() { 1492 | Scanner scan = new Scanner(System.in); 1493 | ArrayList set = new ArrayList(); 1494 | int num = scan.hasNextLine() ? Integer.parseInt(scan.nextLine()) : 0; 1495 | while (--num >= 0) { 1496 | set.add(scan.nextLine()); 1497 | } 1498 | Collections.sort(set); 1499 | for (String str : set) { 1500 | System.out.println(str); 1501 | } 1502 | } 1503 | 1504 | /** 1505 | * 将一个英文语句以单词为单位逆序排放。例如“I am a boy”,逆序排放后为“boy a am I” 1506 | * 所有单词之间用一个空格隔开,语句中除了英文字母外,不再包含其他字符 1507 | */ 1508 | private static void reverseSentence() { 1509 | Scanner sc = new Scanner(System.in); 1510 | String sentence = sc.nextLine(); 1511 | 1512 | String[] s = sentence.split("\\s+"); 1513 | StringBuffer buffer = new StringBuffer(); 1514 | for (int i = s.length - 1; i >= 0; i--) { 1515 | buffer.append(s[i] + " "); 1516 | } 1517 | System.out.println(buffer.toString()); 1518 | } 1519 | 1520 | /** 1521 | * 程序不考虑负数的情况,若数字含有0,则逆序形式也含有0,如输入为100,则输出为001 1522 | */ 1523 | private static void convert() { 1524 | Scanner sc = new Scanner(System.in); 1525 | String string = sc.nextLine(); 1526 | for (int i = string.length() - 1; i >= 0; i--) { 1527 | System.out.print(string.charAt(i)); 1528 | } 1529 | } 1530 | 1531 | /** 1532 | * 编写一个函数,计算字符串中含有的不同字符的个数。字符在ACSII码范围内(0~127), 1533 | * 换行表示结束符,不算在字符里。不在范围内的不作统计。多个相同的字符只计算一次 1534 | * 例如,对于字符串abaca而言,有a、b、c三种不同的字符,因此输出3。 1535 | */ 1536 | private static void countWords() { 1537 | Scanner scanner = new Scanner(System.in); 1538 | String string = scanner.next(); 1539 | 1540 | int count = 0; 1541 | String[] arr = new String[128]; 1542 | for (int i = 0; i < string.length(); i++) { 1543 | int ch = string.charAt(i); 1544 | if (string.charAt(i) > 0 && string.charAt(i) < 127 && arr[ch] != "1") { 1545 | //若是ASCII码范围内的字符,arr中1表示已计数过 1546 | count++; 1547 | arr[ch] = "1"; 1548 | } 1549 | } 1550 | System.out.println(count); 1551 | } 1552 | 1553 | private static void reverseSort() { 1554 | /** 1555 | * 输入一个int型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。 1556 | 保证输入的整数最后一位不是0。 1557 | */ 1558 | try { 1559 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 1560 | String str = reader.readLine(); 1561 | StringBuilder builder = new StringBuilder(); 1562 | int[] count = new int[10]; 1563 | for (int i = str.length() - 1; i >= 0; i--) { 1564 | if (count[Integer.parseInt(str.substring(str.length() - 1))] == 0) { 1565 | builder.append(Integer.parseInt(str.substring(str.length() - 1))); 1566 | count[Integer.parseInt(str.substring(str.length() - 1))]++; 1567 | } 1568 | str = str.substring(0, str.length() - 1); 1569 | } 1570 | System.out.println(builder.toString()); 1571 | } catch (IOException e) { 1572 | e.printStackTrace(); 1573 | } 1574 | } 1575 | 1576 | /** 1577 | * 数据表记录包含表索引和数值(int范围的正整数),请对表索引相同的记录进行合并, 1578 | * 即将相同索引的数值进行求和运算,输出按照key值升序进行输出。 1579 | */ 1580 | private static void keyAndValue() { 1581 | try { 1582 | BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 1583 | int i = Integer.parseInt(in.readLine()); 1584 | Map tm = new TreeMap<>(); 1585 | for (int j = 0; j < i; j++) { 1586 | String s = in.readLine(); 1587 | String[] str = s.split("\\s+"); 1588 | int key = Integer.parseInt(str[0]); 1589 | int value = tm.containsKey(key) ? Integer.parseInt(str[1]) + tm.get(key) : Integer.parseInt(str[1]); 1590 | tm.put(key, value); 1591 | } 1592 | for (Integer k : tm.keySet()) { 1593 | System.out.println(k + " " + tm.get(k)); 1594 | } 1595 | } catch (IOException e) { 1596 | e.printStackTrace(); 1597 | } 1598 | } 1599 | 1600 | private static void addAndSub() { 1601 | /** 1602 | * 写出一个程序,接受一个正浮点数值,输出该数值的近似整数值。 1603 | * 如果小数点后数值大于等于5,向上取整;小于5,则向下取整。 1604 | */ 1605 | Scanner scanner = new Scanner(System.in); 1606 | double number = scanner.nextDouble(); 1607 | int i = (int) (number); 1608 | System.out.println((number - i) >= 0.5 ? i + 1 : i); 1609 | } 1610 | 1611 | /** 1612 | * 输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举) 1613 | * (如180的质因子为2 2 3 3 5 ) 1614 | */ 1615 | private static void divNumber() { 1616 | Scanner scanner = new Scanner(System.in); 1617 | StringBuilder sbBuilder = new StringBuilder(); 1618 | 1619 | long num = scanner.nextLong(); 1620 | 1621 | long t = num; 1622 | for (int i = 2; i <= t; i++) { 1623 | while (num % i == 0) { 1624 | num = num / i; 1625 | sbBuilder.append(i); 1626 | sbBuilder.append(" "); 1627 | } 1628 | } 1629 | System.out.println(sbBuilder.toString()); 1630 | } 1631 | 1632 | /** 1633 | * 16进制转10进制 1634 | */ 1635 | private static void transNum() { 1636 | Scanner sc = new Scanner(System.in); 1637 | while (sc.hasNext()) { 1638 | String str = sc.next().substring(2); 1639 | System.out.println(Integer.parseInt(str, 16)); 1640 | } 1641 | } 1642 | 1643 | private static void splitString() { 1644 | /** 1645 | * •连续输入字符串,请按长度为8拆分每个字符串后输出到新的字符串数组; 1646 | •长度不是8整数倍的字符串请在后面补数字0,空字符串不处理。 1647 | */ 1648 | Scanner scanner = new Scanner(System.in); 1649 | while (scanner.hasNext()) { 1650 | String st = scanner.nextLine(); 1651 | while (st.length() >= 8) { 1652 | System.out.println(st.substring(0, 8)); 1653 | st = st.substring(8); 1654 | } 1655 | if (st.length() < 8 && st.length() > 0) { 1656 | st = st + "00000000"; 1657 | System.out.println(st.substring(0, 8)); 1658 | } 1659 | 1660 | System.out.println(st); 1661 | } 1662 | } 1663 | 1664 | 1665 | /** 1666 | * 字符串最后一个单词的长度s 1667 | */ 1668 | private static void lastWordLength() { 1669 | Scanner scanner = new Scanner(System.in); 1670 | String st = scanner.nextLine(); 1671 | String[] arr = st.split("\\s+"); 1672 | 1673 | int n = arr[arr.length - 1].length(); 1674 | System.out.println(n); 1675 | } 1676 | } 1677 | 1678 | --------------------------------------------------------------------------------