J2SE 8的集合

List

ArrayList查询效率高LinkedList插入删除效率高


ArrayList

ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("11");
arrayList.add("22");

//1.循环列表
arrayList.iterator().forEachRemaining(n->System.out.println(n));
System.out.println();
arrayList.stream().forEach(n->System.out.println(n));
System.out.println();

//2.remove之前需要调用next()
Iterator<String> iterator = arrayList.iterator();
while(iterator.hasNext()){
	System.out.println(iterator.next());
	
	//调用remove之前需要先调用next()
	iterator.remove();
}
System.out.println();
 

//3.contains
boolean contains = arrayList.contains("11");
System.out.println(contains);


arrayList.add("33");
arrayList.add("44");
arrayList.add("55");
arrayList.add("66");
arrayList.add("77");


//4.removeIf
arrayList.removeIf(x->x.equals("33"));
System.out.println(arrayList.contains("33"));
System.out.println();


//5.toArray
String[] array = arrayList.toArray(new String[arrayList.size()]);
for (String string : array) {
	System.out.println(string);
}
System.out.println();


//6.subList and clear
arrayList.subList(1, 2).clear();
arrayList.stream().forEach(n->System.out.println(n));


//7.ArrayList线程不安全,使用下面方法得到线程安全的List
List<String> synchronizedList = Collections.synchronizedList(arrayList);


//8.CopyOnWriteArrayList也是线程安全的
CopyOnWriteArrayList<String> copyOnWriteArrayList = new CopyOnWriteArrayList<String>();


//9. 得到一个read only的list
List<String> unmodifiableList = Collections.unmodifiableList(arrayList);

//10. Array.newInstance 新建Array
String[] arrayString = {"11","22"};
if(arrayString.getClass().isArray()){
    //新建一个空的数组,类型为array的type,size为新传入的
    Object newInstance = Array.newInstance(arrayString.getClass().getComponentType(), 10);
    
    //拷贝
    System.arraycopy(arrayString, 0, newInstance, 0, Math.min(Array.getLength(arrayString), 10));
    System.out.println(newInstance instanceof String[]);    //true
}

//11. 排序
Arrays.sort(arrayString);
Collections.sort(arrayList);


//12.查找元素
arrayList.indexOf(""); 

Arrays

//1.字符串->数组
String[] splitArray = "11111
22222
33333
6666666666666".split("
");
System.out.println(Arrays.toString(splitArray));

//2.数组转->字符串
String string2 = Arrays.toString(splitArray);
System.out.println(string2);

//3.数组->List
List<String> asList = Arrays.asList(new String[]{"aa","bb","cc"});
asList = Arrays.asList("aa","bb","cc");
System.out.println(asList.toString());

//4. 二分法查找
Arrays.binarySearch(splitArray, ""); 



LinkedList

添加和删除元素比较方便;查找,效率比较低

LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("11");
linkedList.add("22");
linkedList.add("33");


//1.正向遍历列表
ListIterator<String> listIterator = linkedList.listIterator();
while(listIterator.hasNext()){
	System.out.println(listIterator.next());
}
System.out.println();

//2.反向遍历列表
while(listIterator.hasPrevious()){
	System.out.println(listIterator.previous());
	
	//下一次索引的位置
//			System.out.println(listIterator.nextIndex());
	//前一次索引的位置
//			System.out.println(listIterator.previousIndex());
}
System.out.println();


//3.get(i)会从0位置开始找,所以查找很没有效率
//比如foreach,从中找每次都是get(i),那每次都是从0位置开始找,所以效率很低
String string = linkedList.get(3);


Map

 最近在阿里java开发手册上看到了这句话:Map/Set 的 key 为自定义对象时,必须重写 hashCode 和 equals。这里Set集合中放入的是String类型,假如我们放入一个自己定义的类实例的时候,比如Person类实例,这时候我们要自己重新hashcode和equal方法,用自己的关键字段来重写,因为当使用HashSet时,hashCode()方法就会得到调用,判断已经存储在集合中的对象的hash code值是否与增加的对象的hash code值一致;如果不一致,直接加进去;如果一致,再进行equals方法的比较,equals方法如果返回true,表示对象已经加进去了,就不会再增加新的对象,否则加进去


HashMap

可以通过构造器设置容量capacity和负载因子load factor,以调整容器的性能

HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("11", null);

//1. 当Map中取到的为不存在的值时(指没有对应的key),可以指定defaultValue
System.out.println(hashMap.getOrDefault("11", "Default value 1"));
System.out.println(hashMap.getOrDefault("22", "Default value 2"));
System.out.println();

//2. forEach
hashMap.put("11", "11 value");
hashMap.put("22", "22 value");
hashMap.put("33", "33 value");
hashMap.forEach((k,v)->System.out.println(k+"	"+v));
System.out.println();


//3. contains
System.out.println(hashMap.containsKey("11"));
System.out.println(hashMap.containsValue("22 value"));
System.out.println();


//4. 更新值
//(1) 原值没有会得到null值,可以指定初始值
hashMap.put("44", hashMap.getOrDefault("44", "")+"**");
hashMap.forEach((k,v)->System.out.println(k+"	"+v));
System.out.println();
//(2) 键存在才会赋值
hashMap.putIfAbsent("55", hashMap.get("55")+"**");
hashMap.forEach((k,v)->System.out.println(k+"	"+v));
System.out.println();
//(3) merge, 对于指定的key,用指定的function去添加value==>这样有的值可以不用先取出来,直接append
hashMap.merge("11", " 11 added value", String::concat);
hashMap.forEach((k,v)->System.out.println(k+"	"+v));
System.out.println();


//5. KeySet			-- key
Set<String> keySet = hashMap.keySet();
keySet.forEach(n->System.out.println(n));
System.out.println();


//6. Collection		-- values
Collection<String> values = hashMap.values();
values.forEach(n->System.out.println(n));
System.out.println();


//7. EntrySet		-- key & values
Set<Entry<String, String>> entrySet = hashMap.entrySet();
for (Entry<String, String> entry : entrySet) {
	System.out.println(entry.getKey()+"	"+entry.getValue());
}
System.out.println();

entrySet.forEach((n)->System.out.println(n.getKey()+"	"+n.getValue()));
System.out.println();



//8. read only
Map<String, String> unmodifiableMap = Collections.unmodifiableMap(hashMap);

LinkedHashMap

HashMap的双向链表

在迭代访问时发而更快,因为它使用链表维护内部次序

LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<>();

linkedHashMap.put("44", "444");
linkedHashMap.put("11", "111");
linkedHashMap.put("22", "222");
linkedHashMap.put("33", "333");

linkedHashMap.keySet().forEach(n->System.out.println(n));


linkedHashMap.get("44");
linkedHashMap.keySet().forEach(n->System.out.println(n));

WeakHashMap

当Map中的key不再使用时,需要程序删除对应的key,或者使用WeakHashMap; 垃圾回收相关

Map中使用的对象也被允许释放: 这是为解决特殊问题设计的。如果没有map之外的引用指向某个“键”,则此“键”可以被垃圾收集器回收

WeakHashMap<String, String> weakHashMap = new WeakHashMap<String, String>();

TreeMap

底层是二叉树数据结构,线程不同步,可用于给Map集合中的键进行排序

TreeMap<String, String> treeMap = new TreeMap<String, String>(String::compareTo);

treeMap.put("22", "11");
treeMap.put("11", "11");

treeMap.entrySet().forEach(n->System.out.println(n.getKey()));

ConcurrentHashMap

并发效率更高的Map,用来替换其他线程安全的Map容器,比如Hashtable和Collections.synchronizedMap

ConcurrentHashMap<String, String> concurrentHashMap = new ConcurrentHashMap<>();

IdentifyHashMap

使用==代替equals()对“键”作比较的hash map

ArrayMap

ArrayMap是一个<key,value>映射的数据结构,它设计上更多的是考虑内存的优化,内部是使用两个数组进行数据存储,
一个数组记录key的hash值,另外一个数组记录Value值,
它和SparseArray一样,也会对key使用二分法进行从小到大排序,在添加、删除、查找数据的时候都是先使用二分查找法得到相应的index,然后通过index来进行添加、查找、删除等操作,
所以,应用场景和SparseArray的一样,如果在数据量比较大的情况下,那么它的性能将退化至少50%

SparseArray

SparseArray比HashMap更省内存,在某些条件下性能更好,主要是因为它避免了对key的自动装箱(int转为Integer类型),它内部则是通过两个数组来进行数据存储的,一个存储key,另外一个存储value,为了优化性能,它内部对数据还采取了压缩的方式来表示稀疏数组的数据,从而节约内存空间

HashTable

HashMap是Hashtable的轻量级实现,非线程安全的实现他们都实现了map接口,主要区别是HashMap键值可以为空null,效率可以高于Hashtable


Set

 最近在阿里java开发手册上看到了这句话:Map/Set 的 key 为自定义对象时,必须重写 hashCode 和 equals。这里Set集合中放入的是String类型,假如我们放入一个自己定义的类实例的时候,比如Person类实例,这时候我们要自己重新hashcode和equal方法,用自己的关键字段来重写,因为当使用HashSet时,hashCode()方法就会得到调用,判断已经存储在集合中的对象的hash code值是否与增加的对象的hash code值一致;如果不一致,直接加进去;如果一致,再进行equals方法的比较,equals方法如果返回true,表示对象已经加进去了,就不会再增加新的对象,否则加进去


HashSet

HashSet不能装入重复的值

HashSet<String> hashSet = new HashSet<>();

hashSet.add("111");
hashSet.add("111");
hashSet.add("222");

System.out.println(hashSet.size());

hashSet.forEach(n->System.out.println(n));

TreeSet

不重复,有序集合;插入值后,自动排序

注意:此例重写了equals(), hashCode(), compareTo()方法

TreeSet<Integer> treeSet = new TreeSet<>();
treeSet.add(10);
treeSet.add(10);
treeSet.add(6);
treeSet.add(8);
treeSet.forEach(n->System.out.println(n));
System.out.println();


//需要实现Comparable
TreeSet<Item> treeSet1 = new TreeSet<>();
treeSet1.add(new Item("Tom", 123));
treeSet1.add(new Item("Jack", 123));
treeSet1.add(new Item("Alice", 127));
treeSet1.forEach(n->System.out.println(n));
System.out.println();


//指定一个Comparable
TreeSet<Item> treeSet2 = new TreeSet<>(Comparator.comparing(Item::getDescription));
treeSet2.addAll(treeSet1);
treeSet2.forEach(n->System.out.println(n));
System.out.println();
class Item implements Comparable<Item>{
	private String description;
	private int partNumber;
	
	public Item(String description, int partNumber) {
		this.description=description;
		this.partNumber=partNumber;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public int getPartNumber() {
		return partNumber;
	}

	public void setPartNumber(int partNumber) {
		this.partNumber = partNumber;
	}
	
	@Override
	public String toString() {
		return "description:"+description+",partNumber:"+partNumber;
	}
	
	@Override
	public boolean equals(Object obj) {
		if(this == obj){
			return true;
		}
		
		if(null==obj){
			return false;
		}
		
		if(getClass()!=obj.getClass()){
			return false;
		}
		
		Item anotherItem = (Item)obj;
		
		return Objects.equals(description, anotherItem.getDescription())
				&&partNumber==anotherItem.getPartNumber();
	}
	
	@Override
	public int hashCode() {
		return Objects.hash(description,partNumber);
	}

	@Override
	public int compareTo(Item o) {
		int compare = Integer.compare(partNumber, o.partNumber);
		
		if(compare!=0){
			return compare;
		}else{
			return description.compareTo(o.getDescription());
		}
	}
}

其它Collection


PriorityQueue

任务调度,每个任务有优先级;随机加入队列中;启动新任务时,将优先级最高的任务从队列中删除

PriorityQueue<LocalDate> priorityQueue = new PriorityQueue<>();

priorityQueue.add(LocalDate.of(2000, 01, 01));
priorityQueue.add(LocalDate.of(2001, 11, 21));
priorityQueue.add(LocalDate.of(1998, 01, 01));

priorityQueue.forEach(n->System.out.println(n));

//每次删除优先级最高的
priorityQueue.remove();
System.out.println();

priorityQueue.forEach(n->System.out.println(n));

priorityQueue.remove();
System.out.println();

priorityQueue.forEach(n->System.out.println(n));




原文地址:https://www.cnblogs.com/xiang--liu/p/9710379.html