1. java中 list和array哪個效率高map是如何取值的
List底層就是數組,是動態數組,所以存儲效率差不多,但是查詢效率會比array高
map是通過鍵值對存數據的,所以通過key取值,比如map.get(String
key)
希望對你有幫助
2. java中一下兩種方式遍歷數組哪種效率高
list集合的遍歷3種方法:
[java] view plain
package com.sort;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* list的三種遍歷
* @author Owner
*
*/
public class ListTest {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
list.add("c");//可添加重復數據
//遍歷方法一
for(Iterator<String> iterator = list.iterator();iterator.hasNext();){
String value = iterator.next();
System.out.println(value);
}
//遍歷方法二
for(String value : list){
System.out.println(value);
}
//遍歷方法三
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
}
}
三種遍歷的比較分析:
方法一遍歷:
執行過程中會進行數據鎖定, 性能稍差, 同時,如果你想在循環過程中去掉某個元素,只能調用it.remove方法。
方法二遍歷:
內部調用第一種
方法三遍歷:
內部不鎖定, 效率最高, 但是當寫多線程時要考慮並發操作的問題
List介面的兩種主要實現類ArrayList和LinkedList都可以採用這樣的方法遍歷
關於ArrayList與LinkedList的比較分析
a) ArrayList底層採用數組實現,LinkedList底層採用雙向鏈表實現。
b) 當執行插入或者刪除操作時,採用LinkedList比較好。
c) 當執行搜索操作時,採用ArrayList比較好。
3. Java中迭代列表中數據時幾種循環寫法的效率比較
Java中經常會用到迭代列表數據的情況,本文針對幾種常用的寫法進行效率比較。雖然網上已經有了類似的文章,但是對他們的結論並不認同。常見的實現方法:1.for循環:for(int i = 0; i < list.size(); i++) for(int i = 0, size = list.size(); i < size; i++) 一般人都會認為第二種寫法效率高。 2.foreach:for(Object obj : list) 這是一種簡潔的寫法,只能對列表進行讀取,無法修改。 3.while:int size = list.size(); while(size-- > 0) 4.迭代: Object iter = list.iterator(); while(iter.hasNext()) { iter.next(); }測試代碼: 針對以上幾種方法編寫的測試代碼。 public static void main(String[] args) { List<Integer> list = new ArrayList<Integer>(); int runTime = 1000;//執行次數 for (int i = 0; i < 1000 * 1000; i++) { list.add(i); } int size = list.size(); long currTime = System.currentTimeMillis();//開始分析前的系統時間 //基本的for for(int j = 0; j < runTime; j++) { for (int i = 0; i < size; i++) { list.get(i); } } long time1 = System.currentTimeMillis(); //foreach for(int j = 0; j < runTime; j++) { for (Integer integer : list) { } } long time2 = System.currentTimeMillis(); for(int j = 0; j < runTime; j++) { //while int i = 0 ; while(i < size){ list.get(i++); } } long time3 = System.currentTimeMillis(); for(int j = 0; j < runTime; j++) {//普通for循環 for (int i = 0; i < list.size(); i++) { list.get(i); } } long time4 = System.currentTimeMillis(); for(int j = 0; j < runTime; j++) {//迭代 Iterator<Integer> iter = list.iterator(); while(iter.hasNext()) { iter.next(); } } long time5 = System.currentTimeMillis(); long time = time1 - currTime ; System.out.print("use for:" + time); time = time2 - time1; System.out.print("\tuse foreach:" + time); time = time3 - time2; System.out.print("\tuse while:" + time); time = time4 - time3; System.out.print("\tuse for2:" + time); time = time5 - time4; System.out.print("\tuse iterator:" + time); System.out.println(); }輸出結果(JDK1.6):1.use for:8695 use foreach:17091 use while:6867 use for2:7741 use iterator:14144 2.use for:8432 use foreach:18126 use while:6905 use for2:7893 use iterator:139763.use for:8584 use foreach:17177 use while:6875 use for2:7707 use iterator:14345 結論:1.針對列表的 foreach的效率是最低:耗時是普通for循環的2倍以上。個人理解它的實現應該和iterator相似。2. list.size()的開銷很小:list.size()次數多少對效率基本沒有影響。查看ArrayList的實現就會發現,size()方法的只是返回了對象內的長度屬性,並沒有其它計算,所以只存在函數調用的開銷。對數組的測試:將代碼中的列表list換做數組再進行測試(iterator不適用),發現耗時基本為0。說明: 3. 列表的get()方法開銷不少應該主要是檢測數據合法性時產生的。將執行次數增加100萬倍,這時可以看出結果基本相等,並沒有明顯的差異。說明:4. 數組length也沒有開銷可見數組長度並不是每次執行的時候都要計算的。聯想一下Java創建數組的時候要求必須指定數組的長度,編譯處理的時候顯然沒有把這個值拋棄掉。網上有一篇類似的文章,它居然得出了一個foreach執行效率最高的結論。
4. List數據對比篩選,如何才能達到最佳效率
1、最簡單的就是用雙重循環進行比較,雖然簡單,但是如果兩個List的數據量都很大,那麼運行時間將成數量級增長。循環次數為1000*1000
2、把一個List通過循環放入Map中,把需要比較的欄位作為Map的Key,然後循環另外一個List,到Map裡面去匹配。
Java代碼
for(A a : aList){
map.put(a.amount,a);
}
for(B b : bList){
A a = map.get(b.amount);
if(a==null){
//a==null則說明沒有同b匹配的項
}else{
//a!=null則說明匹配上了
}
}
5. java jdk1.6 list.isempty 和list.size 哪個性能快理由是什麼請高人指點,謝...
據說老版本jdk的list.size,會一個一個去數總共有多少個元素,list.isempty可以一步判斷出是否為空,所以老版本如果list較大的話會,只是判斷是否為空的話,肯定empty效率更高,但是新版本已經改進了size方法也是一步到位獲取元素總數,而不是去一個一個數。所以兩者的效率就沒有什麼差別了。jdk1.6上已經沒有差別了
6. Java用哪種方法迭代list 效率最好
Java中沒有foreach 關鍵字。所以的話你可以使用List 中的Arraylist 或者Linkedlist迭代
7. Java的List如何實現線程安全
Java的List如何實現線程安全?
Collections.synchronizedList(names);效率最高,線程安全
Java的List是我們平時很常用的集合,線程安全對於高並發的場景也十分的重要,那麼List如何才能實現線程安全呢 ?
加鎖
首先大家會想到用Vector,這里我們就不討論了,首先討論的是加鎖,例如下面的代碼
public class Synchronized{
private List<String> names = new LinkedList<>();
public synchronized void addName(String name ){
names.add("abc");
}
public String getName(Integer index){
Lock lock =new ReentrantLock();
lock.lock();
try {
return names.get(index);
}catch (Exception e){
e.printStackTrace();
}
finally {
lock.unlock();
}
return null;
}
}
synchronized一加,或者使用lock 可以實現線程安全,但是這樣的List要是很多個,代碼量會大大增加。
java自帶類
在java中我找到自帶有兩種方法
CopyOnWriteArrayList
CopyOnWrite 寫入時復制,它使一個List同步的替代品,通常情況下提供了更好的並發性,並且避免了再迭代時候對容器的加鎖和復制。通常更適合用於迭代,在多插入的情況下由於多次的復制性能會一定的下降。
下面是add方法的源代碼
public boolean add(E e) {
final ReentrantLock lock = this.lock; // 加鎖 只允許獲得鎖的線程訪問
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
// 創建個長度加1的數組並復制過去
Object[] newElements = Arrays.Of(elements, len + 1);
newElements[len] = e; // 賦值
setArray(newElements); // 設置內部的數組
return true;
} finally {
lock.unlock();
}
}
Collections.synchronizedList
Collections中有許多這個系列的方法例如
主要是利用了裝飾者模式對傳入的集合進行調用 Collotions中有內部類SynchronizedList
static class SynchronizedList<E>
extends SynchronizedCollection<E>
implements List<E> {
private static final long serialVersionUID = -7754090372962971524L;
final List<E> list;
SynchronizedList(List<E> list) {
super(list);
this.list = list;
}
public E get(int index) {
synchronized (mutex) {return list.get(index);}
}
public E set(int index, E element) {
synchronized (mutex) {return list.set(index, element);}
}
public void add(int index, E element) {
synchronized (mutex) {list.add(index, element);}
}
public E remove(int index) {
synchronized (mutex) {return list.remove(index);}
}
static class SynchronizedCollection<E> implements Collection<E>, Serializable {
private static final long serialVersionUID = 3053995032091335093L;
final Collection<E> c; // Backing Collection
final Object mutex; // Object on which to synchronize
這里上面的mutex就是鎖的對象 在構建時候可以指定鎖的對象 主要使用synchronize關鍵字實現線程安全
/**
* @serial include
*/
static class SynchronizedList<E>
extends SynchronizedCollection<E>
implements List<E> {
private static final long serialVersionUID = -7754090372962971524L;
final List<E> list;
SynchronizedList(List<E> list) {
super(list);
this.list = list;
}
SynchronizedList(List<E> list, Object mutex) {
super(list, mutex);
this.list = list;
}
這里只是列舉SynchronizedList ,其他類類似,可以看下源碼了解下。
測試
public class Main {
public static void main(String[] args) {
List<String> names = new LinkedList<>();
names.add("sub");
names.add("jobs");
// 同步方法1 內部使用lock
long a = System.currentTimeMillis();
List<String> strings = new CopyOnWriteArrayList<>(names);
for (int i = 0; i < 100000; i++) {
strings.add("param1");
}
long b = System.currentTimeMillis();
// 同步方法2 裝飾器模式使用 synchronized
List<String> synchronizedList = Collections.synchronizedList(names);
for (int i = 0; i < 100000; i++) {
synchronizedList.add("param2");
}
long c = System.currentTimeMillis();
System.out.println("CopyOnWriteArrayList time == "+(b-a));
System.out.println("Collections.synchronizedList time == "+(c-b));
}
}
兩者內部使用的方法都不一樣,CopyOnWriteArrayList內部是使用lock進行加鎖解鎖完成單線程訪問,synchronizedList使用的是synchronize
進行了100000次添加後時間對比如下:
可以看出來還是使用了synchronize的集合工具類在添加方面更加快一些,其他方法這里篇幅關系就不測試了,大家有興趣去試一下。
8. Java中哪一個List最快實現插入
LinkedList 和 ArrayList 是另個不同變數列表的實現。
ArrayList 的優勢在於動態的增長數組,非常適合初始時總長度未知的情況下使用。
LinkedList 的優勢在於在中間位置插入和刪除操作,速度是最快的。
LinkedList 實現了 List 介面,允許 null 元素
此外 LinkedList 提供額外的 get,remove,insert 方法在 LinkedList 的首部或尾部。
這些操作使 LinkedList 可被用作堆棧 (stack),隊列 (queue) 或雙向隊列 (deque)。
ArrayList 實現了可變大小的數組。它允許所有元素,包括 null。
每個 ArrayList 實例都有一個容量(Capacity),即用於存儲元素的數組的大小。
這個容量可隨著不斷添加新元素而自動增加,但是增長演算法並沒有定義。
當需要插入大量元素時,在插入前可以調用 ensureCapacity 方法來增加 ArrayList 的容量以提高插入效率。
9. java list 與map有什麼區別
List:是存儲單列數據的集合,存儲的數據是有序並且是可以重復的
Map:存儲雙列數據的集合,通過鍵值對存儲數據,存儲 的數據是無序的,Key值不能重復,value值可以重復key和value是一一對應的
Collection介面
Collection是Java中最基本的集合介面。它描述了一組有關集合操作的方法。
int Size(); //集合大小
boolean isEmpty(); //是否為空
boolean contains(Object o); //是否包含某個對象
Iterator<E> iterator(); //返回一個迭代對象,用來遍歷集合中的元素
Object[] toArray(); //將集合中的元素以數組形式然後返回
<T> T[] toArray(T[] a); //上一個方法的泛型形式
boolean add(E e); //將對象e添加進集合,添加成功則返回true
boolean remove(Object o); //移除某個元素
boolean containsAll(Collection<?> c); //傳入一個集合c,如果c中的元素都存在,則返回true
boolean addAll(Collection<? extends E> c); //將集合c中的元素全部添加進本集合
boolean removeAll(Collection<?> c); //本集合減去c集合中的元素
boolean retainAll(Collection<?> c); //取本集合和c集合的交集
void clear(); //清空集合
boolean equals(Object o); //判斷相等
int hashCode(); //獲取集合當前的hash值
Set介面
Set介面直接繼承自Collection介面,並且方法介面上也一模一樣。Set對添加的元素有一些要求,其不允許出現重復的元素,並且元素之間沒有次序。這相當於一個不允許重復的離散的集合。因此,添加進Set的元素類型需要定義equals方法。若是使用自定義的類,則應該重寫equals方法來確保實現自己需要的功能。
Set介面主要實現了兩個類:HashSet,TreeSet。
HashSet是按照哈希來存取元素的,因此速度較快。HashSet繼承自抽象類AbstractSet,然後實現了Set、Cloneable、Serializable介面。
TreeSet也是繼承自AbstractSet,不過不同的是其實現的是NavigableSet介面。而NavigableSet繼承自SortedSet。SortedSet是一個有序的集合。其添加的元素必須實現了Comparable介面,因為其在添加一個元素的時候需要進行排序。NavigableSet則提供了更多的有關元素次序的方法。
LinkedHashSet也是Set的一個實現。和HashSet類似,只不過內部用鏈表來維護,按照元素插入次序來保存。
List介面
List介面也是繼承自Collection。與Set不同的是,List可以存儲重復的元素。主要有兩種實現:ArrayList和LinkedList。
ArrayList沒有什麼好說的,就像傳統的數組一樣,有著很快的隨機存取速度,但是插入刪除的速度就很慢。
LinkedList則與ArrayList恰恰相反,因為用鏈表來保存數據,所以插入刪除元素的速度很快,但是訪問數據的速度就不如ArrayList了。
Map介面
Map(映射)是一個存儲鍵值對的容器介面。每一個元素包含一個key對象和value對象,且元素不允許重復。
Map介面的實現有以下幾個:
HashMap是最常用的一個實現。HashMap使用hash映射來存取數據,這個速度是相當快,是O(1)的速度。其容量capacity,和負載因子load factor可以在一開始設定。當元素個數達到capacity*load factor的時候,就會進行擴容。
LinkedHashMap和HashMap類似,只不過內部用鏈表來維護次序。因此遍歷時候的順序是其插入順序。
TreeMap是基於紅黑樹的Map,插入的數據被有次序保存,並且有很高的效率。因此在遍歷輸出的時候可以得到排序的數據。但是這要求插入的數據實現了comparable介面。
總結
Collection、Set、List和Map都是介面,不能被實例化。
Set和List都繼承自Collection,而Map則和Collection沒什麼關系。
Set和List的區別在於Set不能重復,而List可以重復。
Map和Set與List的區別在於,Map是存取鍵值對,而另外兩個則是保存一個元素。
希望對您有所幫助!~
10. Java中ArrayList與List區別是什麼,哪個效率更好
List是介面,你根本用不了,ArrayList才是你真正用的東西,那什麼時候用List,參數聲明的時候用,為了多態,這樣所有實現了List介面的實參都可以傳進來用了。
實現了List介面的還有很多類LinkedList,Vector也有用的時候,其他忽略可