对Java的List转Array的源码一点思考

在Java里面,List转为Array是调用的Java的一个Arrays.copyOf()这个方法,查看了下源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public Object[] toArray() {
return Arrays.copyOf(this.elementData, this.size);
}

public static <T> T[] copyOf(T[] original, int newLength) {
return (T[]) copyOf(original, newLength, original.getClass());
}

public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
@SuppressWarnings("unchecked")
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}


public static Object newInstance(Class<?> componentType, int length)
throws NegativeArraySizeException {
return newArray(componentType, length);
}

在这里需要注意的是在copyOf()方法中的那个三元表达式,也就是说在这里无论执行的true还是false,都会返回一个新的数组对象。而在这里有一行代码就是((Object)newType == (Object)Object[]).class),这一句看起来没什么,其实可以看参数Class<? extends T[]> newTypeObject会发现这两个数组对象都被强转成了Object,而==`比较符是不能比较不同类型的。例如:

1
2
3
4
public void te(){
System.out.println("ad" == 2);
System.out.println((String.class == Object.class));
}

上面的代码在代码的编译期就会被提示==不可以适用于上述的两种情况.如下:

阅读更多

关于Java的HashMap

Map接口:

  1. 在map接口中的存在一个主接口:public interface Map 和一个内部接口:interface Entry
  2. 其中Map接口主要功能是提供map的一些基本的操作,例如put,inEmpty,get等,而Entry接口则主要是负责遍历操作时的一些方法,例如getKey(),getValue(),setValue

#HashMap实现类:

  1. 在HaspMap这个类里面其实包含了很多的内部类:如下图:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Node
    HashMap
    KeySet
    KeySpliterator
    EntrySet
    Values
    HashIterator
    KeyIterator
    ValueIterator
    EntryIterator
    HashMapSpliterator
    ValueSpliterator
    EntrySpliterator
    TreeNode

    TreeNode类: TreeNode类是一个红黑树:里面包含的是一些红黑树的操作;

    EntrySet类: EntrySet类是提供一个HashMap的遍历方式的一个类,EntrySet类里面有iterator方法,其作用在于map的一种遍历方式:

    1
    2
    3
    4
    5
    Iterator iterator =map.entrySet().iterator();
    while (iterator.hasNext()){
    Map.Entry<Object,Object> map1 = (Map.Entry<Object, Object>) iterator.next();
    System.out.println(map1.getKey());
    }
    这里涉及的知识是EntrySet是继承了AbstractSet间接实现了Set接口,而map.entrySet()方法返回的是一个Set<Map.Entry<K,V>>这个实例。

    其他的暂时还不知道有什么用

关于HashMap的其他细节

阅读更多

关于ArrayList的所见所想

关于ArrrayList扩容:

今天在面试的时候面试官提到过ArrayList扩容是原来的1.5倍加一,但是我看jdk1.8的时候是显示为1.5倍

查看源码:

1
2
3
4
5
6
7
8
9
10
11
12
//Java1.8的扩容方法
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}

那么ArrayList会是扩充1.5倍之后加一呢?

阅读更多