最近有一個需求是這樣的,
根據(jù)鍵值對存儲類型數(shù)據(jù),也算是數(shù)據(jù)緩存塊模塊功能設(shè)計。
一個鍵對應(yīng)多個值。每一個鍵的值類型相同,但是每個不同的鍵之間類型不一定相同。
Java 設(shè)計如下
HashMap<String, ArrayList<Object>>
java把數(shù)據(jù)添加到集合中
TestIterator tIterator = new TestIterator();        ArrayList<Object> objs = new ArrayList<>();        objs.add("sdfsfdsfdsf");        objs.add("sdfsfdsfdsf");        objs.add("sdfsfdsfdsf");        objs.add("sdfsfdsfdsf");        tIterator.getList().put("Key1", objs);        objs = new ArrayList<>();        objs.add(1);        objs.add(2);        objs.add(3);        objs.add(4);        tIterator.getList().put("Key2", objs);        objs = new ArrayList<>();        objs.add(new String[]{"1", ""});        objs.add(new String[]{"2", ""});        objs.add(new String[]{"3", ""});        objs.add(new String[]{"4", ""});        tIterator.getList().put("Key3", objs);添加進(jìn)數(shù)據(jù)緩存后,然后讀取數(shù)據(jù),我們先忽略,緩存集合的線程安全性問題,
{            ArrayList<Object> getObjs = tIterator.getList().get("Key1");            for (Object getObj : getObjs) {                System.out.我們發(fā)現(xiàn)。使用的時候,每個地方都需要轉(zhuǎn)換。
(String[]) getObj;(int) getObj(String) getObj
同樣代碼需要重復(fù)寫,那么我們是否可以封裝一次呢?
public <T> ArrayList<T> getValue(String keyString, Class<T> t) {        ArrayList<T> rets = new ArrayList<>();        ArrayList<Object> getObjs = _List.get(keyString);        if (getObjs != null) {            for (Object getObj : getObjs) {                //if (getObj instanceof T) {                rets.add((T) getObj);                //}            }        }        return rets;    }這里我發(fā)現(xiàn)一個問題,不支持泛型檢查,據(jù)我很淺的知識了解到,java算是動態(tài)類型數(shù)據(jù)。
并且是偽泛型類型所以不支持泛型類型判定

這點很不爽了,為啥不能泛型類型判定。也許是我知識淺薄~!望前輩指點;
再次查看調(diào)用
{            ArrayList<String> value = tIterator.getValue("Key1", String.class);            for (String value1 : value) {            }        }        {            ArrayList<Integer> value = tIterator.getValue("Key1", Integer.class);            for (Integer value1 : value) {            }        }        {            ArrayList<String[]> value = tIterator.getValue("Key1", String[].class);            for (String[] value1 : value) {            }        }稍稍覺得清爽了一點吧。當(dāng)然,我這里都是用到基礎(chǔ)類型,如果用到復(fù)雜類型,和滿篇調(diào)用的時候才能體現(xiàn)出這段代碼的優(yōu)越性。
更加的符合面向?qū)ο缶幊痰闹貥?gòu)行和復(fù)用性;
可是上面代碼,不曉得大家注意沒,出現(xiàn)一個問題,那就是每一次調(diào)用都再一次的聲明了
ArrayList<T> rets = new ArrayList<>();
對象,如果是需要考慮性能問題的時候,我們肯定不能不能這樣。每次調(diào)用都需要重新分配ArrayList的內(nèi)存空間。并且在 ArrayList.add() 的時候每一次都在檢查ArrayList的空間夠不夠,不夠,再次開辟新空間。重組。
雖然這個動作很快,可是如果我們緩存的數(shù)據(jù)過多。那么情況可就不一樣了。且伴隨著每一次的調(diào)用都是一個消耗。訪問次數(shù)過多的話。那么程序的的性能勢必會變的低下。
再次考慮,是否可以用迭代器實現(xiàn)功能呢?
查看了一下迭代器實現(xiàn)方式,我無法完成我需求的迭代器功能。只能依葫蘆畫瓢,實現(xiàn)了一個自定義的迭代器功能。
class TestIterator {    HashMap<String, ArrayList<Object>> _List = new HashMap<>();    public TestIterator() {    }    public <T> ArrayList<T> getValue(String keyString, Class<T> t) {        ArrayList<T> rets = new ArrayList<>();        ArrayList<Object> getObjs = _List.get(keyString);        if (getObjs != null) {            for (Object getObj : getObjs) {                //if (getObj instanceof T) {                rets.add((T) getObj);                //}            }        }        return rets;    }    public HashMap<String, ArrayList<Object>> getList() {        return _List;    }    public void setList(HashMap<String, ArrayList<Object>> _List) {        this._List = _List;    }    public <T> TestIterator.ArrayIterator<T> iterator(String keyString, Class<T> t) {        return new ArrayIterator<T>(keyString);    }    public class ArrayIterator<T> {        private String key;        int index = -1;        private T content;        public ArrayIterator(String key) {            this.key = key;        }        public void reset() {            index = -1;        }        public T getContent() {            //忽略是否存在鍵的問題            Object get = TestIterator.this._List.get(key).get(index);            return (T) get;        }        public boolean next() {            //忽略是否存在鍵的問題            if (index >= TestIterator.this._List.get(key).size()) {                reset();                return false;            }            index++;            return true;        }    }}調(diào)用方式
        {            TestIterator.ArrayIterator<String> iterator1 = tIterator.iterator("Key1", String.class);            while (iterator1.next()) {                String content = iterator1.getContent();            }        }        {            TestIterator.ArrayIterator<Integer> iterator1 = tIterator.iterator("Key2", Integer.class);            while (iterator1.next()) {                Integer content = iterator1.getContent();            }        }        {            TestIterator.ArrayIterator<String[]> iterator = tIterator.iterator("Key3", String[].class);            while (iterator.next()) {                String[] content = iterator.getContent();            }        }總結(jié)了一些問題,
Java的泛型是偽泛型,底層其實都是通過object對象,裝箱拆箱完成的。
 /**     * Shared empty array instance used for empty instances.     */    private static final Object[] EMPTY_ELEMENTDATA = {};    /**     * Shared empty array instance used for default sized empty instances. We     * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when     * first element is added.     */    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};    /**     * The array buffer into which the elements of the ArrayList are stored.     * The capacity of the ArrayList is the length of this array buffer. Any     * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA     * will be expanded to DEFAULT_CAPACITY when the first element is added.     */    transient Object[] elementData; // non-private to simplify nested class access這個從我目前代碼設(shè)計思路我能理解。如果讓我自己設(shè)計。也行也會設(shè)計如此。
但是無法理解為什么使用泛型無法類型判定;
我這個自定義的迭代器無法使用 for each 功能;
說了這么多。接下來我們看看.net;
C# 設(shè)計如下
Dictionary<String, List<Object>>
TestIterator tIterator = new TestIterator();            List<Object> objs = new List<Object>();            objs.Add("sdfsfdsfdsf");            objs.Add("sdfsfdsfdsf");            objs.Add("sdfsfdsfdsf");            objs.Add("sdfsfdsfdsf");            tIterator["Key1"] = objs;            objs = new List<Object>();            objs.Add(1);            objs.Add(2);            objs.Add(3);            objs.Add(4);            tIterator["Key2"] = objs;            objs = new List<Object>();            objs.Add(new String[] { "1", "" });            objs.Add(new String[] { "2", "" });            objs.Add(new String[] { "3", "" });            objs.Add(new String[] { "4", "" });            tIterator["Key3"] = objs;由于有了以上 Java 部分的代碼和思路,那么我們直接創(chuàng)建自定義迭代器就可以了;
 public class TestIterator : Dictionary<String, List<Object>>    {        public IEnumerable<T> CreateEnumerator<T>(String name)        {            if (this.ContainsKey(name))            {                List<Object> items = this[name];                foreach (var item in items)                {                    if (item is T)                    {                        Console.WriteLine(item);                        yield return (T)item;
新聞熱點
疑難解答