集合

Java集合框架

数组:数据类型相同,内存空间连续,长度固定
Java集合框架:Java中提供的各种集合的统称
集合特点:
1.长度是随意的,动态变化
2.集合只能存储引用数据类型,也可以存基本数据类型(存储时自动装箱)
部分集合底层是由数组实现的
Set—/— HashSet
/ — HashTree
Collection—–
\ Vector — Stack
\ /
List—— LinkedList

ArrayList

ArrayList

底层由数组实现,查询快,增删慢,线程不安全,效率高

ArrayList arr = new ArrayList();
arr.add(1);//添加元素
arr.add(索引,值);//追加元素
//add方法如果是List集合一直返回true,因为List集合可以存储重复元素;
//如果是Set集合,当存储重复元素时,会返回false;


arr.size();//长度
arr.remove(1);//删除(如果是数字默认为索引,不会自动装箱)
arr.clear();//移除所有元素
arr.addAll(arr2);把另外一个集合加到此集合中
arr.isEmpty();//是否为空 返回布尔值 
arr.contains(元素);//元素是否在集合中
arr.containsAll(arr2);//判断调用的集合是否包含传入的集合
arr.removerAll();删除交集
arr.retainAll(arr2);//取交集,把交集赋给arr,如果arr没有改变返回false.改变了返回true
arr.get(1);取到索引1 的元素
arr.set(1,"aaaa");用aaaa替换索引1的元素;
List arrNew = arr.subList(start,end);返回指定start-to的集合
List.toArray();//转化为数组

集合的长度是由添加的元素个数决定的,与初始化的长度无关
特点:
1)有序,根据添加的顺序决定
2)可重复,不唯一
3)空间连续

遍历集合

//1
for(int i = 0; i < arr.size();i++){
    System.out.println(arr.get(i));
}
//2
for(Object o:ary){
    System.out.println(o.toString);
}
//3迭代器
Iterator it = ary.iterator();
while(it.hasNext()){
    System.out.println(it.next());
}

适用场合:遍历操作频繁时(内存空间连续)

//listIterator是list特有的
ListIterator lit = list.listIterator();
while(lit.hasNext()){
    String str = (String)lit.next();
    if("word".equals(str){
        lit.add("javaee");//可以在遍历的同时增加元素,并发修改ConcurrentModificationException
    }
}
lit.hasPrevious();//指针位置是否有前一个元素;直接用的话指针在第一个位置,没有前一个元素,所以要hasNext()遍历移动指针后才能用,所以说压根儿没什么用吧

数组转集合:

int[] arr= {11,22,33};
List list = Arrays.asList(arr);//基本数据类型的数组转换成集合,会将整个数组当做一个元素
Integer[] arr1 = {11,22,33,44};
List<Integer> list = Arrays.asList(arr);

集合转数组:

ArrayList<String> List = new ArrayList<>();
String[] arr = list.toArray(new String[10]);//当集合转数组时,数组长度如果小于等于集合的size,转换后的数组长度等于集合size;如果数组长度大于size,数组长度等于分配的size;

LinkedList

链表:有序,可重复,空间不连续,查询慢,增删快.
可以使用List接口的方法.扩展了3对 6个方法
适用于频繁增删
不适用频繁遍历
由于内存空间不连续,头部尾部操作方法比通过索引操作效率高

public class LinkedTest {
    public static void main(String[] args) {
        LinkedList ll = new LinkedList();
        ll.add("aa");
        ll.add("bb");
        ll.addFirst("cc");//头部元素
        System.out.println(ll.getFirst());//得到头部元素
        ll.removeFirst();//删除头部元素
        ll.addLast("dd");//尾部元素
        System.out.println(ll.getLast());//得到尾部元素
        ll.removeLast();//删除尾部元素
    }
}

Vector

用法及存储结构和ArrayList相同,是一个古老的集合
底层由数组实现,查询快
Vector线程安全,效率低
ArrayList线程不安全,效率高

Vector v = new Vector();
v.addElement("a");
Enumeration en = v.elements();    //获取枚举
while(en.hasMoreElements()){    //判断集合中是否有下一个元素
    System.out.println(en.nextElement());    //获取元素
}

泛型集合

List下的集合:
1.存入的数据都会转换为Object
2.取出数据时容易发生异常
使用泛型集合来提升集合的安全性:
泛型集合是对集合中存放数据的类型的约束,非约定的类型
提高安全性,省去强转的麻烦.
1.7新特性:前面写了泛型后面写<>即可
<>中存放的必须是引用类型

//LeetCode上的
// "static void main" must be defined in a public class.
public class Main {
    public static void main(String[] args) {
        // 1. initialize
        List<Integer> v0 = new ArrayList<>();
        List<Integer> v1;                           // v1 == null
        // 2. cast an array to a vector
        Integer[] a = {0, 1, 2, 3, 4};
        v1 = new ArrayList<>(Arrays.asList(a));
        // 3. make a copy
        List<Integer> v2 = v1;                      // another reference to v1
        List<Integer> v3 = new ArrayList<>(v1);     // make an actual copy of v1
        // 3. get length
        System.out.println("The size of v1 is: " + v1.size());;
        // 4. access element
        System.out.println("The first element in v1 is: " + v1.get(0));
        // 5. iterate the vector
        System.out.print("[Version 1] The contents of v1 are:");
        for (int i = 0; i < v1.size(); ++i) {
            System.out.print(" " + v1.get(i));
        }
        System.out.println();
        System.out.print("[Version 2] The contents of v1 are:");
        for (int item : v1) {
            System.out.print(" " + item);
        }
        System.out.println();
        // 6. modify element
        v2.set(0, 5);       // modify v2 will actually modify v1
        System.out.println("The first element in v1 is: " + v1.get(0));
        v3.set(0, -1);
        System.out.println("The first element in v1 is: " + v1.get(0));
        // 7. sort
        Collections.sort(v1);
        // 8. add new element at the end of the vector
        v1.add(-1);
        v1.add(1, 6);
        // 9. delete the last element
        v1.remove(v1.size() - 1);
    }
}

Set

无序,不能重复,没有索引
无序:存放的顺序和遍历取出的顺序不一致;
HashSet:根据哈希表存储

TreeSet:根据二叉树存储

值唯一性的原理分析:判断的是对象的存放地址,存放时,首先获取地址的hashCode()值,根据hashcode判断是否重复.
可以重写类的hashcode方法,根据自定义的属性值产生hashcode
Java判断对象是否相同的过程:
1.先判断hashCode();如果hashCode不同,加入集合中;
如果hashCode不同,进一步判断equals
2.重写equals()
setStu.add(stu1);
自动调用stu1对象的hashCode(),系统自动判断此hashCode值在HashSet集合中是否已经存值
如果没有存值,则存入到HashSet中
如果有,再次调用eqals()方法,根据equals返回的结果true
:值相同,不添加到HashSet
false :值不同,则添加到HashSet

Map:无索引
提供key-value的存储方式
键 值 对
CN - 中华人民共和国
USA - 美国
JP -日本
共同特点:无序
key唯一(key重复后,会进行覆盖)

重点:Map集合的遍历

Map 接口
实现类:HashMap  HashTable  TreeMap(可以自动以排序规则)

总结:集合框架
一:Collection
1.1、List
ArrayList:内存连续 有序 可重复
Vector:线程安全,效率低
LinkedList: 有序 可重复 内存不连续 6个方法

1.2、Set :不连续 无索引 无序 唯一
HashSet:Hash表结构存放数据
子类LinkedHashSet 有序
TreeSet:以Tree结构存放数据
由于实现了SortedSet接口,可以自定义排序规则

二:Map:无索引 无序 key唯一 value可重复
2.1、HashMap
LinkedHashMap有序
2.2、HashTable
2.3、TreeMap 实现了SortedMap接口,可以自定义排序规则

三:Collections 封装了工具类
辅助操作集合

类集框架

1.类集框架是一组类和接口
2.位于java.util包当中
3.主要用于存储和管理对象
4.主要分为三大类–集合,列表,映射;

集合(Set)

集合中的对象不按特定方式排序,并且没有重复对象.
继承了Collection接口.有一个实现类HashSet

public class Test{
    public static void main (String[] args){
        Set<String> set = new HashSet<String>();
        set.add("a");//添加元素
        set.add("b");
        set.add("a");//重复的元素会被忽略掉
        System.out.println(set.size());//长度
        set.remove("a");//删除a元素
        set.clear();//清除
        set.isEmpty();//返回值为布尔值,是否为空

        //Iterator<---Collection<---Set<---HashSet
        //                        <---List<---ArrayList
        //Iterator:hasNext(); next();
        //调用Set对象的Iterator方法,会生成一个迭代器对象,该对象用于遍历整个Set
        Iterator<String> it = set.iterator();
        while(it.hasNext()){
            String s = it.next();//判断当前游标位置有没有下一个元素
            System.out.println(s);//把当前游标的下一个元素取出来并将游标移动到下一个位置
        }
    }
}

列表(List)

集合中对象按照索引位置排序,可以有重复的对象.

映射(Map)

集合中的每一个元素包含一个键对象和一个值对象,键不可以重复,值可以重复.每一个元素都是一个键值对
HashMap是Map的实现类

Map<String,String> ary = new HashMap<>();
ary.put("去","死") //添加一个元素,如果key重复,覆盖之前的
ary.get("去");    //通过键找值

Collection接口

Hash算法

输入数据,通过hash算法得到一个唯一的散列值.
存储数据,数据与散列值关联.查找数据

equals

== 比较两个引用指向的地址.
equals比较对象的内容.通常在重写后:
1)对象的类型相等(intanceof比较)
2)两个对象的成员变量的值完全相等
重写equals方法

public boolean equals(Object o){
    if(this == o){
        return true;
    }
    if(o instanceof User){
        User u = (User)o;
        if(this.age == u.age && this.name.equals(u.name)){//name调用的equals方法
            return true;
        }else{
            return false;
        }
    }else{
        return false;
    }
}