All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.landawn.abacus.util.ArrayHashMap Maven / Gradle / Ivy

/*
 * Copyright (c) 2015, Haiyang Li.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.landawn.abacus.util;

import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * It's designed to supported primitive/object array key.
 * The elements in the array must not be modified after the array is put into the map as key.
 *
 * @since 0.8
 *
 * @author Haiyang Li
 */
public class ArrayHashMap implements Map {
    private final Map, V> map;

    public ArrayHashMap() {
        map = new HashMap<>();
    }

    public ArrayHashMap(final int initialCapacity) {
        map = new HashMap<>(initialCapacity);
    }

    @SuppressWarnings("rawtypes")
    public ArrayHashMap(final Class mapType) {
        //  StackOverflowError

        /*
        ......
        at java.lang.Class.getDeclaredConstructor(Class.java:2066)
        at com.landawn.abacus.util.N.getDeclaredConstructor(N.java:1554)
        at com.landawn.abacus.util.N.newInstance(N.java:3180)
        at com.landawn.abacus.util.ArrayHashMap.(ArrayHashMap.java:45)
        at com.landawn.abacus.util.N.getDeclaredConstructor(N.java:1564)
        at com.landawn.abacus.util.N.newInstance(N.java:3180)
        at com.landawn.abacus.util.ArrayHashMap.(ArrayHashMap.java:45)
        ......
        */

        // map = N.newInstance(mapType);

        try {
            map = Modifier.isAbstract(mapType.getModifiers()) ? N.newInstance(mapType) : mapType.newInstance();
        } catch (InstantiationException e) {
            throw N.toRuntimeException(e);
        } catch (IllegalAccessException e) {
            throw N.toRuntimeException(e);
        }
    }

    public ArrayHashMap(final Map m) {
        if (N.isNullOrEmpty(m)) {
            map = new HashMap<>();
        } else {
            map = new HashMap<>(N.initHashCapacity(m.size()));
        }

        putAll(m);
    }

    @Override
    public V get(Object key) {
        return map.get(Wrapper.of(key));
    }

    @Override
    public V put(K key, V value) {
        return map.put(Wrapper.of(key), value);
    }

    @Override
    public void putAll(Map m) {
        if (N.isNullOrEmpty(m)) {
            return;
        }

        for (Map.Entry entry : m.entrySet()) {
            put(entry.getKey(), entry.getValue());
        }
    }

    @Override
    public V remove(Object key) {
        return map.remove(Wrapper.of(key));
    }

    @Override
    public boolean containsKey(Object key) {
        return map.containsKey(Wrapper.of(key));
    }

    @Override
    public boolean containsValue(Object value) {
        return map.containsValue(value);
    }

    @Override
    public Set keySet() {
        return new ArrayHashSet<>(map.keySet());
    }

    @Override
    public Collection values() {
        return map.values();
    }

    @Override
    public Set> entrySet() {
        return new ArrayEntrySet<>(map.entrySet());
    }

    @Override
    public int size() {
        return map.size();
    }

    @Override
    public boolean isEmpty() {
        return map.isEmpty();
    }

    @Override
    public void clear() {
        map.clear();
    }

    @Override
    public int hashCode() {
        return map.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        return obj == this || (obj instanceof ArrayHashMap && ((ArrayHashMap) obj).map.equals(map));
    }

    @Override
    public String toString() {
        return map.toString();
    }

    static class ArrayEntrySet implements Set> {
        private final Set, V>> set;

        ArrayEntrySet(Set, V>> set) {
            this.set = set;
        }

        @Override
        public boolean add(java.util.Map.Entry e) {
            throw new UnsupportedOperationException();
        }

        @Override
        public boolean addAll(Collection> c) {
            throw new UnsupportedOperationException();
        }

        @Override
        public boolean remove(Object o) {
            throw new UnsupportedOperationException();
        }

        @Override
        public boolean containsAll(Collection c) {
            throw new UnsupportedOperationException();
        }

        @Override
        public boolean removeAll(Collection c) {
            throw new UnsupportedOperationException();
        }

        @Override
        public boolean retainAll(Collection c) {
            throw new UnsupportedOperationException();
        }

        @Override
        public boolean contains(Object o) {
            if (o instanceof Map.Entry) {
                final Map.Entry entry = (Map.Entry) o;

                return set.contains(N.newEntry(Wrapper.of(entry.getKey()), entry.getValue()));
            }

            return false;
        }

        @Override
        public Iterator> iterator() {
            return new ArrayEntryIterator<>(set.iterator());
        }

        @Override
        public Object[] toArray() {
            final int size = size();

            if (size == 0) {
                return N.EMPTY_OBJECT_ARRAY;
            }

            final Object[] result = new Object[size];
            int i = 0;

            for (Map.Entry, V> e : set) {
                result[i++] = new ArrayEntry<>(e);
            }

            return result;
        }

        @Override
        public  T[] toArray(T[] a) {
            final int size = size();

            if (a.length < size) {
                a = N.newArray(a.getClass().getComponentType(), size);
            }

            final Object[] result = a;
            int i = 0;

            for (Map.Entry, V> e : set) {
                result[i++] = new ArrayEntry<>(e);
            }

            return a;
        }

        @Override
        public int size() {
            return set.size();
        }

        @Override
        public boolean isEmpty() {
            return set.isEmpty();
        }

        @Override
        public void clear() {
            throw new UnsupportedOperationException();
        }

        @Override
        public int hashCode() {
            return set.hashCode();
        }

        @Override
        public boolean equals(Object obj) {
            return obj == this || (obj instanceof ArrayEntrySet && ((ArrayEntrySet) obj).set.equals(set));
        }

        @Override
        public String toString() {
            return set.toString();
        }
    }

    static class ArrayEntryIterator implements Iterator> {
        private final Iterator, V>> it;

        ArrayEntryIterator(Iterator, V>> it) {
            this.it = it;
        }

        @Override
        public boolean hasNext() {
            return it.hasNext();
        }

        @Override
        public java.util.Map.Entry next() {
            return new ArrayEntry<>(it.next());
        }

        @Override
        public void remove() {
            it.remove();
        }
    }

    static class ArrayEntry implements Map.Entry {
        private final Map.Entry, V> entry;

        ArrayEntry(Map.Entry, V> entry) {
            this.entry = entry;
        }

        @Override
        public K getKey() {
            return entry.getKey().value();
        }

        @Override
        public V getValue() {
            return entry.getValue();
        }

        @Override
        public V setValue(V value) {
            return entry.setValue(value);
        }

        @Override
        public int hashCode() {
            return entry.hashCode();
        }

        @Override
        public boolean equals(Object obj) {
            return obj == this || (obj instanceof ArrayEntry && ((ArrayEntry) obj).entry.equals(entry));
        }

        @Override
        public String toString() {
            return entry.toString();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy