集合
概念
集合顾名思义,就是一堆东西放到一起,就叫做一个集合,和高中时学的集合类似
因为数组在处理一些特殊问题的时候,存在许多的不方便性,所以使用集合, 比如数组在生成了以后,长度就不再能变化,所以可以使用集合来向数组中进行增删操作
集合API
从大类型上分:集合可以分为 单列和双列
单列: collection 也就是一般的线性表和链表 :
collection 又可以分为: list 和 set
list为一般的元素列表
可以分为:ArrayList , LinkedList , …
set为不重复的元素集合
可以分为:HashSet , TreeSet
…
双列: Map 也就是类似于Python的字典
所谓字典,就是键值对 key – value 的形式
具体分类: HashMap …
泛型
日常使用中,我们需要给一个储存类型中传入很多的不同的元素,那么怎么传入不同元素呢,java在这引入了泛型, 顾名思义, 泛型就是可以代之所有类型, 默认为Object
<T> //用大写字母T来表示
Collection
单列集合 : 作为一个接口 , 里面有两个具体的数据结构
分别是set 和 list
//collection 中的一些方法
boolean add(Object element);
boolean addAll(Collection c);
boolean remove(Object element);
boolean removeAll(Collection c);//删除指定集合 不包含时,删除相交的元素
void clear();
int size();
boolean isEmpty();
boolean contains(Object element);
boolean containsAll(Collection c);
boolean retainAll(Collection c); //求交集,集合数据发生变化返回true,不变返回false
List
collection中的子类,
ArrayList
数组列表:也就是线性表
所谓线性表就是线性存储,可以增删,但是增加和删除的过程需要移动其他的元素
ArrayList : 1 2 3 4 5 6 7 8 9 0
如果对他进行增加:在 2 后面添加一个 0
需要把 3 4 5 6 7 8 9 0 都向后移动一个
非常的复杂:
package com.cxy.javaCollection.list;
import java.util.ArrayList;
public class ListDemo1 {
public static void main(String[] args) {
ArrayList<Integer> l1 = new ArrayList<Integer>();
System.out.println("li:"+l1);
for(int i = 0; i<10;i++){
l1.add(i);
}
System.out.println("li:"+l1);
System.out.println("li第6号位置:"+l1.get(6));
System.out.println("l1中值为2的元素位置:"+l1.indexOf(2));
l1.add(2);
System.out.println("l1中值为2的元素最后出现位置位置:"+l1.lastIndexOf(2));
l1.remove(2);
System.out.println("删除2号位置li:"+l1);
l1.remove(2);
System.out.println("删除2号位置li:"+l1);
//l1.removeRange(2,4);
l1.set(2,100);
System.out.println("更改2号位置li:"+l1);
}
}
>>>"C:\Program Files\Java\jdk1.8.0_261\bin\java.exe"
>>> li:[]
>>> li:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> li第6号位置:6
>>> l1中值为2的元素位置:2
>>> l1中值为2的元素最后出现位置位置:10
>>> 删除2号位置li:[0, 1, 3, 4, 5, 6, 7, 8, 9, 2]
>>> 删除2号位置li:[0, 1, 4, 5, 6, 7, 8, 9, 2]
>>> 更改2号位置li:[0, 1, 100, 5, 6, 7, 8, 9, 2]
Process finished with exit code 0
LinkedList
链表
LinkedList : 1-2-3-4-5-6-7-8-9-0
如果对他进行增加:在 2 后面添加一个 0
不需要把 3 4 5 6 7 8 9 0 都向后移动一个
断开 2-3 中间的指针
用 2 后面的指针指向 0 ,在用 0 指向 3,
2-0-3即可
package com.cxy.javaCollection.list;
import java.util.LinkedList;
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList<Integer> l1 = new LinkedList<>();
int[] a = {1,2,34,5,6,87,0,454,98,0};
for(int item:a){
l1.add(item);
}
System.out.println("l1:"+l1);
l1.set(2,100);
System.out.println("修改2号位置上的结果为100:"+l1);
l1.add(2,99);
System.out.println("在2号位上插入99:"+l1);
l1.clear();
System.out.println("l1:"+l1);
}
}
>>> "C:\Program Files\Java\jdk1.8.0_261\bin\java.exe"
>>> l1:[1, 2, 34, 5, 6, 87, 0, 454, 98, 0]
>>> 修改2号位置上的结果为100:[1, 2, 100, 5, 6, 87, 0, 454, 98, 0]
>>> 在2号位上插入99:[1, 2, 99, 100, 5, 6, 87, 0, 454, 98, 0]
>>> l1clear之后:[]
>>> Process finished with exit code 0
vector
数组列表,线程安全,有同步锁
Set
set就是不可重复的集合:
这类集合中元素不可以重复:主要包含两种set : 1. HashSet 2. TreeSet
HashSet
HashSet的底层其实是使用hashMap的其中一个列来实现的,我们都知道HashMap的keys是不可以重复的,所以使用map中的keys用来存储set就很巧妙
//声明
HashSet<T> set = new HashSet<>();
HashSet在存储过程中,其中得元素是无序的, 传入一个值的时候, 会自动调用该泛型中的HashCode()方法和Equals()方法,
当HashCode()方法所求出的哈希值不同的时候, 说明两个对象不同,所以可以添加进set中 , 但有时HashCode()方法求出的哈希值会相同 , 所以在相同了之后, 程序会自动调用Equals()方法, 从对象的各个细节一个一个去比较.
使用HashCode()效率高,使用Equals()方法比较安全;
例:
public class Student implements Comparable<Student>{
String name ;
int age;
public Student(String name,int age){
this.name=name;
this.age=age;
}
@Override
public int hashCode() {
return name.hashCode();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return Objects.equals(name, student.name);
}
}
TreeSet
对比HashSet ,TreeSet中的元素是按照一定的顺序排列好的, 当我们有需要的时候, 我们可以通过重写compareto方法去重新排序
例:
public class Student implements Comparable<Student>{
String name ;
int age;
public Student(String name,int age){
this.name=name;
this.age=age;
}
@Override
public int compareTo(Student o) { // 让TreeSet按照age排序
return this.age-o.age;
}
}
map
类似python的字典
存储形式为键值对的形式 : key–>value
主要特点为 key不能重复 ,主要分为HashMap和TreeMap,必要时可以重写其中的一些方法,
HashMap
无序的
TreeMap
有序的,
//利用俩个LinkedList写出来的自定义map
package com.cxy.javaCollection.list.day3;
import java.util.LinkedList;
public class MyMap<K,V> {
int size;
LinkedList<K> keyArray = new LinkedList<>();
LinkedList<V> valueArray= new LinkedList<>();
/**
* 无参构造
*/
public MyMap(){
}
/**
* 字典的添加
* @param key 键
* @param value 值
*/
void add(K key,V value){
if(keyArray.size()>0){
// boolean flag = true;
// for(K item:keyArray){
// if(item.equals(key)){
// flag = false;
// }
// }
// if (flag){
if(!keyArray.contains(key)){
keyArray.add(key);
valueArray.add(value);
}else{
for(int i = 0;i<keyArray.size();i++){
if (keyArray.get(i).equals(key)){
valueArray.set(i,value);
}
}
}
}else{
keyArray.add(key);
valueArray.add(value);
}
size++;
}
/**
* 删除对应键位置的元素
* @param key 传入的key键
*/
void remove(K key){
for(int i = 0;i<keyArray.size();i++){
if(keyArray.get(i).equals(key)){
keyArray.remove(i);
valueArray.remove(i);
size--;
}
}
}
/**
* 获取对应键的值的值
* @param key 传入的键
* @return 返回对应的值
*/
V get(K key){
for(int i = 0;i<keyArray.size();i++){
if (keyArray.get(i).equals(key)){
return valueArray.get(i);
}else{
return null;
}
}
return null;
}
/**
* 获取所有的键的表
* @return 返回键,用数组承接
*/
LinkedList<K> toKeys(){
return keyArray;
}
/**
* 获取所有值的表
* @return 返回值,用数组承接
*/
LinkedList<V> toValues(){
return valueArray;
}
/**
* 重写toString()
* @return 用{key:value}的方法输出
*/
@Override
public String toString() {
StringBuffer sb = new StringBuffer("{");
for(int i =0;i<keyArray.size();i++){
if (i==keyArray.size()-1){
sb.append(keyArray.get(i)+":");
sb.append(valueArray.get(i));
}else{
sb.append(keyArray.get(i)+":");
sb.append(valueArray.get(i)+", ");
}
}
sb.append("}");
return sb.toString();
}
}