精华内容
下载资源
问答
  • 2018-11-29 09:08:05

    https://blog.csdn.net/u010575093/article/details/50731281
    

    抽象类中可以定义成员变量,而接口中定义的成员变量实际上都是常量
    接口不可继承抽象类,抽象类可实现多个接口。接口与接口之间是继承,用extends,可继承多个接口

    mport java.util.HashMap;
    import java.util.Map;
    
    interface Test{
            public void mm();
    }
    
    interface Test1{
            public void kk();
    }
    //接口可以继承多个接口
    interface Test2 extends Test, Test1{
            public void mk();
    }
    //抽象类成员都是public,
    //抽象类中可以定义成员变量,而接口中定义的成员变量实际上都是常量。
    //抽象类可以继承接口,并实现接口方法
    abstract class ATest1 implements Test1{
            public void kk(){  System.out.println("ATtest mm");  }
    }
    
    abstract class ATest2 implements Test1, Test{
            public void mm(){       System.out.println("ATest2 mm");        }
            public void kk(){}
    }
    // 抽象类可以继承抽象类 也可以继承实体类
    abstract class ATest3 extends ATest1{
    
    }
    
    class Solution{
    	//时间复杂度n
            public void tosum(int[] nums, int target){
                    Map<Integer, Integer> map = new HashMap<>();
                    for(int i = 0; i < nums.length; i++)
                            map.put(nums[i],i);
                    for(int i = 0; i < nums.length; i++){
                            int comp = target - nums[i];
                            System.out.println("comp="+comp+" containsKey "+map.containsKey(comp));
                            System.out.println("map get "+map.get(comp));
                            if(map.containsKey(comp) && map.get(comp)!=i){
                                    System.out.println("match:"+i+" "+map.get(comp));
                            }
                    }
                    System.out.println("tosum");
            }
            //时间复杂度1
            public int[] tosum1(int[] nums, int target){
                    Map<Integer, Integer> map = new HashMap<>();
                    for (int i = 0; i < nums.length; i++) {
                            int complement = target - nums[i];
                            if (map.containsKey(complement)) {
                                    return new int[] { map.get(complement), i };
                            }
                            map.put(nums[i], i);
                    }
                    throw new IllegalArgumentException("No two sum solution");
            }
    }
    class HashSum{
    
            public static void main(String argv[]){
                    System.out.println("111");
                    new Solution().tosum();
            }
    }
    
    
    更多相关内容
  • 反射获取hashmap以及继承hashmap的类

    反射获取hashMap

    反射是基于hashmap内部实现原理,Hashmap的核心在putval方法和内部类Node的组成.

    核心方法putVal

    final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                       boolean evict) {
            Node<K,V>[] tab; Node<K,V> p; int n, i;
            if ((tab = table) == null || (n = tab.length) == 0)
                n = (tab = resize()).length;
            if ((p = tab[i = (n - 1) & hash]) == null)
                tab[i] = newNode(hash, key, value, null);
            else {
                Node<K,V> e; K k;
                if (p.hash == hash &&
                    ((k = p.key) == key || (key != null && key.equals(k))))
                    e = p;
                else if (p instanceof TreeNode)
                    e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
                else {
                    for (int binCount = 0; ; ++binCount) {
                        if ((e = p.next) == null) {
                            p.next = newNode(hash, key, value, null);
                            if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                                treeifyBin(tab, hash);
                            break;
                        }
                        if (e.hash == hash &&
                            ((k = e.key) == key || (key != null && key.equals(k))))
                            break;
                        p = e;
                    }
                }
                if (e != null) { // existing mapping for key
                    V oldValue = e.value;
                    if (!onlyIfAbsent || oldValue == null)
                        e.value = value;
                    afterNodeAccess(e);
                    return oldValue;
                }
            }
            ++modCount;
            if (++size > threshold)
                resize();
            afterNodeInsertion(evict);
            return null;
        }
    

    可以看到hashmap由Node对象构成基础,那么我们反射的时候就要想法设法的把它的node给搞出来

    Node构成

    static class Node<K,V> implements Map.Entry<K,V> {
            final int hash;
            final K key;
            V value;
            Node<K,V> next;
    
            Node(int hash, K key, V value, Node<K,V> next) {
                this.hash = hash;
                this.key = key;
                this.value = value;
                this.next = next;
            }
    
            public final K getKey()        { return key; }
            public final V getValue()      { return value; }
            public final String toString() { return key + "=" + value; }
    
            public final int hashCode() {
                return Objects.hashCode(key) ^ Objects.hashCode(value);
            }
    
            public final V setValue(V newValue) {
                V oldValue = value;
                value = newValue;
                return oldValue;
            }
    
            public final boolean equals(Object o) {
                if (o == this)
                    return true;
                if (o instanceof Map.Entry) {
                    Map.Entry<?,?> e = (Map.Entry<?,?>)o;
                    if (Objects.equals(key, e.getKey()) &&
                        Objects.equals(value, e.getValue()))
                        return true;
                }
                return false;
            }
        }
    

    node由hash,key,value,next这几个构成,他们都为属性名,那么就是可以通过反射获取到的。

    反射的实现

    //o 就是一个hash数组 里面有{code,msg,data}
    private Object  GetHashTableValue(Object o){
            Object resObj = new Object();
        //定义hashmap
            Class clsHashMap = null;
        //定义hashmap里的Node
            Class clsHashMap$Node = null;
        
            Field[] f = null;
            Field t = null, fNode = null;
    
            try {
                clsHashMap = Class.forName("java.util.HashMap");
                clsHashMap$Node = Class.forName("java.util.HashMap$Node");
    
                // 获取hashmap里的全部属性
                //里面有serialVersionUID,DEFAULT_INITIAL_CAPACITY,MAXIMUM_CAPACITY,DEFAULT_LOAD_FACTOR,TREEIFY_THRESHOLD,UNTREEIFY_THRESHOLD,MIN_TREEIFY_CAPACITY,
                f = clsHashMap.getDeclaredFields();
                
                AccessibleObject.setAccessible(f, true);
                for (Field field : f) {
                    // System.out.println(field.getName());
                    //获取属性名为table的,然后赋值给 filed
                    if (field.getName() == "table")
                        t = field;
                }
                //这这里的t为tree  transient Node<K,V>[] table; 由此可见这个是一个数组,所以要Object[] 来转换下
                 //注:如果是继承hashmap那么继承的属性也会在这里面。比如有个getmes类,其中有code,msg属性,那么o1也会有
                Object[] o1 = ((Object[]) t.get(o));
                //这里面遍历的便是node
                for (Object o2 : o1) {
                    if (o2!=null){
                        Object next = o2;//这个next就相当于是node一个类
                        while (next!=null){
                            //反射value属性
                            Field value = clsHashMap$Node.getDeclaredField("value");
                            //反射next属性
                            Field o_next  = clsHashMap$Node.getDeclaredField("next");
                            //根据自己需要还可以反射key和hash,方法一样
    
                            o_next.setAccessible(true);
                            value.setAccessible(true);
    
                            //得到value值
                            resObj = value.get(next);
                            
                            //得到下个节点node 可以赋值给fNode
                            Object objNext = o_next.get(next);
                            next = objNext;
                        }
                    }
                }
            } catch (ClassNotFoundException | IllegalAccessException | NoSuchFieldException e) {
                e.printStackTrace();
            }
    
            return resObj;
        }
    

    可以看到hashmap有大量的属性

     transient Node<K,V>[] table;
    
    private static final long serialVersionUID = 362498820763181265L;
    
       
    
        /**
         * The default initial capacity - MUST be a power of two.
         */
        static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
    
        /**
         * The maximum capacity, used if a higher value is implicitly specified
         * by either of the constructors with arguments.
         * MUST be a power of two <= 1<<30.
         */
        static final int MAXIMUM_CAPACITY = 1 << 30;
    
        /**
         * The load factor used when none specified in constructor.
         */
        static final float DEFAULT_LOAD_FACTOR = 0.75f;
    
        /**
         * The bin count threshold for using a tree rather than list for a
         * bin.  Bins are converted to trees when adding an element to a
         * bin with at least this many nodes. The value must be greater
         * than 2 and should be at least 8 to mesh with assumptions in
         * tree removal about conversion back to plain bins upon
         * shrinkage.
         */
        static final int TREEIFY_THRESHOLD = 8;
    
        /**
         * The bin count threshold for untreeifying a (split) bin during a
         * resize operation. Should be less than TREEIFY_THRESHOLD, and at
         * most 6 to mesh with shrinkage detection under removal.
         */
        static final int UNTREEIFY_THRESHOLD = 6;
    
        /**
         * The smallest table capacity for which bins may be treeified.
         * (Otherwise the table is resized if too many nodes in a bin.)
         * Should be at least 4 * TREEIFY_THRESHOLD to avoid conflicts
         * between resizing and treeification thresholds.
         */
        static final int MIN_TREEIFY_CAPACITY = 64;
        /**
         * Holds cached entrySet(). Note that AbstractMap fields are used
         * for keySet() and values().
         */
        transient Set<Map.Entry<K,V>> entrySet;
    
        /**
         * The number of key-value mappings contained in this map.
         */
        transient int size;
    
        /**
         * The number of times this HashMap has been structurally modified
         * Structural modifications are those that change the number of mappings in
         * the HashMap or otherwise modify its internal structure (e.g.,
         * rehash).  This field is used to make iterators on Collection-views of
         * the HashMap fail-fast.  (See ConcurrentModificationException).
         */
        transient int modCount;
    
     
        int threshold;
    
        final float loadFactor;
    

    :transient是短暂的意思。对于transient 修饰的成员变量,在类的实例对象的序列化处理过程中会被忽略。 因此,transient变量不会贯穿对象的序列化和反序列化,生命周期仅存于调用者的内存中而不会写到磁盘里进行持久化

    总结:

    ​ 反射hashmap核心还是反射其中hashmap的内部类node类,只要拿的到它,就能反射相应的元素

    展开全文
  • 一开始我是用R继承hashmap然后定义一个私有属性data,没想到出错了,因为序列化过程中会忽略掉类的私有属性(继承hashmap的类),因此在反序列过程中会吧data的值丢失。 public class R<T> extends HashMap<...

    在springcloud微服务调用返回数据时,出现获取数据为null的情况:
    一开始我是用R继承hashmap然后定义一个私有属性data,没想到出错了,因为序列化过程中会忽略掉类的私有属性(继承hashmap的类),因此在反序列过程中会吧data的值丢失。

    public class R<T> extends HashMap<String,T> {
        private T data;
        public void setData(T data){
            this.data = (T) data;
        };
    
        public T getData(){
            return data;
        }
    }
    class t{
        public static void main(String[] args) {
            R r = new R();
            r.setData(new Integer(1));
            System.out.println(r.getData());
            //序列化
            String s = JSON.toJSONString(r);
            System.out.println(s);
            //反序列化
            R r1 = JSON.parseObject(s, R.class);
            System.out.println(r1.getData());
            /**结果为
             * 1
             * {}
             * null
             */
        }
    }
    

    因此在放入数据时,需要利用put的方法放入map中,而又因为springcloud在调用其他服务后返回结果会转换为LinkedHashMap(前提是,如果map中的value为复杂对象,例如为List。这里不是很清楚,懂得人可以解答下),所以先将LinkedHashMap转换为json字符串,然后再转换为自己想要的类型对象
    在这里插入图片描述

    public class R extends HashMap<String, Object> {
    	private static final long serialVersionUID = 1L;
    
    	public <T> T getData(TypeReference<T> typeReference){
    		Object data = get("data");
    		String s = JSON.toJSONString(data);
    		T t = JSON.parseObject(s, typeReference);
    		return t;
    	}
    
    	public R setData(Object data){
    		put("data",data);
    		return this;
    	}
    
    展开全文
  • 新建一个继承HashMap的Bean @Data @EqualsAndHashCode(callSuper = true) public class R<T> extends HashMap<String,Object> implements Serializable { private T data; } 进行fastjson...

    新建一个继承了HashMap的Bean

    @Data
    @EqualsAndHashCode(callSuper = true)
    public class R<T> extends HashMap<String,Object> implements Serializable {
    
        private T data;
    
    }

    进行fastjson进行序列化和反序列化

    public static void main(String[] args) {
       R r = new R();
       r.setData("1");
       String s = JSONObject.toJSONString(r);
       R r1 = JSONObject.parseObject(s,R.class);
       System.out.println(r1.getData());
    }

     结果输出null

    R如果不继承HashMap,结果输出“1”

    这是为什么呢???

    我们进一步观察可以看到,其实是R在序列化的时候就为{},所以反序列化也为null

    可以用debug去看下fastjson的源码:

    以上是fastjson的源码,会将Map类型的javaBean强转为Map类型,所以子类的私有属性都会被丢弃,而又是不是所有都会转化为Map类型呢?不是的

    可以看到,如果使用Map.class.isAssignableFrom(clazz)判断就会进入Map的处理方式中,看来fastjson是对map进行了特殊封装

    那么spring自带的jackson呢?

    public static void main(String[] args) {
       R<String> r = new R<>();
       r.put("test","1");
       r.setData("1");
       ObjectMapper build = new Jackson2ObjectMapperBuilder().build();
       System.out.println(r.getData());
       String s = null;
       try {
          s = build.writeValueAsString(r);
       } catch (JsonProcessingException e) {
          e.printStackTrace();
       }
       System.out.println(s);
    }
    

    不出意料,以上代码也是输出为:

    1
    {"test":"1"}

    其中“data”属性并没有被带上

    我们也可以进入jackson的源码中分析下:

    可以看到,jackson也是在不断的尝试寻找Serializer,但是并没有通过常规的方式找到,我们进入这个_createAndCacheUntypedSerializer方法,它是返回了一个MapSerializer序列化器

    找不到了,反正是返回了一个MapSerializer.....

    然后我们可以继续往下面看,看这个MapSerializer是怎么进行序列化的

    到了以上这步就很明显了,Object作为实参,而Map作为形参,所以会有类型强制转化的操作,相当于进行了向上转型,导致了子类中的私有变量消失了

    至此,我们得出了结论,继承了HashMap的实体类的私有属性,通过fastjson与Jackson都是不能被序列化与反序列化的

     

    展开全文
  • 继承于map或者list或者set后,在其他对于这个类的操作时需要特别注意,比如,使用fastjson等工具类进行转换成json时将不会转换map、list、set之外的属性。举例,A类继承list后,又在A类中添加了一个name属性,如果...
  • public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable public class LinkedHashMap<K,V> extends HashMap<K,V> implements...
  • 继承HashMap类,重写了toString()方法。

    千次阅读 2008-04-22 13:53:00
    //定义一个HashMapSon类,它继承HashMap类 class HashMapSon,V> extends HashMap { //重写HashMapSon类的toString()方法  @Override public String toString(){  Set,V>> keyset = this.entrySet();  Iterator,V>...
  • 一张图看懂java HashMap继承关系

    千次阅读 2018-08-05 12:34:20
    这是JDK1.8.0_151下的HashMap类定义: public class HashMap&lt;K,V&gt; extends AbstractMap&lt;K,V&gt; implements Map&...根据类定义,追根刨底,看看HashMap继承结构图: ...
  • 一、MyBatis的ContextMap实现HashMap重写get方法 MetaObject封装用户入参parameterObject MetaObject metaObject = configuration.newMetaObject(parameterObject); ContextMap封装MetaObject,间接就是封装了用户...
  • 1、HashMap 继承与接口关系图 2、HashSet 继承与接口关系(HashSet 独立图) 3、List 、ArrayList 、HashSet、Set、关系图  
  • HashMap中的对象可以被拷贝 克隆 序列到磁盘上,WeakhashMap都不行 重要方法 WeakhashMap的put方法(key重复,新值覆盖旧值;头插新节点) hash算法不一样(WeakhashMap源码297行 ) /** * Retrieve object hash...
  • 我们使用 put(key, value) 存储对象到 HashMap 中,使用 get(key) 从 HashMap 中获取对象。当我们给 put() 方法传递键和值时,我们先对键调用 hashCode() 方法,计算并返回的 hashCode 是用于找到 Map 数组的 bucket...
  • HashMap如何添加元素详解

    千次阅读 2020-03-16 14:18:15
    Map接口结构 ...MapHashMapLinkedHashMapHashtable实现map接口实现map接口继承HashMap实现map接口MapHashMapLinkedHashMapHashtable HashMap特点 存储结构在jdk1.7当中是数组加链表的结构,在jdk1...
  • Java关于hashmap的创建:问题描述如下,有这样一个编程要求step1:创建类StudentJavaScore,实现comparable接口,包含两个字段intjavaScore记录java成绩,Stringname表示学生姓名,生成...Java 关于hashmap的创建:...
  • 使用hashmap封装mybatis的查询参数: HashMap<String, Object> map=new HashMap(); map.put("name","jack"); List<User> list=userService.getUserList(map); mybatis查询语句 <select id=...
  • jdk中HashMap的声明如下  public class HashMap extends AbstractMap implements Map, Cloneable, Serializable AbstractMap的声明如下  public abstract class AbstractMap implements Map 这就让人很奇怪...
  • import java.util.HashMap; /** * Keafmd * * @ClassName: TestHashMap * @Description: * @author: 牛哄哄的柯南 * @Date: 2021-04-21 14:37 * @Blog: https://keafmd.blog.csdn.net/ */ public class ...
  • java返回结果使用HashMap接收

    千次阅读 2021-02-12 22:25:46
    java返回结果使用HashMap接收发布时间:2020-11-07 16:22:48来源:亿速云阅读:108作者:Leahjava返回结果使用HashMap接收?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇...
  • Description: 自定义一个HashMap * 实现了put方法增加键值对,并解决了键重复的时候覆盖相应的节点&amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;gt; * @author zhangyan * @date 2019/1/28 20:07
  • // hashMap底层存储结构 transient Node<K,V>[] table; // onlyIfAbsent- 如果为true,改变已存在的值(暂时还不太理解) // evict- 如果为false,表明该table目前是创建模式,看了下,目前仅发现有两个地方...
  • HashMap继承Map

    千次阅读 2018-03-09 12:27:53
     import java.util.HashMap;import java.util.Map;import java.util.Set; /** *HashMap 类 ,是Map接口的实现类 * 特点: * 1:内部是依靠哈希表存储 * 2:不允许键的重复 * 3:允许null键和null值的出现 * ...
  • 要创建HashMap,请使用HashMap类-HashMaphm=newHashMap();以键值对形式将元素添加到HashMap-hm.put("Bag",newInteger(1100));hm.put("Wallet",newInteger(700));hm.put("Belt",newInteger(600));以下是创建HashMap并...
  • HashMap重写实现

    2011-01-15 10:22:46
    HashMap重写实现 轻量级实现 使用自定义的轻量对象HashObjectMap替代jdk的HahMap HashMap里的Entry占用较大内存,可以用自己实现的轻量级容器替换,步骤如下: 1、 缓存的对象需要继承BaseHashObject /** * 这个类...
  • 本文主要向大家介绍了Java语言里Hashmap序列化的一个...在一个继承了 Serializable 接口的java bean里按照常规操作添加了一个hashmap和与之对应的getter、setter,就像这样:...private HashMapmChooseMap;publicHas...
  • 简单总结 HashMap、Hashtable、ConcurrentHashMap 之间的区别,基于 JDK 1.8.0_191 先说结论,暂时有以下几个需要注意的不同点: 继承、实现接口不同 初始大小、扩容倍数不同 线程安全 NULL KEY,NULL VALUE 支持...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 179,340
精华内容 71,736
关键字:

继承hashmap