编程语言
首页 > 编程语言> > Java 集合

Java 集合

作者:互联网

目录

Java 集合

一、 Collection集合

1、 集合概述

集合和数组都是容器

数组的特点:

集合的特点:

Collection集合体系

Collection 集合特点:

集合对于泛型的支持:

集合和泛型不支持基本类型,只支持引用数据类型

2、 常用API

Collection是单例集合的祖宗接口,它的功能是全部单例集合都可以继承使用的

package collection;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

public class Main {
    public static void main(String[] args) {
        // HashSet:添加的元素都是无序,不重复,无索引的
        Collection<String> list = new ArrayList<>();
        
        // 添加元素:添加成功返回true
        list.add("java");
        list.add("python");
        list.add("C");
        System.out.println(list);
        
        // 清空集合的元素
        // list.clear();
        
        // 判断集合是否为空,是则返回true
        System.out.println(list.isEmpty());
        
        // 获取集合的大小
        System.out.println(list.size());
        
        // 判断集合中是否包含某个元素
        System.out.println(list.contains("python"));
        
        // 删除某个元素:如果有多个重复元素,默认删除前面的第一个
        System.out.println(list.remove("C"));
        
        // 把集合转换成数组
        Object[] arrs = list.toArray();  // 注意不能集合里面不能完全确定一种数据类型
        System.out.println("数组内容:" + Arrays.toString(arrs));
        
        System.out.println("-------------------扩展-----------------------");
        Collection<String> c1 = new ArrayList<>();
        Collection<String> c2 = new ArrayList<>();
        c2.addAll(c1);  // 把C1中的元素全部导入c2中
    }
}

3、 集合的遍历

3.1 迭代器

迭代器遍历的概述:

集合获取迭代器

方法名称 说明
Iterator<E> iterator() 返回集合中的迭代器对象,该迭代器默认指向当前集合的首地址

迭代器常用方法

方法名称 说明
boolean hasNext() 询问当前位置是否有元素存在,存在返回true
E next() 获取当前位置的元素,并同时将迭代器对象移向下一个位置,注意防止取出越界
package collection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Main {
    public static void main(String[] args) {
        Collection<String> lis = new ArrayList<>();
        lis.add("李华");
        lis.add("赵华");
        lis.add("张华");
        lis.add("小华");
        System.out.println(lis);

        // 得到当前集合的迭代器对象
        Iterator<String> it = lis.iterator();
        while (it.hasNext()) {
            // 遍历迭代器对象
            System.out.println(it.next());
        }
    }
}

3.2 for

增强for循环

格式:

for (元素数据类型 变量名: 数组或者Collection集合) {
	// 在此处使用变量即可,该变量就是元素
}
package collection;

import java.util.ArrayList;
import java.util.Collection;

public class Main {
    public static void main(String[] args) {
        Collection<String> lis = new ArrayList<>();
        lis.add("李华");
        lis.add("赵华");
        lis.add("张华");
        lis.add("小华");
        System.out.println(lis);

        for (String ele:
             lis) {
            // 在遍历内部修改元素值是无意义的,其不会改变原来的值
            System.out.println(ele);
        }
    }
}

3.3 lambda

Lambda表达式遍历集合:

Collection结合Lambda遍历API:forEach()

package collection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;

public class Main {
    public static void main(String[] args) {
        Collection<String> lis = new ArrayList<>();
        lis.add("李华");
        lis.add("赵华");
        lis.add("张华");
        lis.add("小华");
        System.out.println(lis);
    
        lis.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
        
        lis.forEach(s -> {
            System.out.println(s);
        });
    }
}

4、 Collection工具类

4.1 排序

方法名称 说明
public static <T> void sort(List<T> list) 将集合中元素按照默认规则排序
public static <T> void sort(List<T> list, Comparator<? super T> c) 将集合中的元素指定规则进行排序

4.2 常用API

方法名称 说明
public static <T> boolean addAll(Collection<? super T> c, T...elements) 给集合对象批量添加元素
public static void shuffle(List<?> list) 打乱List集合元素的顺序

二、 常见数据结构

1、 概述、栈、队列

1.1 概述

数据结构是计算机底层存储,组织数据的方式。是指数据相互之间是以什么方式排列在一起的

通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率

常见的数据结构:

1.2 栈

栈数据结构的执行特点:

数据进入栈模型的过程称为:压栈、进栈

数据离开栈模型的过程称为:弹栈、出栈

1.3 队列

队列数据结构的执行特点:

数据从后端进入队列模型的过程称为:入队列

数据从前端离开队列模型的过程称为:出队列

2、 数组

内存中的连续区域

特点:

数组是一种查询快,增删慢的模型

3、 链表

特点:

链表是一种查询慢、增删快的模型(对比数组)

单向链表

双向链表

4、 二叉树

二叉树里面存储了:父节点地址、值、左子节点地址、右子节点地址

特点:

二叉查找树又称二叉排序树或者二叉搜索树

特点:

目的:提高检索数据的性能

存储规则:

​ 小的存左边

​ 大的存右边

​ 一样的不存

5、 平衡二叉树

平衡二叉树是在满足查找二叉树的大小规则下,让树尽可能矮小,以此提高查数据的性能

要求:

平衡二叉树在添加元素后可能导致不平衡

平衡二叉树旋转的四种情况

6、 红黑树

红黑树是一种自平衡的二叉查找树,是计算机科学中用到的一种数据结构

每一个节点可以是红或者黑;红黑树不是通过高度平衡的,它的平衡是通过“红黑规则”进行实现的

红黑规则:

添加节点:

红黑树增删改查的性能都很好

三、 List系列集合

1、 集合特点、特有API

1.1 集合特点

ArrayList、 LinkedList:有序、可重复、有索引

1.2 特有API

List集合因为支持索引,所以多了解索引操作的独特API,其他Collection的功能List也都继承了

方法名称 说明
void add(int index, E element) 在此集合中的指定索引插入指定的元素
E remove(int index) 删除指定索引处的元素,返回被删除的元素
E get(int index) 返回指定索引处的元素
E set(int index, E element) 修改指定索引处的元素,返回被修改的元素

2、 遍历

  1. 迭代器
  2. 增强for循环
  3. Lambda表达式
  4. for循环(存在索引)
package collection;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class Main {
    public static void main(String[] args) {
        List<String> lis = new ArrayList<>();
        lis.add("李华");
        lis.add("赵华");
        lis.add("张华");
        lis.add("小华");
        System.out.println(lis);

        // 索引遍历
        for (int i = 0; i < lis.size(); i++) {
            System.out.println(lis.get(i));
        }
        
        // foreach遍历
        lis.forEach(s -> {
            System.out.println(s);
        });
        // 还有其他的遍历方法
    }
}

3、 LinkedList

方法名称 说明
public void addFirst(E e) 在该列表开头插入指定的元素
public void addLast(E e) 在指定的元素追加到此列表的末尾
public E getFirst() 返回此列表中的第一个元素
public E getLast() 返回此列表中的最后一个元素
public E removeFirst() 从此列表中删除并返回第一个元素
public E removeLast() 从此列表中删除并返回最后一个元素

LinkedList 可以完成队列结构和栈结构(双链表)

四、 泛型深入

1、 泛型概述

泛型:是JDK5中引入的特性,可以在编译阶段约束操作的数据类型,并进行检查

泛型的格式:<数据类型>;注意:泛型只能支持引用数据类型

集合体系的全部接口和实现类都是支持泛型的使用的

泛型的好处:

2、 泛型的定义

泛型可以在很多地方进行定义:

2.1 泛型类

定义类时,同时定义了泛型的类就是泛型类

泛型类的格式:修饰符 class 类名<泛型变量>{}

class A<T> {
    // 此处泛型变量T可以随便写为任意标识,常见的如E/T/K/V等
}

作用:编译阶段可以指定数据类型,类似于集合的作用

模拟ArrayList集合自定义一个集合:

package collection;
import java.util.ArrayList;

public class MyArrayList<E> {
    // 需求,模拟ArrayLIst定义一个泛型设计
    private ArrayList<E> lis = new ArrayList<>();
    
    public void add(E e) {
        // 添加数据功能
        lis.add(e);
    }
    
    public void remove(E e) {
        // 移除数据功能
        lis.remove(e);
    }

    @Override
    public String toString() {
        // 输出功能
        return lis.toString();
    }
}

2.2 泛型方法

定义方法的同时定义了泛型方法就是泛型方法

泛型方法的格式:修饰符 <泛型变量> 方法返回值类型 方法名称(形参列表){}

package collection;

public class Main {
    public static void main(String[] args) {
        show("hello");  // 自动判断数据类型
    }
    public static <T> void show(T t) {
        System.out.println(t);
    }
}

泛型方法的核心思想:

作用:

2.3 泛型接口

使用了泛型定义的接口就是泛型接口

泛型接口的格式:修饰符 interface 接口名称 <泛型变量>{}

作用:泛型接口可以让实现类选择当前功能需要操作的数据类型

package collection;

public interface Data<T> {
    // 对数据进行操作
    void add(T s);
    void delete(T s);
    T queryById(int id);
}

3、 通配符

?可以在“使用泛型”的时候代表一切类型

泛型的上下限:

五、 Set系列集合

1、 概述

特点:

实现类特点:

2、 常用API

Set系列的API大部分继承自Collection,几乎没有新的API

package set_;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class SetDemo {
    public static void main(String[] args) {
        // 创建
        Set<String> sets = new HashSet<>();
        // 添加数据
        sets.add("hello");
        sets.add("world");
        sets.add("python");
        // 移除数据
        sets.remove("hello");
        System.out.println(sets);

        // 遍历数据
        for (String s:
            sets) {
            System.out.println(s);
        }
        sets.forEach(s -> {
            System.out.println(s);
        });
        Iterator<String> it = sets.iterator();  // 转换成迭代器
        while (it.hasNext()) {
            System.out.println(it.next());
        }
    }
}

3、 HashSet底层原理

HashSet集合底层原理采取哈希表存储的数据

哈希表是一种对于增删改查数据性能都较好的结构

组成:

哈希值:

哈希值特点:

Set集合去重原理,先判断哈希值,再判断equals

如果是要进行自定义数据类型以及复杂数据类型的去重,需要我们重写equalshashCode方法

4、 LinkedHashSet

特点:有序、不重复、无索引

原理:底层数据结构依然是哈希表,只是每个元素又额外多了一个双链表的机制记录存储的顺序

5、 TreeSet

特点:不重复、无索引、可排序

可排序:按照元素的大小默认升序(由小到大)排序

TreeSet集合底层是基于红黑树的数据结构实现排序的,增删改查性能都较好

集合默认排序规则:

6、 可变参数

可变参数用在形参中可以接收多个数据

可变参数的格式:数据类型...参数名称

作用:

可变参数的注意事项:

package set_;

import java.util.Arrays;

public class SetDemo {
    public static void main(String[] args) {
        sum(1);
        sum(1, 2, 3);
        sum(new int[]{1, 3, 6, 2});

    }
    public static void sum(int...sum_) {
        System.out.println(Arrays.toString(sum_));  // 输出整型数组的内容
    }
}

六、 Map系列集合

1、 概述

Map集合是一种双列集合,每个元素包含两个数据

Map集合的每个元素的格式:key=value(键值对元素)

Map集合也被称为:“键值对集合”

Map集合体系特点:

Map集合实现类特点:

2、 常用API

Map是双列集合的祖宗接口,它的功能是全部双列集合都可以继承使用的

方法名称 说明
V put(K key, V value) 添加元素
V remove(Object key) 根据键删除键值对元素
void clear() 移除所有的键值对元素
boolean containsKey(Object key) 判断集合中是否包含指定的键
boolean containsValue(Object value) 判断集合是否包含指定的值
boolean isEmpty() 判断集合是否为空
int size() 集合的长度,也就是集合中键值对的个数

3、 遍历

3.1 键找值

先获取Map集合的全部键的Set集合

遍历键的Set集合,然后通过键提取对应值

方法名称 说明
Set<K> keySet() 获取所有键的集合
V get(Object key) 根据键获取值
package set_;

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

public class SetDemo {
    public static void main(String[] args) {
        // 创建一个Map集合对象
        Map<String, Integer> maps = new HashMap<>();
        maps.put("笔记本", 23);
        maps.put("IPad", 234);
        maps.put("IPhone", 345);
        System.out.println(maps);
        // 遍历Map集合
        Set<String> keys = maps.keySet();
        for (String s:
        keys) {
            System.out.println(maps.get(s));
        }
    }
}

3.2 键值对

先把Map集合转换成Set集合,Set集合中每个元素都是键值对实体类型了

遍历Set集合,然后提取键以及提取值

方法名称 说明
Set<Map.Entry<K, V>> entrySet() 获取所有键值对对象的集合
K getKey() 获得键
V getValue() 获取值
package set_;

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

public class SetDemo {
    public static void main(String[] args) {
        // 创建一个Map集合对象
        Map<String, Integer> maps = new HashMap<>();
        maps.put("笔记本", 23);
        maps.put("IPad", 234);
        maps.put("IPhone", 345);
        System.out.println(maps);
        // 遍历Map集合
        Set<Map.Entry<String, Integer>> entries = maps.entrySet();  // 获取键值对组成的集合
        for (Map.Entry<String, Integer> entry:
        entries) {
            System.out.println("键为:" + entry.getKey() + "\n值为:" + entry.getValue());
        }
    }
}

3.3 Lambda表达式

得益于JDK8开始的新技术Lambda表达式,提供了一种更简单、更直接的遍历集合的方式

package set_;

import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;

public class SetDemo {
    public static void main(String[] args) {
        // 创建一个Map集合对象
        Map<String, Integer> maps = new HashMap<>();
        maps.put("笔记本", 23);
        maps.put("IPad", 234);
        maps.put("IPhone", 345);
        System.out.println(maps);
        // 遍历Map集合
        maps.forEach((String s, Integer integer) -> {
                System.out.println(s + "====" + integer);
        });
    }
}

4、 HashMap

使用最多的Map集合是HashMap

特点:

实际上:Set系列集合的底层就是Map实现的,只是Set集合中的元素只要键数据,不要值数据而已

HashMap的特点和底层原理:

5、 LinkedHashMap

特点:

6、 TreeMap

特点:

TreeMap集合自定义排序规则有2中:

7、 不可变集合

特点:

Set<String> names = Set.of("李华", "张三");  // 这个集合是不可以改变的
Map<String, Integer> maps = Map.of("华为", 2, "Java", 4);  // 这个Map也是不可以改变的

七、 Stream流

1、 概述

什么是Stream流?

Stream流的思想:

作用:

2、 获取

Stream流的三类方法:

获取Stream流的方式:

名称 说明
default Stream<E> stream() 获取当前集合对象的Stream流

数组获取Stream流的方式:

名称 说明
public static<T> Stream<T> stream(T[] array) 获取当前数组的stream流
public static<T> Stream<T> of(T...values) 获取当前数组/可变数据的Stream流
String[] names = {"hello", "world"};
Stream<String> nameStream = Array.stream(names);
Stream<String> nameStream2 = Stream.of(names);

3、 常用API

即为中间操作方法

名称 说明
Stream<T> filter(Predicate<? super T> predicate) 用于对流中数据进行过滤
Stream<T> limit(long maxSize) 获取前几个元素
Stream<T> skip(long n) 跳过前几个元素
Stream<T> distinct() 去除流中重复的元素,依赖hashCode和equals
static<T> Stream<T> concat(Stream a, Stream b) 合并a和b两个流为一个流

注意:

4、 收集数据

名称 说明
R collect(Collect collector) 开始收集Stream流,指定收集器

Collection工具类提供了具体的收集方式

名称 说明
public static<T> Collector toList() 把数据收集到List集合中
public static<T> Collector toSet() 把数据收集到Set集合中
public static Collector toMap(Function keyMapper, Function valueMapper) 把数据收集到Map集合
package set_;

import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;
import java.util.stream.Stream;


public class SetDemo {
    public static void main(String[] args) {
        List<String> lis = new ArrayList<>();
        lis.add("李华");
        lis.add("赵华");
        lis.add("张华");
        lis.add("小华");
        System.out.println(lis);
        Stream<String> s = lis.stream().filter(s_ -> s_.startsWith("张"));
        
        // 注意,流只能使用一次
        // Object[] arrs_t = s.toArray();  // 返回类数组,后面可以进行类型转换
        // String[] arrs = s.toArray(String[]::new);  // 直接返回字符串数组
        System.out.println(s.collect(Collectors.toList()));  // 转换为List集合。使用这个方法,s.toList(),返回不可变集合
    }
}

还有其他的接口,以及集合,大家可以通过官方文档查找

标签:Java,元素,节点,泛型,lis,集合,public
来源: https://www.cnblogs.com/liuzhongkun/p/16466150.html