分享
 
 
 

和 .Net 迭代器功能

王朝学院·作者佚名  2016-05-20
窄屏简体版  字體: |||超大  

初来乍到 java 和 .Net 迭代器功能最近有一个需求是这样的,

根据键值对存储类型数据,也算是数据缓存块模块功能设计。

一个键对应多个值。每一个键的值类型相同,但是每个不同的键之间类型不一定相同。

Java 设计如下

HashMap<String, ArrayList<Object>>

java把数据添加到集合中

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);

添加进数据缓存后,然后读取数据,我们先忽略,缓存集合的线程安全性问题,

{ ArrayList<Object> getObjs = tIterator.getList().get("Key1"); for (Object getObj : getObjs) { System.out.PRintln("My is String:" + (String) getObj); } } { ArrayList<Object> getObjs = tIterator.getList().get("Key2"); for (Object getObj : getObjs) { System.out.println("My is int:" + (int) getObj); } } { ArrayList<Object> getObjs = tIterator.getList().get("Key3"); for (Object getObj : getObjs) { String[] strs = (String[]) getObj; System.out.println("My is String[]:" + strs[0] + " : " + strs[1]); } }

我们发现。使用的时候,每个地方都需要转换。

(String[]) getObj;(int) getObj(String) getObj

同样代码需要重复写,那么我们是否可以封装一次呢?

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; }

这里我发现一个问题,不支持泛型检查,据我很浅的知识了解到,java算是动态类型数据。

并且是伪泛型类型所以不支持泛型类型判定

这点很不爽了,为啥不能泛型类型判定。也许是我知识浅薄~!望前辈指点;

再次查看调用

{ 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) { } }

稍稍觉得清爽了一点吧。当然,我这里都是用到基础类型,如果用到复杂类型,和满篇调用的时候才能体现出这段代码的优越性。

更加的符合面向对象编程的重构行和复用性;

可是上面代码,不晓得大家注意没,出现一个问题,那就是每一次调用都再一次的声明了

ArrayList<T> rets = new ArrayList<>();

对象,如果是需要考虑性能问题的时候,我们肯定不能不能这样。每次调用都需要重新分配ArrayList的内存空间。并且在 ArrayList.add() 的时候每一次都在检查ArrayList的空间够不够,不够,再次开辟新空间。重组。

虽然这个动作很快,可是如果我们缓存的数据过多。那么情况可就不一样了。且伴随着每一次的调用都是一个消耗。访问次数过多的话。那么程序的的性能势必会变的低下。

再次考虑,是否可以用迭代器实现功能呢?

查看了一下迭代器实现方式,我无法完成我需求的迭代器功能。只能依葫芦画瓢,实现了一个自定义的迭代器功能。

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; } }}

调用方式

{ 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(); } }

总结了一些问题,

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

这个从我目前代码设计思路我能理解。如果让我自己设计。也行也会设计如此。

但是无法理解为什么使用泛型无法类型判定;

我这个自定义的迭代器无法使用 for each 功能;

说了这么多。接下来我们看看.net;

C# 设计如下

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 部分的代码和思路,那么我们直接创建自定义迭代器就可以了;

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;

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有