# Java核心基础

# 一、基础知识

# 1.2 Java创建对象

  • 方式一 new Student s = new Student();
  • 方式二 反射
Student s = (Student) Student.forName("com.demo.Student").newInstance();
Student s = Student.class.newInstance();
1
2
  • 方式三 反射,利用构造器
public class Student {
    private Integer id;
    public Student(Integer id) {
        this.id = id;
    }
    public static void main(String[] args) throws Exception {
        // 首先得到要实例化类的构造器(有参)
        Constructor<Student> constructor = Student.class.getConstructor(Integer.class);
    	Student s = constructor.newInstance(12);
    }
}
1
2
3
4
5
6
7
8
9
10
11
  • 方式四 Clone (不会调用任何构造函数)
public class Student implements Cloneable {
    private Integer id;
    public Student(Integer id) {
        this.id = id;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
    public static void main(String[] args) throws Exception {
        Constructor<Student> constructor = Student.class.getConstructor(Integer.class);
        Student stu3 = constructor.newInstance(13);
        Student stu4 = (Student) stu3.clone();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  • 方式五 ((反)序列化机制)(不会调用构造函数)

序列化:

在程序运行过程中,所有的变量都是在内存中,当程序运行结束的时候,变量所占用的内存会被操作系统全部回收。这样变量如果需要存储或者传输的话,我们就会使用到序列化。

  1. 序列化:把对象转化为字节序列的过程

  2. 反序列化:把字节序列恢复到对象的过程

public class Student implements Serializable {
    private static final long serialVersionUID = 1L;

     private String name;
     /** transient修饰的属性不会被序列化 **/
     private transient String pwd;

     public Student() {
     }

     public Student(String name, String pwd) {
          this.name = name;
          this.pwd = pwd;
     }

     @Override
     public String toString() {
          return "Student{" +
                  "name='" + name + '\'' +
                  ", pwd='" + pwd + '\'' +
                  '}';
     }
     
    public static void main(String[] args) throws Exception {
         Student userInfo = new Student("张三", "admin123");
         System.out.println(userInfo);
        // 写对象 序列化
        ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("student.bin"));
        output.writeObject(userInfo);
        output.close();
        // 读对象 反序列化
        ObjectInputStream input = new ObjectInputStream(new FileInputStream("student.bin"));
        Student stu5 = (Student) input.readObject();
        input.close();
        System.out.println(stu5);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

# 1.3 字符串String相关

  1. String,StringBuffer,StringBuilder,都是final修饰的类,都不能被继承
  2. String private final char value[]; 所以每次用String都需要在堆上创建对象
  3. StringBuffer, StringBuilder char[] value;
  4. 效率: StringBuilder > StringBuffer > String
  5. 线城安全性:StringBuffer线城安全

# 二、算法

# 一、深度优先搜索(Depth-First Search,DFS)

当我们深入到叶结点时回溯,这就被称为 DFS 算法。

让我们分解一下:

  1. 从根结点(1)开始。输出
  2. 进入左结点(2)。输出
  3. 然后进入左孩子(3)。输出
  4. 回溯,并进入右孩子(4)。输出
  5. 回溯到根结点,然后进入其右孩子(5)。输出
  6. 进入左孩子(6)。输出
  7. 回溯,并进入右孩子(7)。输出
  8. 完成

# 1. 前序遍历

输出结果为: 1–2–3–4–5–6–7

这和我们在上述示例中的作法基本类似。

  1. 输出节点的值
  2. 进入其左结点并输出。当且仅当它拥有左结点。
  3. 进入右结点并输出之。当且仅当它拥有右结点
    /** 深度优先搜索(Depth-First Search,DFS)--前序遍历 **/
    public static void preOrder(BinaryTree node) {
        if (null != node) {
            System.out.println(node.data);
            if (null != node.left) {
                node.left.preOrder(node.left);
            }
            if (null != node.right) {
                node.right.preOrder(node.right);
            }
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12

# 2. 中序遍历

输出结果3–2–4–1–6–5–7

左结点优先,之后是中间,最后是右结点。

  1. 进入左结点并输出之。当且仅当它有左结点。
  2. 输出根结点的值。
  3. 进入结节点并输出之。当且仅当它有结节点。
    /** 深度优先搜索(Depth-First Search,DFS)--中序遍历 **/
    public static void inOrder(BinaryTree node) {
        if (null != node) {
            if (null != node.left) {
                node.left.inOrder(node.left);
            }
            System.out.println(node.data);
            if (null != node.right) {
                node.right.inOrder(node.right);
            }
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12

# 2. 后序遍历

输出结果3–4–2–6–7–5–1

左结点优先,之后是右结点,根结点的最后。

  1. 进入左结点输出,
  2. 进入右结点输出
  3. 输出根结点
    /** 深度优先搜索(Depth-First Search,DFS)--后序遍历 **/
    public static void postOrder(BinaryTree node) {
        if (null != node) {
            if (null != node.left) {
                node.left.postOrder(node.left);
            }
            if (node.right != null) {
                node.right.postOrder(node.right);
            }
            System.out.println(node.data);
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12

参考博客:https://blog.csdn.net/dandandeshangni/article/details/79972501 (opens new window)

package com.list2tree.tree;

import lombok.Data;

@Data
public class BinaryTree {

    /** 树的内容 **/
    protected String data;

    protected BinaryTree left;

    protected BinaryTree right;

    public BinaryTree() {
    }

    public BinaryTree(String data, BinaryTree left, BinaryTree right) {
        this.data = data;
        this.left = left;
        this.right = right;
    }

    public BinaryTree(String data) {
        this(data, null, null);
    }

    /** 插入节点 ,如果当前的节点没有左节点,我们就创建一个新节点,然后将其设置为当前节点的左节点。 **/
    public static void insertLeft(BinaryTree node, String value) {
        if (null != node) {
            if (null == node.left) {
                node.setLeft(new BinaryTree(value));
            } else {
                BinaryTree newNode = new BinaryTree(value);
                newNode.left = node.left;
                node.left = newNode;
            }
        }
    }

    /** 插入节点 ,如果当前的节点没有右节点,我们就创建一个新节点,然后将其设置为当前节点的右节点。 **/
    public static void insertRight(BinaryTree node, String value) {
        if (null != node) {
            if (node.right == null) {
                node.setRight(new BinaryTree(value));
            } else {
                BinaryTree newNode = new BinaryTree(value);
                newNode.right = node.right;
                node.right = newNode;
            }
        }
    }

    /** 深度优先搜索(Depth-First Search,DFS)--前序遍历 **/
    public static void preOrder(BinaryTree node) {
        if (null != node) {
            System.out.println(node.data);
            if (null != node.left) {
                node.left.preOrder(node.left);
            }
            if (null != node.right) {
                node.right.preOrder(node.right);
            }
        }
    }

    /** 深度优先搜索(Depth-First Search,DFS)--中序遍历 **/
    public static void inOrder(BinaryTree node) {
        if (null != node) {
            if (null != node.left) {
                node.left.inOrder(node.left);
            }
            System.out.println(node.data);
            if (null != node.right) {
                node.right.inOrder(node.right);
            }
        }
    }

    /** 深度优先搜索(Depth-First Search,DFS)--后序遍历 **/
    public static void postOrder(BinaryTree node) {
        if (null != node) {
            if (null != node.left) {
                node.left.postOrder(node.left);
            }
            if (node.right != null) {
                node.right.postOrder(node.right);
            }
            System.out.println(node.data);
        }
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

# 其他

# 1 读取配置文件properties

static {
    Properties prop = new Properties();
    try {
        prop.load(JDBCUtil.class.getResourceAsStream("conninfo.properties"))
        String driver = prop.getProperty("driver");
        String url = prop.getProperty("url");
        String username = prop.getProperty("username");
        String password = prop.getProperty("password");
        
        //注册驱动
        Class.forName(driver);
    } catch(Exception e) {
        e.printStackTrace();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 2 Java对象根据某属性去重

List<MenuInfo> menuInfos;

//定义一个空map,用来装去重后的数据
Map<String, MenuInfo> map = new HashMap<>();

for(MenuInfo menu : menuInfos) {
    if(!map.containsKey(menu.getId())) {
        map.put(menu.getId(), menu);
    }
}
1
2
3
4
5
6
7
8
9
10

# 3 发送Http请求

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

import javax.net.ssl.HttpsURLConnection;

import org.springframework.web.bind.annotation.RequestMethod;

import com.springtour.app.util.StringUtil;

import oracle.net.aso.i;

/**
 * HTTP传输工具类
 * @author gusaishuai
 * @since 2013-10-10
 * <p>Copyright © Spring Airlines;Spring Travel.All rights reserved.
 */
public class HttpUtil {

	/**
	 * JSON通过HTTP传输
	 */
	public static String urlJSONRequest(String json, String address) {
		try {
			URL url = new URL(address);
			if (address.toLowerCase().contains("https")) {
				HTTPSTrustManager.allowAllSSL();
			}
			HttpURLConnection con = (HttpURLConnection) url.openConnection();
			
			con.setRequestMethod(RequestMethod.POST.name());
			con.setUseCaches(false);
			con.setDoInput(true);
			con.setDoOutput(true);
			//5000是connectTimeout,30000是readTimeout
			con.setConnectTimeout(5000);
			con.setReadTimeout(30000);
			con.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
			con.connect();
			BufferedWriter out = new BufferedWriter(
					new OutputStreamWriter(con.getOutputStream(), "UTF-8"));
			out.write(json);
			out.flush();
			out.close();
			BufferedReader in = new BufferedReader(
					new InputStreamReader(con.getInputStream(), "UTF-8"));
			StringBuilder sb = new StringBuilder();
			String line = null;
			while (!StringUtil.isEmpty(line = in.readLine())) {
				sb.append(line);
			}
			in.close();
			return sb.toString();
		} catch (Exception e) {
			LogUtil.logError("HTTP-POST请求传输JSON", "", e, "JSON:" + json + ",ADDRESS:" + address);
			return "";
		}
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

不区分大小写的Map LinkedCaseInsensitiveMap

@WebFilter(filterName = "caseInsensitiveFilter", urlPatterns = "/*")
public class CaseInsensitiveRequestParameterNameFilter extends OncePerRequestFilter {

    public CaseInsensitiveRequestParameterNameFilter() {
        System.out.println("CaseInsensitiveRequestParameterNameFilter.CaseInsensitiveRequestParameterNameFilter()");
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        filterChain.doFilter(new CaseInsensitiveParameterNameHttpServletRequest(request), response);
    }

    public static class CaseInsensitiveParameterNameHttpServletRequest extends HttpServletRequestWrapper {
        private final LinkedCaseInsensitiveMap<String[]> map = new LinkedCaseInsensitiveMap<>();

        public CaseInsensitiveParameterNameHttpServletRequest(HttpServletRequest request) {
            super(request);
            map.putAll(request.getParameterMap());
        }

        @Override
        public String getParameter(String name) {

            String[] array = this.map.get(name);
            if (array != null && array.length > 0) {
                return array[0];
            }
            return null;
        }

        @Override
        public Map<String, String[]> getParameterMap() {
            return Collections.unmodifiableMap(this.map);
        }

        @Override
        public Enumeration<String> getParameterNames() {
            return Collections.enumeration(this.map.keySet());
        }

        @Override
        public String[] getParameterValues(String name) {
            return this.map.get(name);
        }

    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49