Java笔记:集合框架

Posted arseneyao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java笔记:集合框架相关的知识,希望对你有一定的参考价值。

一、接口

  • Collection:构建集合框架的基础,定义集合的所有类都必须实现该接口。
  • List:线性表,Collection接口扩展。
  • Set:集,Collection接口扩展。
  • SorttedSet:以升序排序的集,Set接口扩展。
  • NavigableSet:可基于最接近匹配原则检索元素的集,SortedSet接口扩展。
  • Queue:队列,Collection接口扩展。
  • Deque:双端队列,Queue接口扩展。

 

二、集合类

动态数组。

技术分享图片
import java.util.ArrayList;

class Solution {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>(100);//初始大小100
        for (int i = 0; i < 100; i++)
            list.add(i);
        list.ensureCapacity(500);//重置大小为500
        for (int i = 100; i < 500; i++)
            list.add(i);
        Integer[] arr = new Integer[list.size()];
        arr = list.toArray(arr);//获取数组
        for (int i : arr)
            System.out.println(i);
    }
}
View Code

链表。

技术分享图片
import java.util.LinkedList;

class Solution {
    public static void main(String[] args) {
        LinkedList<Integer> list = new LinkedList<>();
        for (int i = 0; i < 100; i++)
            list.add(i);//插入尾元素
        for (int i = 100; i < 200; i++)
            list.push(i);//插入首元素
        list.removeFirst();//删除首元素
        list.removeLast();//删除尾元素
        System.out.println(list);
    }
}
View Code

哈希集。

技术分享图片
import java.util.HashSet;

class Solution {
    public static void main(String[] args) {
        HashSet<Integer> setA = new HashSet<>();//默认容量16
        HashSet<Integer> setB = new HashSet<>(100, (float) 0.8);//初始容量为100,填充率到达0.8时扩容
    }
}
View Code

 

三、迭代器

迭代器是实现了Iterator接口或ListIterator接口的对象。ListIterator接口为Iterator接口的扩展,支持双向遍历。

技术分享图片
import java.util.ArrayList;
import java.util.Iterator;

class Solution {
    public static void main(String[] args) {
        ArrayList<Character> list = new ArrayList<>();
        for (char c = ‘A‘; c <= ‘E‘; c++)
            list.add(c);
        //迭代器遍历
        Iterator<Character> itr = list.iterator();
        while (itr.hasNext())
            System.out.print(itr.next());
        //foreach遍历
        for (char c : list)
            System.out.print(c);
    }
}
View Code

实现了Spliterator的迭代器可循环遍历,并且支持并行迭代。它将hasNext和next合并以提高效率。

技术分享图片
import java.util.ArrayList;
import java.util.Spliterator;

class Solution {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        for (int i = 0; i < 10; i++)
            list.add(i);
        Spliterator<Integer> splitr = list.spliterator();
        while (splitr.tryAdvance((i) -> System.out.println(i)));

        splitr = list.spliterator();
        splitr.forEachRemaining((i) -> System.out.println(i));
    }
}
View Code

 

四、映射

  • Map:将键映射到值。
  • Map.Entry:描述键值对。
  • SortedMap:以升序保存键,Map接口扩展。
  • NavigableMap:基于最接近匹配的键值对检索,SortedMap接口扩展。

哈希映射,无序。

技术分享图片
import java.util.HashMap;

class Solution {
    public static void main(String[] args) {
        HashMap<String, Integer> months = new HashMap<>();
        months.put("Jan", 1);
        months.put("Feb", 2);
        months.put("Mar", 3);
        months.put("Apr", 4);
        months.put("May", 5);
        months.put("June", 6);
        months.put("July", 7);
        months.put("Aug", 8);
        months.put("Sept", 9);
        months.put("Oct", 10);
        months.put("Nov", 11);
        months.put("Dec", 12);

        System.out.println(months.entrySet());
        System.out.println(months.keySet());//[June, Sept, Oct, Feb, Apr, Aug, Dec, May, Nov, Jan, July, Mar]
        System.out.println(months.values());//[6, 9, 10, 2, 4, 8, 12, 5, 11, 1, 7, 3]
    }
}
View Code

红黑树映射,有序。

技术分享图片
import java.util.TreeMap;

class Solution {
    public static void main(String[] args) {
        TreeMap<String, Integer> months = new TreeMap<>();
        months.put("Jan", 1);
        months.put("Feb", 2);
        months.put("Mar", 3);
        months.put("Apr", 4);
        months.put("May", 5);
        months.put("June", 6);
        months.put("July", 7);
        months.put("Aug", 8);
        months.put("Sept", 9);
        months.put("Oct", 10);
        months.put("Nov", 11);
        months.put("Dec", 12);

        System.out.println(months.entrySet());
        System.out.println(months.keySet());//[Apr, Aug, Dec, Feb, Jan, July, June, Mar, May, Nov, Oct, Sept]
        System.out.println(months.values());//[4, 8, 12, 2, 1, 7, 6, 3, 5, 11, 10, 9]
    }
}
View Code

哈希映射链表实现,按插入顺序迭代。

技术分享图片
import java.util.LinkedHashMap;

class Solution {
    public static void main(String[] args) {
        LinkedHashMap<String, Integer> months = new LinkedHashMap<>();
        months.put("Jan", 1);
        months.put("Feb", 2);
        months.put("Mar", 3);
        months.put("Apr", 4);
        months.put("May", 5);
        months.put("June", 6);
        months.put("July", 7);
        months.put("Aug", 8);
        months.put("Sept", 9);
        months.put("Oct", 10);
        months.put("Nov", 11);
        months.put("Dec", 12);

        System.out.println(months.entrySet());
        System.out.println(months.keySet());//[Jan, Feb, Mar, Apr, May, June, July, Aug, Sept, Oct, Nov, Dec]
        System.out.println(months.values());//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
    }
}
View Code

 

五、比较器

如果希望以不同的方式排序元素,可以再构造集合时指定比较器。

Comparator是泛型接口,部分方法如下

  • compare:比较对象的大小。
  • equals:测试比较器的排序顺序是否相同。
  • reversed:获取相反顺序的比较器。
  • reverseOrder:获取相反元素的自然顺序比较器。
  • naturalOrder:获取自然顺序比较器。
  • nullsFirst:认为null比其他值小的比较器。
  • nullsLast:认为null比其他值大的比较器。
  • thenComparing:当首次比较相等时指定其他比较器。
技术分享图片
import java.util.Comparator;
import java.util.TreeSet;

class Student {
    String name;
    int total;

    Student(String name, int total) {
        this.name = name;
        this.total = total;
    }

    @Override
    public String toString() {
        return name + " " + total;
    }
}

class StudentComparator implements Comparator<Student> {
    @Override
    public int compare(Student a, Student b) {
        if (a.total != b.total)
            return a.total - b.total;
        else return a.name.compareTo(b.name);
    }
}

class Solution {
    public static void main(String[] args) {
        TreeSet<Student> set = new TreeSet<>(new StudentComparator().reversed());
        StringBuilder nameBuilder = new StringBuilder();
        for (int i = 0; i < 1000; i++) {
            int total = (int) (750 * Math.random());
            for (int j = 0; j < 3; j++)
                nameBuilder.append((char) (25 * Math.random() + 65));
            set.add(new Student(nameBuilder.toString(), total));
            nameBuilder.delete(0, nameBuilder.length());
        }
        System.out.println(set);
    }
}
View Code

函数式接口。

技术分享图片
Comparator<Student> comp = (a, b) -> {
    if (a.total != b.total)
        return a.total - b.total;
    else return a.name.compareTo(b.name);
};
TreeSet<Student> set = new TreeSet<>(comp);
View Code

thenComparing。

技术分享图片
import java.util.Comparator;
import java.util.TreeSet;

class Student {
    String name;
    int total;

    Student(String name, int total) {
        this.name = name;
        this.total = total;
    }

    @Override
    public String toString() {
        return name + " " + total;
    }
}

class ComparatorA implements Comparator<Student> {
    @Override
    public int compare(Student a, Student b) {
        return a.total - b.total;
    }
}

class ComparatorB implements Comparator<Student> {
    @Override
    public int compare(Student a, Student b) {
        return a.name.compareTo(b.name);
    }
}

class Solution {
    public static void main(String[] args) {
        ComparatorA compA = new ComparatorA();
        Comparator<Student> comp = compA.thenComparing(new ComparatorB());
        TreeSet<Student> set = new TreeSet<>(comp);
        StringBuilder nameBuilder = new StringBuilder();
        for (int i = 0; i < 1000; i++) {
            int total = (int) (750 * Math.random());
            for (int j = 0; j < 3; j++)
                nameBuilder.append((char) (25 * Math.random() + 65));
            set.add(new Student(nameBuilder.toString(), total));
            nameBuilder.delete(0, nameBuilder.length());
        }
        System.out.println(set);
    }
}
View Code


六、集合算法

集合框架定义了可用于集合和映射的算法,这些算法被定义为Collections中的静态方法。

技术分享图片
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;

class Solution {
    public static void main(String[] args) {
        LinkedList<Integer> list = new LinkedList<>();
        for (int i = 0; i < 10; i++)
            list.add(i);
        Comparator<Integer> comp = Collections.reverseOrder();//获取整数的反向比较器
        Collections.sort(list, comp);
        System.out.println(list);//[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
        System.out.println(Collections.max(list));
        System.out.println(Collections.min(list));
        Collections.shuffle(list);//随机化
        System.out.println(list);
    }
}
View Code

数组算法。

技术分享图片
import java.util.Arrays;
import java.util.Collections;
import java.util.Spliterator;
import java.util.stream.Stream;

class Solution {
    public static void main(String[] args) {
        Integer[] arr = {1, 2, 3, 4, 5};
        System.out.println(Arrays.binarySearch(arr, 0));//-1
        Integer[] cpyA = Arrays.copyOf(arr, 3);//1 2 3
        Integer[] cpyB = Arrays.copyOfRange(arr, 0, 3);//1 2 3
        System.out.println(Arrays.equals(cpyA, cpyB));

        Arrays.sort(arr, Collections.reverseOrder());
        Arrays.parallelSort(arr);//并行排序

        Spliterator<Integer> splitr = Arrays.spliterator(arr);//获取迭代器
        Stream<Integer> stream = Arrays.stream(arr);//获取流
    }
}
View Code

 

七、遗留类与接口

Vector实现了动态数组。ArrayList与其的主要区别是Vector是同步的,并且包含许多遗留方法。

技术分享图片
import java.util.Collections;
import java.util.Vector;

class Solution {
    public static void main(String[] args) {
        Vector<Integer> vector = new Vector<>();
        for (int i = 0; i < 100; i++)
            vector.addElement(i);
        vector.sort(Collections.reverseOrder());
        for (int i = 0; i < vector.size(); i++)
            System.out.println(vector.elementAt(i));
    }
}
View Code

Stack是Vector的子类,实现了标准的堆栈。不反对使用,但ArrayDeque是更好的选择。

技术分享图片
import java.util.Stack;

class Solution {
    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        for (int i = 0; i < 100; i++)
            stack.push(i);
        while (!stack.empty())
            System.out.println(stack.pop());
    }
}
View Code

Dictionary是表示键值对存储库的抽象类。已被Map完全取代,不推荐使用。
Hashtable原本是Dictionary的具体实现,随着集合的出现Hashtable被重新设计并实现了Map接口。Hashtable与HashMap的主要区别是Hashtable是线程安全的,两者的底层均是数组+链表实现,填充率均为0.75,但Hashtable不直接支持迭代器。

技术分享图片
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;

class Solution {
    public static void main(String[] args) {
        Hashtable<String, Integer> table = new Hashtable<>();
        table.put("A", 1);
        table.put("C", 2);
        table.put("B", 4);
        table.put("E", 3);
        table.put("D", 5);
        Set<String> set = table.keySet();
        Iterator<String> itr = table.keySet().iterator();
        while (itr.hasNext())
            System.out.println(itr.next());
    }
}
View Code

Properties是Hashtable的子类,用于保存值的列表。Properties可以指定默认属性。如果没有值与特定键关联,就会返回默认属性。

技术分享图片
import java.util.Properties;

class Solution {
    public static void main(String[] args) {
        Properties p = new Properties();
        p.put("A", "1");
        p.put("B", "2");
        p.put("C", "3");
        System.out.println(p.getProperty("E", "-1"));//-1
    }
}
View Code

使用store方法和load方法可以将Properties存储到磁盘以及从磁盘中加载。

技术分享图片
import java.io.*;
import java.util.Properties;

class Solution {
    public static void main(String[] args) throws IOException {
        Properties information = new Properties();
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String name, number;
        FileInputStream fin = null;
        try {
            fin = new FileInputStream("file.txt");
        } catch (FileNotFoundException exc) {
            System.out.println("File not found");
        }
        try {
            if (fin != null) {
                information.load(fin);//载入信息
                fin.close();
            }
        } catch (IOException exc) {
            System.out.println("Error reading file");
        }
        name = reader.readLine();
        number = reader.readLine();
        information.put(name, number);
        FileOutputStream fout = new FileOutputStream("file.txt");
        information.store(fout, "Information");//存储信息
        fout.close();
    }
}
View Code

 



以上是关于Java笔记:集合框架的主要内容,如果未能解决你的问题,请参考以下文章

Java学习笔记29(集合框架三:泛型)

JAVA 笔记 从源码深入浅出集合框架

阿花宝宝 Java基础笔记 之 集合框架

Java笔记:集合框架

jdk源码阅读笔记之java集合框架(基础篇)

Java基础学习笔记十六 集合框架