单链表和spring生命周期简图

master
kn5886348135 3 years ago
parent 6ba259614d
commit 228bd5aef9

@ -0,0 +1,326 @@
单链表反转
使用while循环保存next节点设置当前节点的next保存pre移动head最后返回pre
```Java
private static Node reverseLinkedList(Node head) {
Node pre = null;
Node next = null;
while (head != null) {
next = head.getNext();
head.setNext(pre);
pre = head;
head = next;
}
return pre;
}
```
双链表反转
使用while循环保存next节点设置当前节点的last和pre保存pre移动head最后返回pre
```Java
private static Node reverDoubleLinkedList(Node head) {
Node pre = null;
Node next = null;
while (head != null) {
next = head.getLast();
head.setLast(pre);
head.setPre(next);
pre = head;
head = next;
}
return pre;
}
```
单链表实现队列和栈
```Java
public class CustomQueue<V> {
private Node<V> head;
private Node<V> tail;
private int size;
public boolean isEmpty(){
return size == 0;
}
public void offer(V value) {
Node<V> node = new Node<>(value);
if (tail == null) {
head = node;
tail = node;
} else {
tail.setNext(node);
tail = node;
}
size++;
}
public V poll(){
if (head == null) {
return null;
}
V ans = head.getValue();
head = head.getNext();
size--;
return ans;
}
public V peek() {
if (head == null) {
return null;
}
return head.getValue();
}
private class Node<V> {
private V value;
private Node<V> next;
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
public Node<V> getNext() {
return next;
}
public void setNext(Node<V> next) {
this.next = next;
}
public Node(V value) {
this.value = value;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Node<?> node = (Node<?>) o;
return value.equals(node.value) &&
next.equals(node.next);
}
@Override
public int hashCode() {
return Objects.hash(value, next);
}
}
}
```
```Java
public class CustomStack<V> {
private Node<V> head;
private int size;
public boolean isEmpty(){
return size == 0;
}
public void push(V value){
Node<V> node = new Node<>(value);
if (head == null) {
head = node;
} else {
node.setNext(head);
head = node;
}
size++;
}
public V pop(){
if (head == null) {
return null;
}
V ans = null;
ans = head.getValue();
head.setNext(head.getNext());
size--;
return ans;
}
public V peek() {
return head == null ? null : head.getValue();
}
class Node<V>{
private V value;
private Node<V> next;
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
public Node<V> getNext() {
return next;
}
public void setNext(Node<V> next) {
this.next = next;
}
public Node(V value) {
this.value = value;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Node<?> node = (Node<?>) o;
return Objects.equals(value, node.value) &&
Objects.equals(next, node.next);
}
@Override
public int hashCode() {
return Objects.hash(value, next);
}
}
}
```
### 使用双链表实现双端队列
```Java
public class CustomDeque<V> {
private Node<V> head;
private Node<V> tail;
private int size;
public boolean isEmpty() {
return size == 0;
}
public void pushHead(V value){
Node<V> node = new Node<>(value);
if (head == null) {
head = node;
tail = node;
} else {
node.setLast(head);
head.setPre(node);
head = node;
}
size++;
}
public void pushTail(V value){
Node<V> node = new Node<>(value);
if (head == null) {
head = node;
tail = node;
} else {
tail.setLast(node);
node.setPre(tail);
tail = node;
}
size++;
}
public V pollHead(){
if (head == null) {
return null;
}
V ans = head.getValue();
if (head.equals(tail)) {
head = null;
tail = null;
} else {
head = head.getLast();
head.setPre(null);
}
size--;
return ans;
}
public V pollTail(){
if (tail == null) {
return null;
}
V ans = tail.getValue();
if (head.equals(tail)) {
head = null;
tail = null;
} else {
tail = tail.getPre();
tail.setLast(null);
}
size--;
return ans;
}
public V peekHead(){
return head == null ? null : head.getValue();
}
public V peekTail(){
return tail == null ? null : tail.getValue();
}
class Node<V>{
private V value;
private Node<V> last;
private Node<V> pre;
public Node(V value) {
this.value = value;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
public Node<V> getLast() {
return last;
}
public void setLast(Node<V> last) {
this.last = last;
}
public Node<V> getPre() {
return pre;
}
public void setPre(Node<V> pre) {
this.pre = pre;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Node<?> node = (Node<?>) o;
return Objects.equals(value, node.value);
}
@Override
public int hashCode() {
return Objects.hash(value);
}
}
}
```
单链表和双链表的新增、删除,主要注意处理好前驱和后继指针,必要的时候添加中间变量保存。双链表注意处理头尾重合、为空的边界条件。
K个节点的组内逆序调整

@ -76,4 +76,43 @@ private static int binarySearchRight(int[] arr, int target) {
} }
``` ```
有序数组给定区间元素的个数 有序数组给定区间元素的个数二分查找上下限然后index取差值。
局部最小值
对无重复元素的无序数组,找出一个局部最小值。
只需要找出一个存在的局部最小值,不是全部的局部最小值,也不是全局最小值。
```Java
public int localMin(int[] arr){
if (arr == null || arr.length == 0) {
return -1;
}
int length = arr.length;
if (length == 1) {
return 0;
}
if (arr[length - 1] < arr[length - 2]) {
return length - 1;
}
int left = 0;
int right = length - 1;
int index = -1;
int middle;
while (left <= right) {
middle = (left + right) >> 1;
if (arr[middle - 1] < arr[middle]) {
right = middle - 1;
} else if (arr[middle + 1] < arr[middle]) {
left = middle + 1;
} else {
index = middle;
break;
}
}
return index;
}
```
可以确定要寻找的元素在一侧必定存在则可以使用二分搜索。
### 时间复杂度

@ -0,0 +1,7 @@
优先选择策略模式而不是模板方法模式的场景
* 所有步骤都不同(而不是几个)
* 实现类需要独立的继承
* 实现类和其他类强相关(常见于J2EE的数据访问场景)
* 实现类需要在运行时发生变化,继承不能做到,但是代理可以<font color=red>模板方法设计模式也是在工作类中持有抽象类的引用,可以在运行时传入不同的子类实现,为什么说不能再运行时发生变化?</font>
* 有很多种不同的实现类或者实现类的数量会持续增长。在这种情况下,策略模式更大的灵活性几乎肯定会证明是有益的,因为它为实现提供了最大的自由度。

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

@ -44,9 +44,9 @@ xxbean.method();
* BeanDefinitionReader * BeanDefinitionReader
* BeanDefinition * BeanDefinition
* BeanFactory * BeanFactory
* FactoryBean
* DefaultListableBeanFactory * DefaultListableBeanFactory
* ClassPathXmlApplicationContext * ClassPathXmlApplicationContext
* PostProcessor
* BeanPostProcessor * BeanPostProcessor
* BeanFactoryPostProcessor * BeanFactoryPostProcessor
* Aware * Aware
@ -68,7 +68,7 @@ BeanDefinition描述带有属性值、构造器参数值、具体实现类的信
这个接口被持有许多bean定义的对象实现每一个对象都由字符串唯一确定。依据bean定义factory将返回一个容器化对象的独立实例(原型设计模式),或者一个单例的共享对象(单例设计模式的一个更好的替代方案该实例在factory内部是单例的)。那种类型的实例会被返回依赖于factory的配置API是相同的。从Spring2.0开始,根据具体应用上下文,更多的范围可以被使用(比如web环境中的request和session)。 这个接口被持有许多bean定义的对象实现每一个对象都由字符串唯一确定。依据bean定义factory将返回一个容器化对象的独立实例(原型设计模式),或者一个单例的共享对象(单例设计模式的一个更好的替代方案该实例在factory内部是单例的)。那种类型的实例会被返回依赖于factory的配置API是相同的。从Spring2.0开始,根据具体应用上下文,更多的范围可以被使用(比如web环境中的request和session)。
这种方法的要点是BeanFactory是应用程序组件的中央注册表并且集中了应用程序组件的配置(例如单个对象不再需要读取属性文件)。可以通过<Expert One-on-One J2EE Design and Development>的第4章和11章了解这种方式的优点。(到底是啥优点?) 这种方法的要点是BeanFactory是应用程序组件的中央注册表并且集中了应用程序组件的配置(例如单个对象不再需要读取属性文件)。可以通过&lt;Expert One-on-One J2EE Design and Development&gt;的第4章和11章了解这种方式的优点。(到底是啥优点?)
一般来讲依靠DI(push配置)通过set或者构造方法配置应用对象是比使用任何形式比如查找BeanFactory拉取配置要好的。Spring的依赖注入功能是使用BeanFactory接口和它的子接口实现的。 一般来讲依靠DI(push配置)通过set或者构造方法配置应用对象是比使用任何形式比如查找BeanFactory拉取配置要好的。Spring的依赖注入功能是使用BeanFactory接口和它的子接口实现的。
@ -95,6 +95,8 @@ BeanFactory的实现类应该尽可能支持标准的bean生命周期接口。
bean工厂关闭的时候会调用DestructionAwareBeanPostProcessors的postProcessBeforeDestruction()方法DisposableBean的destroy()方法自定义的destroy-method方法 bean工厂关闭的时候会调用DestructionAwareBeanPostProcessors的postProcessBeforeDestruction()方法DisposableBean的destroy()方法自定义的destroy-method方法
#### FactoryBean
#### DefaultListableBeanFactory #### DefaultListableBeanFactory
Spring对ConfigurableListableBeanFactory和BeanDefinitionRegistry接口的默认实现基于 bean 定义元数据的成熟的 bean 工厂,可通过后处理器进行扩展。 Spring对ConfigurableListableBeanFactory和BeanDefinitionRegistry接口的默认实现基于 bean 定义元数据的成熟的 bean 工厂,可通过后处理器进行扩展。
@ -115,8 +117,6 @@ Spring对ConfigurableListableBeanFactory和BeanDefinitionRegistry接口的默认
这是一个简单的、一站式便利的 ApplicationContext。考虑使用GenericApplicationContext类结合XmlBeanDefinitionReader进行更灵活的上下文设置。 这是一个简单的、一站式便利的 ApplicationContext。考虑使用GenericApplicationContext类结合XmlBeanDefinitionReader进行更灵活的上下文设置。
#### PostProcessor
#### BeanPostProcessor #### BeanPostProcessor
允许自定义修改新 bean 实例的工厂钩子——例如,检查标记接口或使用代理包装 bean。 允许自定义修改新 bean 实例的工厂钩子——例如,检查标记接口或使用代理包装 bean。

Loading…
Cancel
Save