温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java集合是什么

发布时间:2021-09-10 11:00:24 来源:亿速云 阅读:193 作者:小新 栏目:编程语言

这篇文章主要介绍了Java集合是什么,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

Java集合

1.什么是集合

概念:集合是存放对象的容器,并定义了对多个对象进行操作的常用方法,可实现数组的功能。

和数组的区别:

  • (1)数组长度固定,集合长度不固定;

  • (2)数组可以存储基本类型和引用类型,集合只能存储引用类型。

位置:java.util.*;

2.Collection体系集合

Java集合是什么

3.Collection接口

Collection接口通过顶层设计定义了许多针对集合的操作,大致可以分为增、删、遍历、判断等几个方面的方法。

boolean add(E e) 确保此集合包含指定的元素(可选操作)。  
boolean addAll(Collection<? extends E> c) 将指定集合中的所有元素添加到这个集合(可选操作)。

void clear() 从这个集合中移除所有的元素(可选操作)。  
boolean remove(Object o) 从这个集合中移除指定元素的一个实例,如果它是存在的(可选操作)。  
boolean removeAll(Collection<?> c) 删除此集合中包含的所有元素(可选操作)的所有元素(可选操作)。 
default boolean removeIf(Predicate<? super E> filter) 删除满足给定谓词的这个集合的所有元素。  
boolean retainAll(Collection<?> c) 仅保留包含在指定集合中的这个集合中的元素(可选操作)。

遍历

Iterator<E> iterator() 返回此集合中的元素的迭代器。   
Object[] toArray() 返回包含此集合中所有元素的数组。  
<T> T[] toArray(T[] a) 返回包含此集合中所有元素的数组;返回数组的运行时类型是指定的数组的运行时类型。

判断

boolean contains(Object o) 返回 true如果集合包含指定元素。  
boolean containsAll(Collection<?> c) 返回 true如果这个集合包含指定集合的所有元素。  
boolean isEmpty() 返回 true如果集合不包含任何元素。

其它

int size() 返回此集合中的元素的数目。  
boolean equals(Object o) 将指定的对象与此集合进行比较,以进行相等性。  
int hashCode() 返回此集合的哈希代码值。

4.Collection的使用

遍历常用的两种方法:forEach和Iterator

public class Demo1 {
    public static void main(String[] args) {
        Collection collection = new ArrayList();
        collection.add("苹果");
        collection.add("香蕉");
        collection.add("西瓜");
        //1.foreach
        for(Object object : collection) {
            System.out.println(object);
        }
        
        /**
         * 2.使用Iterator,其包含三个方法:
         * hasnext():判断是否有下一个元素
         * next():获取下一个元素
         * remove():删除迭代器返回的最后一个元素
         */
        Iterator it = collection.iterator();
        while(it.hasNext()) {
            String object = (String)it.next();
//            collection.remove(object); 不能使用被遍历集合的删除方法,会报并发修改异常
            it.remove();
            System.out.println(object);
        }
        System.out.println(collection.size());
    }
}

5.List子接口

(1)基本情况

特点:有序、有下标、元素可以重复。

List在父接口Collection的基础上新增了许多方法。

void add(int index, E element) 在列表中指定的位置上插入指定的元素(可选操作)。  
boolean addAll(Collection<? extends E> c) 追加指定集合的所有元素到这个列表的末尾,按他们的指定集合的迭代器返回(可选操作)。

E remove(int index) 移除此列表中指定位置的元素(可选操作)。

遍历

ListIterator<E> listIterator() 返回列表元素的列表迭代器(在适当的顺序)。  
ListIterator<E> listIterator(int index) 在列表中的元素上返回列表迭代器(在适当的顺序),从列表中的指定位置开始。

其它

Object get(int index) 根据下标返回指定位置元素
int indexOf(Object o) 返回此列表中指定元素的第一个出现的索引,或-如果此列表不包含元素,或- 1。  
List subList(int fromIndex, int toIndex) 返回指定索引之间的集合元素
E set(int index, E element) 用指定元素替换此列表中指定位置的元素(可选操作)。  
default void sort(Comparator<? super E> c) 分类列表使用提供的 Comparator比较元素。
(2)遍历

1.for、foreach、Collection提供的迭代器接口

public class Demo2 {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("华为");
        list.add("苹果");
        list.add("小米");
        //1.for
        for(int i=0; i<list.size(); i++) {
            System.out.println(list.get(i));
        }

        //2.forEach
        for(Object str : list) {
            System.out.println(str);
        }

        //3.迭代器
        Iterator it = list.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }
    }
}

2、使用ListIterator

//顺序遍历
ListIterator lit = list.listIterator();
while(lit.hasNext()) {
    System.out.println(lit.next());
}
//逆序遍历
while (lit.hasPrevious()) {
    System.out.println(lit.previous());
}

ListIterator常用方法

boolean hasNext()  返回 true如果列表迭代器具有更多的元素时,正向遍历列表。  
boolean hasPrevious() 返回 true如果列表迭代器具有更多的元素时,逆向遍历列表。  
E next() 返回列表中的下一个元素,并推进光标位置。  
E previous() 返回列表中的前一个元素,并向后移动光标位置。  
void remove() 从列表中删除最后一个元素是由 next()或 previous()返回(可选操作)。

6.List实现类

三种实现类
  • ArrayList【重点】

    • 数组结构实现,查询快、增删慢;

    • 运行效率快、线程不安全。

  • LinkedList

    • 双向链表实现,增删快,查询慢。

  • Vector(很少使用)

    • 数组结构实现;

    • 运行效率慢、线程安全

重写equals()方法

当要删除List中的指定对象时,需要比较两个对象是否相同,如果要实现不根据同一引用删除属性相同的对象,此时需要在该对象类中重写equals方法,如下为经典的重写方法,记下来。

@Override
public boolean equals(Object obj) {
    //是否为同一对象
    if (this == obj) {
        return true;
    }
    //是否为空
    if (this == null) {
        return false;
    }
    //是否为同类对象
    if (obj instanceof Student) {
        Student s = (Student) obj;
        //比较属性是否相等
        if(this.name = s.name && this.age == s.age){
            return true;
        }
    }
    return false;
}
ArraysList源码解析

重要参数:

  • int size:元素数目;

  • Object[] elementData:保存元素的数组;

add()方法源码解析

public boolean add(E e) {
    modCount++;
    add(e, elementData, size);
    return true;
}
private void add(E e, Object[] elementData, int s) {
    //数组存放满了,扩容
    if (s == elementData.length)
        elementData = grow();
    elementData[s] = e;
    size = s + 1;
}

//扩容
private Object[] grow() {
    return grow(size + 1);
}
//将旧数组扩容
private Object[] grow(int minCapacity) {
    return elementData = Arrays.copyOf(elementData,
                                       newCapacity(minCapacity));
}
private int newCapacity(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity <= 0) {
        //数组为空
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return minCapacity;
    }
    return (newCapacity - MAX_ARRAY_SIZE <= 0)
        ? newCapacity
        : hugeCapacity(minCapacity);
}

private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE)
        ? Integer.MAX_VALUE
        : MAX_ARRAY_SIZE;
}
LinkedList源码解析

相关参数:

  • int size:集合的大小

  • Node first:链表头节点

  • Node last:链表尾节点

add方法源码

public boolean add(E e) {
    linkLast(e);
    return true;
}
/**
  * Links e as last element.
  */
void linkLast(E e) {
    final Node<E> l = last;
    final Node<E> newNode = new Node<>(l, e, null);
    last = newNode;
    if (l == null)
        first = newNode;
    else
        l.next = newNode;
    size++;
    modCount++;
}
private static class Node<E> {
    E item;
    Node<E> next;
    Node<E> prev;

    Node(Node<E> prev, E element, Node<E> next) {
        this.item = element;
        this.next = next;
        this.prev = prev;
    }
}

7.泛型

泛型概念
  • Java泛型的本质是参数化类型,把类型作为参数传递;

  • 常见形式有泛型类、泛型接口、泛型方法;

  • 语法:

    • <T,...> T称为类型占位符,表示一种引用类型;

  • 好处:

    • (1)提高代码的重用性;

    • (2)防止类型转换异常,提高代码的安全性。

泛型类

1.定义泛型类及泛型的用途

/**
 * 泛型类
 * 语法:类名<T>
 *     T 是类型占位符,表示一种引用类型,如果编写多个则使用逗号隔开
 * @param <T>
 */
public class MyGeneric<T> {
    //使用泛型
    //1.创建变量
    T t;
    
    //2.泛型作为方法的参数
    public void show(T t) {
        System.out.println(t);
    }
    
    //3.泛型作为方法的返回值
    public T getT() {
        return t;
    }
}

2.使用泛型

注意:

  • (1)泛型只能使用引用类型;

  • (2)不同泛型类型对象之间不能相互赋值。

public class TestGeneric {
    public static void main(String[] args) {
        MyGeneric<String> myGeneric = new MyGeneric<>();
        myGeneric.t = "苹果";
        myGeneric.show("吃苹果");

        MyGeneric<Integer> myGeneric1 = new MyGeneric<>();
        myGeneric.t = "100";
        myGeneric.show("打100分");
    }
}
泛型接口

(1)定义泛型

/**
 * 泛型接口
 * 语法:接口名<T>
 * 注意:不能使用泛型创建静态常量
 */
public interface MyInterface<T> {
    String name = "apple";

    T server(T t);
}

(2)使用泛型

//1.写实现类时指定类型
public class MyInterfaceImpl implements MyInterface<String>{
    @Override
    public String server(String s) {
        return s;
    }
}

//2.创建对象时再指定类型
public class MyInterfaceImpl1<T> implements MyInterface<T> {
    @Override
    public T server(T t) {
        return t;
    }
}
public class TestGeneric {
    public static void main(String[] args) {
        MyInterfaceImpl1<String> myInterfaceImpl1 = new MyInterfaceImpl1<>();
        System.out.println(myInterfaceImpl1.server("apple1"));
    }
}
泛型方法

(1)定义

/**
 * 泛型方法
 * 语法:<T> 返回值类型
 */
public class GenericMethod {
    //泛型方法, 泛型T可以作为方法的参数或返回值
    public <T> void show(T t) {
        System.out.println(t);
    }
}

(2)使用

在使用时传入具体类型的值。

public class TestGeneric {
    public static void main(String[] args) {
        GenericMethod genericMethod = new GenericMethod();
        genericMethod.show("apple");
        genericMethod.show(200);
        genericMethod.show(3.14);
    }
}
泛型集合

概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致。

特点:

  • 编译时即可检查,而非运行时抛出异常;

  • 访问时,不必类型转换(拆箱);

  • 不同泛型之间引用不能相互赋值,泛型不存在多态。

public class TestGeneric {
    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList();
        arrayList.add("apple");
        arrayList.add("banana");
        arrayList.add(100);
        arrayList.add(3.14);
        for (Object object : arrayList) {
            System.out.println(object);
        }

        //使用泛型限定传入的元素类型
        ArrayList<String> arrayList1 = new ArrayList<>();
        arrayList1.add("apple");
        arrayList1.add(100); //添加其它类型时会报错
    }
}

8.Set子接口

特点:无序、无下标、元素不可重复;

方法:全部继承自Collection中的方法。

1.Set实现类
  • HashSet【重点】

    • 基于HashCode实现元素不重复和确认元素存放位置;

    • 当存入元素的哈希码相同时,会调用equals进行确认,如结果为true,则拒绝后者存入。

  • TreeSet

    • 基于排列顺序实现元素不重复。

2.遍历

使用foreach和Iterator。

public class Demo7 {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        set.add("Jack"); set.add("Lucy"); set.add("Micheal");
		//1.foreach
        for(String string : set)
            System.out.println(string);
        
        //2.Iterator
        Iterator it = set.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }
    }
}
3.HashSet

存储结构:哈希表(数组+链表+红黑树);

存储过程:

  • (1)根据元素的hashcode计算保存的位置,如果该位置为空,则直接保存,否则指定第(2)步;

  • (2)再执行equals方法,如果equals返回true,则认为存在重复元素,不添加,如果为false,则在保存位置形成链表,当链表中元素数量超过指定值时,形成红黑树。

重写hashcode()与equals()方法

@Override
public int hashCode() {
    return Objects.hash(age, name);
}    

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    //getClass()返回对象的hashcode
    if (o == null || getClass() != o.getClass()) return false;
    Person person = (Person) o;
    return age == person.age &&
        Objects.equals(name, person.name);
}
4.TreeSet
  • 基于排列顺序实现元素不重复;

  • 实现了SortedSet接口,对集合元素自动排序;

  • 元素对象的类型必须实现Comparable接口,指定顺序规则;

  • 通过CompareTo方法确定是否为重复元素。

存储结构:红黑树

(1)存储元素为对象时必须实现Comparable接口

并重写其中的compareTo方法,否则元素之间无法比较大小,不能排序,会报类型转换错误。

compareTo()返回为0,表示元素重复。

foreach与迭代器方式
package collectionTest;

import java.util.Objects;

public class Person implements Comparable{
	//TODO
    @Override
    public int compareTo(Object o1) {
        Person o = (Person)o1;
        int n1 = this.getName().compareTo(o.getName());
        int n2 = this.getAge() - o.getAge();
        return n1 == 0 ? n2 : n1;
    }
}

(2)Comparator

实现定制的比较器,并在创建TreeSet时传入该比较器指定比较规则,如此存储的元素对象便不用实现Comparable接口。

public class Demo3 {
    public static void main(String[] args) {
        //使用匿名内部类
        TreeSet<Person> hashSet = new TreeSet<>(new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                int n2 = o1.getName().compareTo(o2.getName());
                int n1 = o1.getAge() - o2.getAge();
                return n1 == 0 ? n2 : n1;
            }
        });
    }
}

9.Map集合

Java集合是什么

Map父接口

特点:存储键值对,无序、无下标,键不可重复,值可重复。

方法:

  • V put(K key, V value)  将指定的值与该映射中的指定键相关联(可选操作)。  
    V get(Object key) 返回到指定键所映射的值,或 null如果此映射包含该键的映射。    
    Set<K> keySet() 返回此集合中包含的键的Set集合。  
    Collection<V> values() 返回此集合中包含的值的Collection集合。 
    Set<Map.Entry<K,V>> entrySet() 返回此集合中包含的映射的Set集合。


遍历
  • (1)使用keySet()

  • (2)使用entrySet()

    • entryset()的效率较高,因为一次性获取到了映射对的key和value值。

public class Demo5 {
    public static void main(String[] args) {
        HashMap<Integer, String> hashMap = new HashMap<>();
        hashMap.put(1, "Jack");
        hashMap.put(2, "Lucy");
        hashMap.put(3, "asdfaJack");
        hashMap.put(4, "DLucy");
        
		//1.keySet()
//        Set<Integer> keySet = hashMap.keySet();
        for(Integer key : hashMap.keySet()) {
            System.out.println(key + " : " + hashMap.get(key));
        }
		
        //2.entrySet()
//        Set<Map.Entry<Integer, String>> entries = hashMap.entrySet();
        for(Map.Entry<Integer, String> entry : hashMap.entrySet()) {
            System.out.println(entry.getKey() + " : " + entry.getValue());
        }
    }
}
Map集合的实现类
  • HashMap:线程不安全,运行效率快;允许使用null作为key或value;

  • Hashtable:线程安全,运行效率慢,不允许null作为key或value。

    • Properties:Hashtable的子类,要求key和value都是String,通常用于配置文件的读取。

  • TreeMap:实现了SortedMap接口(是Map的子接口),可以对key自动排序。

HashMap源码解析

相关参数

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // hashmap初始容量大小
static final int MAXIMUM_CAPACITY = 1 << 30; //hashmap数组最大容量
static final float DEFAULT_LOAD_FACTOR = 0.75f; //默认装载因子
static final int TREEIFY_THRESHOLD = 8; //jdk1.8 当链表长度大于8时,调整成红黑树
static final int UNTREEIFY_THRESHOLD = 6; //链表长度小于6,调整成链表
static final int MIN_TREEIFY_CAPACITY = 64; //jdk1.8 当链表长度大于8且集合元素个数大于等于64时,调整成红黑树。
transient Node<K,V>[] table;  //哈希表中的数组
transient size; //元素个数

构造函数

public HashMap() {
    this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}

//刚创建的hashmap没有添加元素,table=null,size=0
HashMap<Integer, String> hashMap = new HashMap<>();

put() 方法解析,待深入了解。

public V put(K key, V value) {
    return putVal(hash(key), key, value, false, true);
}
TreeMap

TreeMap与TreeSet一样,底层都是由红黑树实现,是有序的,因此元素之间必须是可比较的,可以通过让元素继承Comparable或者在调用TreeMap的构造方法时传入自制比较器实现。

遍历方式

(1)使用keySet()
(2)使用entrySet()
public class Demo6 {
    public static void main(String[] args) {
        TreeMap<Student, String> treeMap = new TreeMap<>();
        Student s1 = new Student(11, "Jack");
        Student s2 = new Student(17, "adfJack");
        Student s3 = new Student(14, "dafJack");
        Student s4 = new Student(12, "fJdack");
        treeMap.put(s1, "nihao");
        treeMap.put(s2, "nihao");
        treeMap.put(s3, "nihao");
        treeMap.put(s4, "nihao");

        for(Student key : treeMap.keySet()) {
            System.out.println(key + " : " + treeMap.get(key));
        }
        
        for(Map.Entry<Student, String> entry : treeMap.entrySet()) {
            System.out.println(entry.getKey() + " : " + entry.getValue());
        }
    }
}

class Student implements Comparable{
    private int age;
    private String name;
    //TODO
}

10.Collections工具类

概念:集合工具类,定义了出了存取以外的集合常用方法。

方法

void sort(List<T> list) 指定列表为升序排序,根据其元素的 natural ordering。  
void sort(List<T> list, Comparator<? super T> c) 根据指定的比较器指定的顺序对指定的列表进行排序。 

static void reverse(List<?> list) 反转指定列表中元素的顺序。  
static void shuffle(List<?> list) 随机置换指定列表使用随机默认源。  
static void swap(List<?> list, int i, int j) 在指定的列表中的指定位置上交换元素。  
static <T> void copy(List<? super T> dest, List<? extends T> src) 将所有的元素从一个列表复制到另一个列表中。

copy函数,必须保证dst的长度与src一致。

public class Demo7 {
    public static void main(String[] args) {
        List<Integer> src = new ArrayList<>();
        src.add(1);src.add(2);src.add(100);src.add(89);
        List<Integer> dst = new ArrayList<>();
        //让dst的长度与src一致
        for(int i=0; i<src.size(); i++)
            dst.add(0);
        Collections.copy(dst, src);
        System.out.println(dst);
    }
}

11.Arrays工具类

方法

static <T> List<T> asList(T... a) 返回由指定数组支持的一个固定大小的列表。

List转数组

public class Demo7 {
    public static void main(String[] args) {
        List<Integer> src = new ArrayList<>();
        src.add(1);src.add(2);src.add(100);src.add(89);
        //传入数组类型作为参数
        Integer[] integers = src.toArray(new Integer[0]);
        System.out.println(Arrays.toString(integers));
    }
}

数组转集合

public class Demo7 {
    public static void main(String[] args) {
        Integer[] integers = new Integer[] {1, 2, 3, 4, 5};
        List<Integer> list = Arrays.asList(integers);
        System.out.println(list);
    }
}

感谢你能够认真阅读完这篇文章,希望小编分享的“Java集合是什么”这篇文章对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,更多相关知识等着你来学习!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI