java基础 Map补充LinkedHashMap,TreeMap,以及Properties类,Set。

因为前面讲hashMap的源码,发现太长了,所以本章作为补充,毕竟Map的接口下还有其他常用的实现类,所以本篇是讲LinkedHashMap还有TreeMap,以及Properties类。

LinkedHashMap

看名知其意,也是一个链表结构,而链表结构的原理前面说过,在讲解List接口中的时候已经说过,如果对于这个有点不了解可以看。java基础 浅解list集合中ArrayList与LinkedList

老规矩,先看代码,然后进行讲解(jdk1.8)。

public class LinkedHlashMap<K,V>  
    extends HashMap<K,V>
    implements Map<K,V>

可以看出LinkedHashMap是HashMap中子类。看见这个,然后有些人想到之前的见过的继承中的重写,脑海中会补充一个方法,就是LinkedHlashMap中重写put方法,我们看源码。

在LinkedHashMap中源码中没有put方法,那用另一个方法然后新建一个LinkedHashMap然后调用put方法,通过ctrl+点击鼠标进入源码,如下:

   /**
     * Associates the specified value with the specified key in this map.
     * If the map previously contained a mapping for the key, the old
     * value is replaced.
     *
     * @param key key with which the specified value is to be associated
     * @param value value to be associated with the specified key
     * @return the previous value associated with <tt>key</tt>, or
     *         <tt>null</tt> if there was no mapping for <tt>key</tt>.
     *         (A <tt>null</tt> return can also indicate that the map
     *         previously associated <tt>null</tt> with <tt>key</tt>.)
     */
    public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }

但是仔细一看其还是HashMap源码中方法,这个时候就有一个一个疑问,到底是什么原因导致的,那样其他的方法是否被重写了,我们依次查看其中都没有重写。

但是找到这个

   /**
     * HashMap.Node subclass for normal LinkedHashMap entries.
     */
    static class Entry<K,V> extends HashMap.Node<K,V> {
        Entry<K,V> before, after;
        Entry(int hash, K key, V value, Node<K,V> next) {
            super(hash, key, value, next);
        }
    }



Entry<K,V> extends HashMap.Node<K,V>,可以看出在LinkedHashMap中的Entry 继承了HashMap node。以及重写了newNode 方法

Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) {
        LinkedHashMap.Entry<K,V> p =
            new LinkedHashMap.Entry<K,V>(hash, key, value, e);
        linkNodeLast(p);
        return p;
    }

    // link at the end of list
    private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {
        LinkedHashMap.Entry<K,V> last = tail;
        tail = p;
        if (last == null)
            head = p;
        else {
            p.before = last;
            last.after = p;
        }
    }

可以看出LinkedHashMap是通过重写了继承HashMap中的内部类Node中的方法,将其变成一个链表结构的。变成了一个双向链表结构。所以其是有序的, 具体链表结构与数组结构的优缺点,前面list中讲解过,所以不再多说。

TreeMap

这个其实就是就是一个二叉树结构,前面也讲解过,但是其存储数据的话,如果存储自己创建的对象,需要两种方式,java基础 comparable与comparator的作用以及区别

其源码结构一般的时候不会有人具体问,所以暂时不再进行详解,如果需要后期补充。

其中记得其存储自己创建的类的两种方式,具体如何实现可以看前面的连结,那个里面讲解了。对于comparable不再过多解释,但是对于实现Comparator接口可能具体如何写可以看以下TreeMap构造方法

TreeMap(Comparator<? super K> comparator)  构造一个新的、空的树映射,该映射根据给定比较器进行排序。

Properties

对于Properties (类位于 java.util.Properties)在Java中很多时候是将其作为一个配置文件,进行使用的, 不过看其源码后发现

public class Properties extends Hashtable<Object,Object> {

也就明白为什么会在讲解map 的是将其进行一个补充,放在这篇文章里面。

对其主要就是使用即可,即在变成中遇见一些需要修改或者方便补充的变量,将其放在配置文件,让程序读取即可。

所以具体还是看代码创建一个test.propertiest 配置文件

date=2021-03-03
file=\test.txt

使用的properties文件的方法

public class test {
   public static void main(String[] args) {

		
		try {
			Properties props = new Properties();
            //如果用FileInputStream进行导入
//			String f = "src/test/test.properties";
//			props.load(new java.io.FileInputStream(f));
            //如果用getResourceAsStream导入
			String f = "test.properties";
			props.load(new Father().getClass().getResourceAsStream(f));
            //循环和map一样可以进行遍历,不过一般的时候不会这样用
			Set<Entry<Object, Object>> ser=props.entrySet();
			Iterator it=ser.iterator();
			while(it.hasNext()) {
				Entry<Object, Object> e=(Entry<Object, Object>) it.next();
				System.out.println(e.getKey());
				System.out.println(e.getValue());
			}
	        //一般会直接调用某个值,然后得到要要的值
			System.out.println(props.get("date"));
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
}
}

补充 set为map的key

在讲解map的时候,我们说的是set其实是map的key的值,所以我们看一下。

在new HashSet<>(); 可以看一下源码

    /**
     * Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
     * default initial capacity (16) and load factor (0.75).
     */
    public HashSet() {
        map = new HashMap<>();
    }

看如何加入数据,其实可以看其add方法,然后我们可以观看其如何进行存储数据的的。

    // Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();

   /**
     * Adds the specified element to this set if it is not already present.
     * More formally, adds the specified element <tt>e</tt> to this set if
     * this set contains no element <tt>e2</tt> such that
     * <tt>(e==null&nbsp;?&nbsp;e2==null&nbsp;:&nbsp;e.equals(e2))</tt>.
     * If this set already contains the element, the call leaves the set
     * unchanged and returns <tt>false</tt>.
     *
     * @param e element to be added to this set
     * @return <tt>true</tt> if this set did not already contain the specified
     * element
     */
    public boolean add(E e) {
        //由上面可以知道PRESENT没有什么意义,智商new 创建一个对象占住map中的value值
        return map.put(e, PRESENT)==null;
    }

最后发现还是调用的是map 中的put方法

    /**
     * Associates the specified value with the specified key in this map.
     * If the map previously contained a mapping for the key, the old
     * value is replaced.
     *
     * @param key key with which the specified value is to be associated
     * @param value value to be associated with the specified key
     * @return the previous value associated with <tt>key</tt>, or
     *         <tt>null</tt> if there was no mapping for <tt>key</tt>.
     *         (A <tt>null</tt> return can also indicate that the map
     *         previously associated <tt>null</tt> with <tt>key</tt>.)
     */
    public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }

这个就需要再走一遍了,其实再讲解HashMap中的put方法。可以得知如果put的key值一样的话会重写讲key的value值重新赋值。所以set中不用存储两个相同的值。其实可以看出set的很多的方法其实调用的map中的方法。

上一篇 :java基础 浅析MAP原理以及1.7与1.8的区别

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值