public class LinkedListNode
{
public object Value { get; private set; }
public LinkedListNode(object value)
{
Value = value;
}
public LinkedListNode Prev { get; internal set; }
public LinkedListNode Next { get; internal set; }
}
public class LinkedList : IEnumerable
{
public LinkedListNode First { get; private set; }
public LinkedListNode Last { get; private set; }
//在链表尾部添加一个新元素
public LinkedListNode AddLast(object node)
{
var newNode = new LinkedListNode(node);
if (First == null)
{
First = newNode;
Last = First;
}
else
{
LinkedListNode previous = Last;
Last.Next = newNode;
Last = newNode;
Last.Prev = previous;
}
return newNode;
}
//实现GetEnumerator()方法
public IEnumerator GetEnumerator()
{
LinkedListNode current = First;
while (current != null)
{
//使用yield语句创建一个枚举器类型
yield return current.Value;
current = current.Next;
}
}
}
var list1 = new LinkedList();
list1.AddLast(2);
list1.AddLast(3);
list1.AddLast("4");
foreach (var i in list1)
{
Console.WriteLine(i);
}
使用泛型定义上述类
public class LinkedListNode
{
public LinkedListNode(T value)
{
Value = value;
}
public LinkedListNode Next { get; internal set; }
public LinkedListNode Prev { get; internal set; }
public T Value { get; private set; }
}
public class LinkedList : IEnumerable
{
public LinkedListNode First { get; private set; }
public LinkedListNode Last { get; private set; }
public LinkedListNode AddLast(T node)
{
var newNode = new LinkedListNode(node);
if (First == null)
{
First = newNode;
Last = First;
}
else
{
LinkedListNode previous = Last;
Last.Next = newNode;
Last = newNode;
Last.Prev = previous;
}
return newNode;
}
public IEnumerator GetEnumerator()
{
LinkedListNode current = First;
while (current != null)
{
yield return current.Value;
current = current.Next;
}
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
var list2 = new LinkedList();
list2.AddLast("java");
list2.AddLast("c#");
list2.AddLast("python");
foreach (string i in list2)
{
Console.WriteLine(i);
}
泛型类功能
在创建泛型类时,可以为泛型类型指定默认值、约束、继承和静态成员等。
创建如下一个简单泛型类 ,用于从队列中读写文档。
public class DocumentManager
{
private readonly Queue documentQueue = new Queue();
public bool IsDocumentAvailable => documentQueue.Count > 0;
public void AddDocument(T doc)
{
lock (this)
{
documentQueue.Enqueue(doc);
}
}
}
//定义一个简单的接口
public interface IDocument
{
string Title { get; set; }
string Content { get; set; }
}
//实现该接口
public class Document : IDocument
{
public Document(string title, string content)
{
this.Title = title;
this.Content = content;
}
public string Content { get; set; }
public string Title { get; set; }
}
泛型类型默认值
在上述类DocumentManager中添加如下方法:
public T GetDocument()
{
//default将泛型类型的值初始化为null或者0,取决于泛型类型是引用类型还是值类型。
T doc = default(T);
lock (this)
{
doc = documentQueue.Dequeue();
}
return doc;
}
public abstract class Calc
{
public abstract T Add(T x, T y);
public abstract T Sub(T x, T y);
}
public class IntCalc : Calc
{
public override int Add(int x, int y) => x + y;
public override int Sub(int x, int y) => x - y;
}
还可以创建一个部分的特殊操作,如下:
public class Query { }
public class StringQuery : Query { }
public class Shape
{
public double Width { get; set; }
public double Height { get; set; }
//重写Object的ToString方法
public override string ToString() => $"Width:{Width},Height:{Height}";
}
//定义子类Rectangle
public class Rectangle : Shape { }
泛型接口的协变
如果泛型类型使用out关键字标注,该泛型接口就是协变的。
public interface IIndex
{
//定义一个索引器
T this[int index] { get; }
int Count { get; }
}
public class RectangleCollection : IIndex
{
private Rectangle[] data = new Rectangle[3] {
new Rectangle{Height=2,Width=5},
new Rectangle{ Height=3, Width=7},
new Rectangle{ Height=4.5, Width=2.9}
};
public int Count => data.Length;
public Rectangle this[int index]
{
get
{
if (index < 0 || index > data.Length)
{
throw new ArgumentOutOfRangeException("index");
}
return data[index];
}
}
}
//静态类不能被实例化
public static class Algorithms
{
public static decimal Accumulate(IEnumerable source)
where TAccount : IAccount
{
decimal sum = 0;
foreach (TAccount a in source)
{
sum += a.Balance;
}
return sum;
}
}
调用上述方法的代码:
var accounts = new List {
new Account("书籍",234),
new Account("文具",56),
new Account("手机",2300)
};
//decimal amount = Algorithms.Accumulate(accounts);
//编译器会从方法的参数类型中自动推断出泛型类型参数,可以简化为下述代码进行调用
decimal amount = Algorithms.Accumulate(accounts);
var accounts = new List {
new Account("书籍",234),
new Account("文具",56),
new Account("手机",2300)
};
decimal amount = Algorithms.Accumulate(
accounts, //传入的参数1
(item, sum) => sum += item.Balance //传入的参数2
);
如果在使用JAXB把xml文件unmarshal成vo(XSD自动生成的vo)时碰到如下错误:
org.xml.sax.saxparseexception : premature end of file
很有可能时你直接读取文件为inputstream,然后将inputstream作为构建unmarshal需要的source参数。InputSource inputSource = new In
servlet 搞java web开发的人一定不会陌生,而且大家还会时常用到它。
下面是java官方网站上对servlet的介绍: java官网对于servlet的解释 写道
Java Servlet Technology Overview Servlets are the Java platform technology of choice for extending and enha
这两天学到事务管理这一块,结合到之前的terasoluna框架,觉得书本上讲的还是简单阿。我就把我从书本上学到的再结合实际的项目以及网上看到的一些内容,对声明式事务管理做个整理吧。我看得Spring in Action第二版中只提到了用TransactionProxyFactoryBean和<tx:advice/>,定义注释驱动这三种,我承认后两种的内容很好,很强大。但是实际的项目当中
1)nosql数据库主要由以下特点:非关系型的、分布式的、开源的、水平可扩展的。
1,处理超大量的数据
2,运行在便宜的PC服务器集群上,
3,击碎了性能瓶颈。
1)对数据高并发读写。
2)对海量数据的高效率存储和访问。
3)对数据的高扩展性和高可用性。
redis支持的类型:
Sring 类型
set name lijie
get name lijie
set na
在多节点的系统中,如何实现分布式锁机制,其中用redis来实现是很好的方法之一,我们先来看一下jedis包中,有个类名BinaryJedis,它有个方法如下:
public Long setnx(final byte[] key, final byte[] value) {
checkIsInMulti();
client.setnx(key, value);
ret