First came to Java and. Net iterator functions, first came to. net

Source: Internet
Author: User

First came to Java and. Net iterator functions, first came to. net

This is a recent requirement,

The function design of the data cache module is based on key-value pairs.

One key corresponds to multiple values. Each key has the same value type, but different keys have different types.

 

The Java design is as follows:

HashMap<String, ArrayList<Object>>

Java adds data to a collection

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

After being added to the data cache and then reading the data, we ignore the thread security issue of the cache set,

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

We found that. Conversion is required in every place.

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

If the same code needs to be repeatedly written, can we encapsulate it once?

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

Here I found a problem that does not support generic checks. As far as I know, java is dynamic data.

It is a pseudo-generic type, so it does not support generic type determination.

This is quite uncomfortable. Why can't I determine the generic type. Maybe it's my knowledge ~! Hope your predecessors can give advice;

View the call again

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

A little refreshing. Of course, I use basic types here. If complex types are used, and full calls can reflect the superiority of this Code.

More in line with the reconstruction and reusability of object-oriented programming;

However, the Code above does not know whether you have noticed it. If there is a problem, it means that every call is declared again.

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

 

Object. If we need to consider performance issues, we certainly cannot. Each call requires re-allocating the ArrayList memory space. In addition, when ArrayList. add () is used, the space of the ArrayList is checked every time. It is not enough to open up new space. Reorganization.

Although this operation is fast, if We cache too much data. The situation may be different. Each call is a consumption. If there are too many accesses. Then the performance of the program will inevitably decrease.

 

Again, can I use an iterator to implement functions?

After checking the implementation method of the iterator, I cannot complete the functions of the iterator I need. You can only draw images from the gourd tree to implement a custom iterator function.

 

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 () {// ignore key issue Object get = TestIterator. this. _ List. get (key ). get (index); return (T) get;} public boolean next () {// ignore the key issue if (index> = TestIterator. this. _ List. get (key ). size () {reset (); return false ;}index ++; return true ;}}}

 

Call Method

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

 

Summarized some problems,

Java generics are pseudo generics, and the underlying layers are actually completed by packing and unpacking through object objects.

 /**     * 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

I can understand this from my current code design ideas. If you want me to design it myself. It will also be designed.

However, I cannot understand why generic data cannot be used for type determination;

My custom iterator cannot use the for each function;

 

So much. Next let's take a look at. net;

 

C # The design is as follows:

 

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;

With the above Java code and ideas, we can directly create a custom iterator;

 

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

 

View call Methods

Foreach (var item in tIterator. CreateEnumerator <String> ("tt1") {Console. WriteLine (item + "too many parameters ");}

Output result:

yield return : sdfsfdsfdsfforeach : sdfsfdsfdsfyield return : sdfsfdsfdsfforeach : sdfsfdsfdsfyield return : sdfsfdsfdsfforeach : sdfsfdsfdsfyield return : sdfsfdsfdsfforeach : sdfsfdsfdsf

 

View and compare the call Methods

Foreach (var item in tIterator. createEnumerator <String> ("Key1") {Console. writeLine ("foreach:" + item);} Console. writeLine ("====================== split line ================ "); IEnumerable <String> getObjs = tIterator. createEnumerator <String> ("Key1 "). toList (); foreach (var item in getObjs) {Console. writeLine ("foreach:" + item );}

The preceding two call methods are used. The output results are completely different.

 

Yield return: sdfsfdsfdsfforeach: descrireturn: sdfsfdsfdsfforeach: sdfsfdsfdsfyield return: sdfsfdsfdsfforeach: sdfsfdsfdsf ========================== yield return: sdfsfdsfdsfyield return: sdfsfdsfdsfyield return: sdfsfdsfdsfforeach: sdfsfdsfdsf

We can see that the second method of calling is to return all the data, which is exactly the same as the previous java design.

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

Although the List object does not appear to be declared on the surface, the allocation of the underlying object still consumes performance;

 

C # The iterator detects generic types;

There is no additional overhead,

 

Summary.

Java custom iteration. More definitions

 private String key;        int index = -1;        private T content;

Generic Type identification is not supported;

 

The C # custom iterator has no additional code overhead, but the underlying layer still implements custom code segments using Java. We just don't need to define it.

C # supports the identification of generic types.

In fact, these are all syntactic sugar issues. There is nothing brilliant or not brilliant. However, in the face of rapid development and high-performance programs, the advantages and disadvantages. Self-identified.

For more information about the above Code, see this article.

Do not touch it ~!~!~!

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.