配置文件
在企业开发过程中,我们习惯把一些需要灵活配置的数据放在一些文本文件中,而不是在Java代码写死 我们把这种存放程序配置信息的文件,统称为配置文件
properties
是一个Map集合(键值对集合),但是我们一般不会当集合使用。
核心作用:Properties是用来代表属性文件的,通过Properties可以读写属性文件里的内容
使用Properties读取属性文件里的键值对数据
使用Properties把键值对数据写出到属性文件里去
public class Demo1 {
public static void main(String[] args)throws IOException {
//1. 创建一个配置文件对象
Properties properties = new Properties();
properties.setProperty("name","卷王");
properties.setProperty("age","18");
properties.store(new FileWriter("E:\\Code191Day\\day10\\a-1.properties"),"卷王个人介绍");
//2. 读取
properties.load(new FileReader("E:\\Code191Day\\day10\\a-1.properties"));
System.out.println(properties.getProperty("name"));
System.out.println(properties.getProperty("age"));
Set<String> set = properties.stringPropertyNames();
for (String s : set) {
System.out.println(s + properties.getProperty(s));
}
}
}
Properties的作用?具体如何使用?
可以加载属性文件中的数据到Properties对象中来
void load(Reader reader)
public String getProperty(String key) 根据键获取值
可以存储Properties属性集的键值对数据到属性文件中去
void store(Writer writer, String comments)
public Object setProperty(String key, String value) 设置键值
XML
本质是一种数据的格式,可以用来存储复杂的数据结构,和数据关系。
XML的特点
1.XML中的“<标签名>” 称为一个标签或一个元素,一般是成对出现的。
2.XML中的标签名可以自己定义(可扩展),但必须要正确的嵌套。
3.XML中只能有一个根标签。
4.XML中的标签可以有属性。
5.如果一个文件中放置的是XML格式的数据,这个文件就是XML文件,后缀一般要写成.xml
XML的语法规则
1.XML文件的后缀名为:xml,文档声明必须是第一行
<?xml version="1.0" encoding="UTF-8" ?>
version:XML默认的版本号码、该属性是必须存在的
encoding:本XML文件的编码
2.XML中可以定义注释信息:<!–- 注释内容 -->,快捷键是Ctrl+shift+/
3.XML中书写”<”、“&”等,可能会出现冲突,导致报错,此时可以用如下特殊字符替代。
< < 小于
> > 大于
& & 和号
' ' 单引号
" " 引号
4.XML中可以写一个叫CDATA的数据区: <![CDATA[ …内容… ]]>,里面的内容可以随便写。
XML的作用和应用场景
本质是一种数据格式,可以存储复杂的数据结构,和数据关系。
应用场景:经常用来做为系统的配置文件;或者作为一种特殊的数据结构,在网络中进行传输。
XML的作用
XML的是一种可扩展的标记语言。
作用:1)作为软件的配置文件 2)用于进行存储数据和传输数据
解析XML文件
Dom4j解析XML-得到Document对象
DOM4J解析XML文件的思想:文档对象模型
<?xml version="1.0" encoding="UTF-8" ?>
<users>
<user id="1">
<name>张无忌</name>
<password>minmin</password>
<address>光明顶</address>
<gender>男</gender>
</user>
<user id="2">
<name>敏敏</name>
<password>wuji</password>
<address>光明顶</address>
<gender>女</gender>
</user>
</users>
public class Demo2 {
public static void main(String[] args) throws DocumentException {
List<User> list = new ArrayList<>();
//1.使用SAXReader读取XML,封装成Document
SAXReader saxReader = new SAXReader();
Document read = saxReader.read("E:\\Code191Day\\day10\\b-2.xml");
//获取跟节点
Element rootElement = read.getRootElement();
//获取根元素下的子元素
List<Element> elements = rootElement.elements();
//遍历集合获取每个元素
for (Element element : elements) {
String id = element.attributeValue("id");
String name = element.element("name").getText();
String password = element.element("password").getText();
String address = element.element("address").getText();
String gender = element.element("gender").getText();
User user = new User(Integer.valueOf(id),name,password,address,gender);
list.add(user);
}
list.stream().forEach(System.out::println);
}
}
Element提供的方法
约束文档
门用来限制xml书写格式的文档,比如:限制标签、属性应该怎么写。
约束文档的分类
1.DTD文档
2.Schema文档
日志技术
程序中的日志,通常就是一个文件,里面记录的是程序运行过程中的各种信息。
1.可以将系统执行的信息,方便的记录到指定的位置(控制台、文件中、数据库中)。
2.可以随时以开关的形式控制日志的启停,无需侵入到源代码中去进行修改。
Logback日志框架
想使用Logback日志框架,至少需要在项目中整合如下三个模块:
1.slf4j-api:日志接口
2.logback-core
3.logback-classic
实现步骤
public class Demo1 {
public static final Logger LOGGER = LoggerFactory.getLogger("Demo1");
public static void main(String[] args) {
LOGGER.debug("哈哈哈");
LOGGER.error("除法报错");
try {
LOGGER.warn("除数为0");
sum(10, 2);
}catch (Exception e){
LOGGER.error("除法报错");
}
}
public static int sum(int a,int b){
LOGGER.info("输入的参数:a={},b={}",a,b);
int c = a / b;
return c;
}
}
日志级别
多线程
1.单线程:在计算机中同一时间只能做一件事
2.多线程:在计算机中同一时间可以做多件事
public class Demo1 {
public static final Logger logger = LoggerFactory.getLogger("Demo1");
public static void main(String[] args) {
//需求:创建两个线程,分别用于打印10个A和10个B,最后观察下输出顺序
new Thread(){
@Override
public void run() {
Thread.currentThread().setName("卷王线程");
for (int i = 0; i < 10; i++) {
logger.info(Thread.currentThread().getName() + i);
}
}
}.start();
new Thread(){
@Override
public void run() {
Thread.currentThread().setName("阿giao线程");
for (int i = 0; i < 10; i++) {
logger.info( Thread.currentThread().getName() + i);
}
}
}.start();
}
}
线程的创建方式
方式一继承Thread类
1.定义一个子类继承线程类java.lang.Thread,
2.重写run()方法 创建子类的对象
3.调用子类对象的start()方法启动线程(底层会自动去执行run方法)
public class Demo1 {
public static final Logger logger = LoggerFactory.getLogger("Demo1");
public static void main(String[] args) {
//需求:创建两个线程,分别用于打印10个A和10个B,最后观察下输出顺序
new Thread(){
@Override
public void run() {
Thread.currentThread().setName("卷王线程");
for (int i = 0; i < 10; i++) {
logger.info(Thread.currentThread().getName() + i);
}
}
}.start();
new Thread(){
@Override
public void run() {
Thread.currentThread().setName("阿giao线程");
for (int i = 0; i < 10; i++) {
logger.info( Thread.currentThread().getName() + i);
}
}
}.start();
}
}
多线程的创建方式二:实现Runnable接口
public class Demo1 {
public static final Logger logger = LoggerFactory.getLogger("Demo1");
public static void main(String[] args) {
//需求:创建两个线程,分别用于打印10个A和10个B,最后观察下输出顺序
new Thread(() -> {
for (int i = 0; i < 10; i++) {
logger.info("Agiao = {}", i);
}
},"Agiao"){
}.start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
logger.info("展丫鹏 = {}" , i);
}
},"展丫鹏"){
}.start();
}
}
多线程的第三种创建方式:利用Callable接口、FutureTask类来实现
public class Demo1 {
public static final Logger logger = LoggerFactory.getLogger("Demo1");
public static void main(String[] args) throws ExecutionException, InterruptedException {
//需求:启动两个子线程,分别计算100之内的奇数的和和偶数的和,然后在主线程中再做个汇总,得到总和
//2.创建任务类对象
OddCallable oddCallable = new OddCallable();
EvenCallable evenCallable = new EvenCallable();
//3.创建未来任务的对象,可以获取线程执行的结果
FutureTask<Integer> integerFutureTask1 = new FutureTask<>(oddCallable);
FutureTask<Integer> integerFutureTask2 = new FutureTask<>(evenCallable);
//4.创建线程类
Thread thread1 = new Thread(integerFutureTask1,"计算奇数");
Thread thread2 = new Thread(integerFutureTask2,"计算偶数");
//5.启动线程
thread1.start();
thread2.start();
//6.从FutureTask对象中获取线程执行结果
//假设结果还没有算出来,线程会在此等待
Integer oddSum = integerFutureTask1.get();
Integer evenSum = integerFutureTask2.get();
logger.info("{}",oddSum + evenSum);
}
}
class OddCallable implements Callable<Integer>{
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 1; i <= 100; i+=2) {
sum += i;
}
return sum;
}
}
class EvenCallable implements Callable<Integer>{
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i <= 100; i+=2) {
sum += i;
}
return sum;
}
}
请对对比说一下三种线程的创建方式,和不同点?