在这篇文章中,我们将为您详细介绍解释集合的语法。emptyList的内容,并且讨论关于的相关问题。此外,我们还会涉及一些关于6.64ArrayList集合嵌套HashMap集合的案例、ArrayLis
在这篇文章中,我们将为您详细介绍解释集合的语法。emptyList的内容,并且讨论关于的相关问题。此外,我们还会涉及一些关于6.64 ArrayList 集合嵌套 HashMap 集合的案例、ArrayList al = new ArrayList();有什么区别?和ArrayList al = new ArrayList(0)?、arraylist size ()==0,null,isEmpty () 的区别、ArrayList,LinkedList,Vector 集合的认识的知识,以帮助您更全面地了解这个主题。
本文目录一览:- 解释集合的语法。emptyList()(集合解释为)
- 6.64 ArrayList 集合嵌套 HashMap 集合的案例
- ArrayList al = new ArrayList();有什么区别?和ArrayList al = new ArrayList(0)?
- arraylist size ()==0,null,isEmpty () 的区别
- ArrayList,LinkedList,Vector 集合的认识
解释集合的语法。emptyList()(集合解释为)
我只是研究了通用编程,List<E>
接口和ArrayList
,所以我可以理解下面的语句。
ArrayList<String> list = new ArrayList<String>();
但是我不理解在浏览网络时看到的下一条语句。
List<String> list2 = Collections.<String>emptyList();
- 什么
Collections
啊 为什么不是Collections<E>
还是Collections<String>
? - 为什么
<String>
将方法名称放在前面emptyList
?
(emptyList<String>()
对于Generic来说不正确吗?)
- 该声明是什么意思?
答案1
小编典典该行通过使用泛型类型参数调用静态方法来创建一个空字符串列表。
在Collections
类内部,有一个静态方法emptyList
声明为:
public static final <T> List<T> emptyList() { return (List<T>) EMPTY_LIST;}
这具有通用类型参数T
。我们使用以下方法调用此方法:
List<String> list = Collections.emptyList();
并被T
推断为是String
由于的类型list
。
我们也可以T
在调用时将其放在尖括号中来指定其类型emptyList
。如果我们想要比推断的类型更具体的类型,则可能需要这样做:
List<? extends Object> list = Collections.<String>emptyList();
emptyList<String>()
是不正确的,因为该放置仅在创建泛型类的实例而不是调用方法时才有效。当使用new
两个可能的类型参数时,类名之前的仅用于构造函数,而类名之后的则用于整个实例,因此对于类:
class MyClass<A> { public <B> MyClass(A a, B b) { System.out.println(a + ", " + b); }}
我们可以调用它的构造,其中A
是String
和B
是Integer
这样的:
MyClass<String> a = new <Integer>MyClass<String>("a", 3);
或使用类型推断:
MyClass<String> a = new MyClass<>("a", 3);
也可以看看:
- 通用方法
- 类型推断
6.64 ArrayList 集合嵌套 HashMap 集合的案例
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
/*
ArrayList集合嵌套HashMap集合并遍历。
需求:
假设ArrayList集合的元素是HashMap。有3个。
每一个HashMap集合的键和值都是字符串。
元素已经完成,请遍历。
结果:
周瑜---小乔
吕布---貂蝉
郭靖---黄蓉
杨过---小龙女
令狐冲---任盈盈
林平之---岳灵珊
*/
public class ArrayListIncludeHashMapDemo {
public static void main(String[] args) {
// 创建集合对象
ArrayList<HashMap<String, String>> array = new ArrayList<HashMap<String, String>>();
// 创建元素1
HashMap<String, String> hm1 = new HashMap<String, String>();
hm1.put("周瑜", "小乔");
hm1.put("吕布", "貂蝉");
// 把元素添加到array里面
array.add(hm1);
// 创建元素1
HashMap<String, String> hm2 = new HashMap<String, String>();
hm2.put("郭靖", "黄蓉");
hm2.put("杨过", "小龙女");
// 把元素添加到array里面
array.add(hm2);
// 创建元素1
HashMap<String, String> hm3 = new HashMap<String, String>();
hm3.put("令狐冲", "任盈盈");
hm3.put("林平之", "岳灵珊");
// 把元素添加到array里面
array.add(hm3);
// 遍历
for (HashMap<String, String> hm : array) {
Set<String> set = hm.keySet();
for (String key : set) {
String value = hm.get(key);
System.out.println(key + "---" + value);
}
System.out.println();
}
}
}
ArrayList al = new ArrayList();有什么区别?和ArrayList al = new ArrayList(0)?
ArrayList al = new ArrayList();有什么区别?和ArrayList al = new ArrayList(0)?
arraylist size ()==0,null,isEmpty () 的区别
ize ()==0 和 isEmpty () 是等价的,都是判断元素是否为空
list == null 和 list.isEmpty () 的区别就是:
这就相当于,你要喝水,
前面就是判断是不是连水杯都没有,
后面就是判断水杯里面没有水,
连盛水的东西都没有,
这个水从何而来?
所以一般的判断是
if(list!=null||!list.isEmpty()){
这个里面取 list 中的值
}else{
做其他处理
}
1、list==null list 为空,可理解为不存在。
2、list.isEmpty () list 内容为空,没有结点数据。
例如:
测试一下
List list1==null;
List list2=new ArrayList();
list2.isEmpty();
System.out.println(list1.size());
System.out.println(list2.size());
ArrayList,LinkedList,Vector 集合的认识
最近在温习 Java 集合部分,花了三天时间读完了 ArrayList 与 LinkedList 以及 Vector 部分的源码。之前都是停留在简单使用 ArrayList 的 API, 读完源码看完不少文章后总算是对原理方面有了较清楚的认知。这部分文章整理基本都是这么一个套路:简单概括,分析源码增删改查,总结成文。
Java 容器源码 (精品):
https://blog.csdn.net/panweiwei1994/article/details/76555359#commentBox
https://juejin.im/post/5afbff9451882542877353dd
ArrayList 动态扩容分析:
https://blog.csdn.net/zymx14/article/details/78324464
接下来整理了下关于 List 集合校招常见的面试题目:
1.ArrayList 与 Vector 的区别
相同点:
都实现了 List 接口,允许元素重复和为 null 值。
底层都是数组,我们可以按位置索引出某个元素
不同点:
ArrayList 是非同步的,在线程上不安全而 Vector 集合给它的每个 API 都套上了 synchronized,所以 Vector 线程上是安全的。
在添加元素实现扩容的时候,ArrayList 集合存储空间是增长为原来的 1.5 倍。而 Vecto 集合是存储空间增加为原来的 2 倍
PS: 其实不考虑线程问题,他两没啥区别。
2. 往 ArrayList 集合加入一万条数据,应该怎么提高效率?
ArrayList 的构造方法有三种。当数据量比较大,这里又已经明确是一万条了,我们应该在初始化的时候就给它设置好容量。
不然使用无参构造器初始容量只有 10,后面要扩容,扩容又比较伤性能,因为涉及到数组的复制,将原来的数组复制到新的存储区域中去。
PS:ArrayList 动态扩容是一个重点一定要理解好,附上传送门:https://blog.csdn.net/zymx14/article/details/78324464
3.ArrayList 插入删除一定很慢吗?
做过测试,ArrayList 要是一直使用 add 方法在尾部插入的话,当数据量非常大的时候,其效率是要比 LinkedList 快的。删除也是。
但是要是在头部插入就要比 LinkedList 效率低不少。
可见测试分析报告:https://juejin.im/post/5c00987de51d451aa843b67b
四:ArrayList 的遍历和 LinkedList 遍历性能比较如何?
Arraylist 遍历性能要好,无论是全部遍历还是遍历某个元素都是这样。它底层使用数组,适合使用 for 循环按下标寻址。而 LinkedList 底层使用双向链表,虽说它在遍历的时候会采取折半查找的策略来提升速度但还是比不上 ArrayList 的速度。
五:ArrayList 是如何扩容的 \ArrayList 是如何实现自动增加的?
如果是使用无参构造的话,初始容量是 10,当超过了 10 个容量时,就需要扩容,每次扩容为之前的 1.5 倍。调用的是 Arrays.copy (elementData,newCapacity)。所以扩容涉及到数组的复制和移动,我们应该避免扩容。在初始化的时候预估容量大小。
六:什么情况下你会使用 ArrayList?什么时候你会选择 LinkedList?
ArrayList 底层使用数组,LinkedList 底层使用双向链表。结合数据结构的特点可知,数组在空间上占用一片连续的内存空间,查询快。链表在增删操作只需要修改链表指针结点就可,增删快。
所以在查询使用较多时,选择 ArrayList 集合,增删使用较多时,选择 LinkedList 集合。
七:当传递 ArrayList 到某个方法中,或者某个方法返回 ArrayList,什么时候要考虑安全隐患?如何修复安全违规这个问题呢?
把 ArrayList 当作参数传递到某个方法中去,涉及到一个浅拷贝深拷贝的问题。如果直接赋值给成员变量时,当成员变量发生改变时,其对应的传递过来的 ArrayList 也会改变
八:如何复制某个 ArrayList 到另一个 ArrayList 中去?
一般不直接用 “=” 赋值,这是将引用指向了同一片地址,一个修改了里面的内容另一个也会跟着变动。
一般采用如下方式:
ArrayList A = new ArrayList();
//假设此时A集合已经有了数据。构造器法
ArrayList B = new ArrayList(A);
//clone法
ArrayList A = new ArrayList();
ArrayList B = (ArrayList) A.clone();
ArrayList A = new ArrayList();
//初始化时最好先预估容量大小
ArrayList B = new ArrayList();
B.addAll(A);
还可以调用 Collections.copy () 方法,参考博客:https://blog.csdn.net/tiantiandjava/article/details/51072173
九:在索引中 ArrayList 的增加或者删除某个对象的运行过程?效率很低吗?解释一下为什么?
查看源代码可以发现,当通过索引去增删元素的时候效率是比较低的,因为要频繁的进行数组的复制和移动,如果经常增删的话我们可以去考虑其他的集合。
通过索引增加过程:1. 检查索引是否越界?2. 检查容量是否足够?3 调用 System.arrayCopy (......) 操作,效率较低
通过索引删除元素:1. 检查索引是否越界?2. 调用 System.arrayCopy (....) 操作
源代码截图如下:
以上是常见的面试题:接下来总结一下自己看源码所学到的
ArrayList:
1.ArrayList 继承了 AbstractList 类,实现了 List 接口,RadomAccess,Clonable,Serialize 接口。结合 List 接口特点可知它是有序的,可以存储重复值且可以为 null。实现了 RadomAccess 接口在加上它底层采用数组实现,所以遍历速度快且遍历方式推荐使用 for 循环遍历下标而不用 for-each 或者 iterator 迭代器遍历。
2. 使用默认无参构造时,初始容量分配为 10. 当进行增操作时,容量不够会进行扩容操作。
理清 ArrayList 增删改查操作:
add (E e):数组末尾进行增。
1. 判断容量是否足够
2.size++
由此可见在末尾进行增操作时,是偶尔需要进行一次扩容操作,扩容时候会调用 Arrays.copyOf (elementData, newCapacity); 也与上文所说的在末尾插入效率并不比 LinkedList 低
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
public void add (int index, E element):按索引增。可知按索引增每次都要进行数组复制,所以效率低
1. 判断索引是否越界 2. 判断容量是否足够 3.size++
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
public boolean addAll (Collection<? extends E> c):增加一个集合。
1. 先将所要增加的集合转为数组 2. 判断容量 3:size++
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
public E remove (int index):按索引值删除。可知每次都要进行数组复制,效率一样不高
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // Let gc do its work
return oldValue;
}
public boolean remove (Object o):按值删除 调用了 fastRemove (index) 方法,其内部也是要进行数组的复制,效率依然不高。
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
LinkedList:
1. 继承了 AbstractSequentialList 类,但 AbstractSequentialList 只支持按次序访问,而不像 AbstractList 那样支持随机访问。这是 LinkedList 随机访问效率低的原因之一。
2. 实现了 List 接口,说明有序,可以存储重复值,允许元素为 null。实现了 Deque 接口,说明可以像操作栈和队列一样操作它。另外它还是可以被克隆和序列化的。
3.LinkedList 底层是双向链表,链表在空间上是离散的,尽管 Linked 遍历时采用了折半查找,但效率依然较低。它的优势在于增删操作,尤其是在头结点。
原文出处:https://www.cnblogs.com/zengcongcong/p/10805799.html
关于解释集合的语法。emptyList和的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于6.64 ArrayList 集合嵌套 HashMap 集合的案例、ArrayList al = new ArrayList();有什么区别?和ArrayList al = new ArrayList(0)?、arraylist size ()==0,null,isEmpty () 的区别、ArrayList,LinkedList,Vector 集合的认识等相关内容,可以在本站寻找。
本文标签: