Java复习——Java中的集合

Java中的集合

单值保存的最大父接口:Collection

很少直接使用,一般使用其两个子接口:List与Set。

允许元素重复的接口: List

List接口通常表示一个列表(数组、队列、链表、栈等),其中的元素可以重复,常用实现类为ArrayList和LinkedList,另外还有不常用的Vector。另外,LinkedList还是实现了Queue接口,因此也可以作为队列使用。

ArrayList性能较高,属于异步处理,而Vector性能较低,属于同步处理

ArrayList不是线程安全的,只能在单线程环境下,多线程环境下可以考虑用collections.synchronizedList(List l)函数返回一个线程安全的ArrayList类,也可以使用concurrent并发包下的CopyOnWriteArrayList类。

ArrayList实现了Serializable接口,因此它支持序列化,能够通过序列化传输,实现了RandomAccess接口,支持快速随机访问,实际上就是通过下标序号进行快速访问,实现了Cloneable接口,能被克隆。

不允许元素重复的接口:Set

常用实现类有HashSet和TreeSet,HashSet是通过Map中的HashMap实现的,而TreeSet是通过Map中的TreeMap实现的。另外,TreeSet还实现了SortedSet接口,因此是有序的集合。HashSet是散列结构,没有顺序。特点是查询速度快,通过元素实现hashCode()与equals(),保证元素的唯一性。
TreeSet是二叉树结构,有顺序。通过元素实现Comparable的compareTo()实现排序。

集合的输出操作

迭代输出Iterator

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Temp {
    public static void main(String[] args){
        List list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");
        list.add("1");
        list.add("5");
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println("item : "+iterator.next());
        }
    }
}

双向迭代输出ListIterator

ListIterator则专门用来遍历List。

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class Temp {
    public static void main(String[] args){
        List list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");
        list.add("1");
        list.add("5");
        Iterator iterator = list.listIterator();
        while (iterator.hasNext()) {
            System.out.println("由前往后输出 item : "+iterator.next());
        }

        System.out.println("-----------------------------------------------------------------");

        while (((ListIterator) iterator).hasPrevious()) {
            System.out.println("由后往前输出 item : "+((ListIterator) iterator).previous());
        }
    }
}

JDK 1.5 后,也可以使用foreach进行输出。

Enumeration

基本不使用,Enumeration是JDK1.0时引入的,作用与Iterator相同,但它的功能比Iterator要少,它只能再Hashtable、Vector和Stack中使用。

键值对保存:Map接口

所有内容都是以key——value的形式保存的,每一对key——value都是一个Map.Entry对象实例:

HashMap与HashTable的区别

HashMap是非线程安全的,只是用于单线程环境下,多线程环境下可以采用concurrent并发包下的concurrentHashMap。

HashMap实现了Serializable接口,因此它支持序列化,实现了Cloneable接口,能被克隆。

Map的输出操作

因为Map中的key是用于查找操作的,所以为了唯一性,key的类必须重写hashCode()与equals()

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class Temp {
    public static void main(String[] args){
        HashMap hashMap = new HashMap<>();
        hashMap.put("a",1);
        hashMap.put("b",2);
        hashMap.put("c",3);
        hashMap.put("d",4);
        hashMap.put("e",5);

        Set> entrySet = hashMap.entrySet();
        Iterator> iterator = entrySet.iterator();
        while (iterator.hasNext()) {
            Map.Entry entry = iterator.next();
            String key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println("第一种方式输出 key = "+key+" , value = "+value);
        }

        Set keySet = hashMap.keySet();
        Iterator iterator1 = keySet.iterator();
        while (iterator1.hasNext()) {
            String key = iterator1.next();
            Integer value = hashMap.get(key);
            System.out.println("第二种方式输出 key = "+key+" , value = "+value);
        }
    }
}

Arrays与Collections

Arrays和Collections是用来操作数组、集合的两个工具类,例如在ArrayList和Vector中大量调用了Arrays.Copyof()方法,而Collections中有很多静态方法可以返回各集合类的synchronized版本,即线程安全的版本,当然了,如果要用线程安全的结合类,首选Concurrent并发包下的对应的集合类。

## HashMap和HashTable的底层实现和区别,两者与ConcurrentHashMap的区别

HashTable线程安全则是依靠方法简单粗暴的sychronized修饰,HashMap则没有相关的线程安全问题考虑。Hashtable不允许key或者value使用null值,而HashMap可以。

https://blog.csdn.net/xuefeng0707/article/details/40834595

简单说就是,ConcurrentHashMap通过把整个Map分为N个Segment(类似HashTable),可以提供相同的线程安全,但是效率提升N倍。

## HashMap的hashcode的作用?什么时候需要重写?如何解决哈希冲突?查找的时候流程是如何?
https://blog.csdn.net/wtt945482445/article/details/52673654

hashCode方法实际上返回的就是对象存储位置的映像。

Arraylist和HashMap如何扩容?负载因子有什么作用?如何保证读写进程安全?

扩容:

https://blog.csdn.net/xiaomageit/article/details/48956087

负载因子:(其实就是根据当前大小,进行扩容。所以才有了负载因子是时间和空间上的一种折中的说法。所以设置负载因子的时候要考虑自己追求的是时间还是空间上的少。)

http://hovertree.com/h/bjaf/2jdr60li.htm

ArrayList 本身不是线程安全的。
所以正确的做法是去用 java.util.concurrent 里的 CopyOnWriteArrayList 或者某个同步的 Queue 类。

HashMap实现不是同步的。如果多个线程同时访问一个哈希映射,而其中至少一个线程从结构上修改了该映射,则它必须 保持外部同步。(结构上的修改是指添加或删除一个或多个映射关系的任何操作;仅改变与实例已经包含的键关联的值不是结构上的修改。)这一般通过对自然封装该映射的对象进行同步操作来完成。如果不存在这样的对象,则应该使用 Collections.synchronizedMap 方法来“包装”该映射。最好在创建时完成这一操作,以防止对映射进行意外的非同步访问.

TreeMap、HashMap、LinkedHashMap的底层实现区别。

https://blog.csdn.net/lolashe/article/details/20806319

HashMap、ConcurrentHashMap和SynchronizedMap区别

https://blog.csdn.net/hwz2311245/article/details/51454686

如果要用线程安全的结合类,首选Concurrent并发包下的对应的集合类。

你可能感兴趣的:(Java,Java复习,Java集合)