【六】Java基础(05)---集合

目录

一.集合框架的概述

二.集合

<一> Collenctions 接口

(一)list 接口

(二)set接口

<二>map 接口


一.集合框架的概述

1.集合。数组都是对多个数组进行存储操作的结构,简称java容器

    说明:此时的存储,主要指内存层面的存储,不涉及到持久化的存储(.txt .jpg .avi.数据库中)

2.数组在存储多个数据方面的特点:

    》一旦初始化以后,长度就确定了

    》比如String[] arr;int[] arr1;元素的类型就确定了,我们也就只能操作指定数据的类型。不过有多态性

    缺点;

    》一旦初始化以后长度就不可以修改了

    》数组中提供的方法非常有限,对于添加,删除,插入数据等操作非常不便,同时效率不高

    》获取数组中实际元素的个数的需求,数组没有现成的属性或方法可用

    》数组存储数据的特点:有序,可重复。对于无序,不可重复的需求,数组不能满足的。

3.集合框架

    java集合可分为collection 和map两种体系

    Collection 接口:单列数据,定义了获取一组对象的方法集合

        list :元素有序,可重复的集合  动态数组

            ArrayList,LinkedList,Vector

        set:元素无序,不可重复的集合  集合

            HashSet,LinkedHashSet,TreeSet

    Map接口:双列数据,保存具有映射关系“key-value”的集合

            HashMap,LinkerHashMap,TreeMap,Hashtable,Properties

二.集合

<一> Collenctions 接口

1.Collections接口常用方法

//add(Object e ):将元素e添加到集合coll中
//size():获取添加的元素的个数
 //addAll(Collection coll); 将coll集合中的元素添加到当前的集合中
//clear();清空集合
//isEmpty();判断当前集合是否为空
 //contains(Object obj):判断当前集合中是否包含obj 
 //containsAll(Collection coll1):判断行惨coll1中的所有元素是否都存在与当前集合中
//remove 方法调用equals方法判断后移除
 //removeAll(Collection coll)从当前集合中移除coll共有的元素 差集
 //retainAll(Collection coll)保留当前集合与coll共有的元素,交集
//equals(Object object) 判断当前集合和行参集合的元素相同
 //hashcode();返回当前对象的哈希值
//toArray();集合--->数组

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

public class CollectionTest {

    public static void main(String[] args){
        Collection coll1 = new ArrayList();
        //add(Object e ):将元素e添加到集合coll中
        coll1.add("AA");
        coll1.add(123);
        coll1.add(new String("Tom"));
        coll1.add(new Person("jerry",20));
        //size():获取添加的元素的个数

        System.out.println(coll1.size());

        //addAll(Collection coll); 将coll集合中的元素添加到当前的集合中
        //Collection coll = new ArrayList();
        //coll.add(111);
        Collection coll = Arrays.asList(123,457);
        System.out.println(coll.size());
        System.out.println(coll);

        //clear();清空集合
        //coll.clear();

        //isEmpty();判断当前集合是否为空
        System.out.println(coll.isEmpty());

        //contains(Object obj):判断当前集合中是否包含obj  会调用obj对象所在类的equals()方法
        //向Collection接口的实现类的对象中添加obj时,要求obj所在类要重写equals()方法
        boolean contains = coll1.contains(123);
        System.out.println("contains :"+contains);
        System.out.println("contains 调用String equals方法 :"+coll1.contains(new String("Tom")));//注意此时又新建了一个对象两个对象地址值不一样
        System.out.println("contains 调用Object equals方法 :"+coll1.contains(new Person("jerry",20)));
        //注意此时第二个是true,所以调用的是String中的equals方法,但是第三个是false说明调用的时object类中的equals方法相当于==

        //containsAll(Collection coll1):判断行惨coll1中的所有元素是否都存在与当前集合中

        boolean contains1 = coll1.containsAll(coll);
        System.out.println("contains1 :"+contains1);

        //remove 方法调用equals方法判断后移除
        coll1.remove(123); //
        System.out.println("remove 方法"+coll1);
        //removeAll(Collection coll)从当前集合中移除coll共有的元素 差集
        //retainAll(Collection coll)保留当前集合与coll共有的元素,交集
        //equals(Object object) 判断当前集合和行参集合的元素相同
        //hashcode();返回当前对象的哈希值
        System.out.println("哈希值: "+coll1.hashCode());
        //toArray();集合--->数组
        Object[] arr = coll1.toArray();
        for(int i =0;i<arr.length;i++){
            System.out.println("集合-->数组 : "+arr[i]);
        }
        //拓展:数组--》集合 调用Arrays类中的asList静态方法
        List<String> list = Arrays.asList(new String[]{"jea","eer","aadf"});
        System.out.println(list);

    }


}
class Person{
    private String name;
    private int age;

    public Person(){

    }
    public Person(String name,int age){
        this.name = name ;
        this.age = age;
    }
    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name = name;
    }
    public int age(){
        return age;
    }
    public void setAge(int age){
        this.age= age;
    }
    @Override
    public String toString(){
        return "Person{" + "name=" + name +'\''+", age = "+age +'}';
    }
}

2.集合遍历

Iterator遍历Collection

for-each循环遍历数组和集合

//for(集合中元素的类型局部变量:集合对象){}

//for(数组元素类型数组变量:数组对象){}

for(Object obj:coll){

System.out.println(obj);

}

(一)list 接口

动态数组

三个具体实现类异同

ArrayList  ,  作为List接口的主要实现类 ,线程不安全,效率高 底层Object[]数组 elementData存储

        ArrayList的源码分析;jdk7 类似单例饿汉式

        ArrayList list=new ArrayList();//底层创建了长度是10Object[]数组elementData

        list.add(123);//element Data[0]=new Integer(123)

        list.add(11);//如果此次添加导致底层elementData数组容量不构,则扩容。默认情况下,扩容 为原来容量的1.5

        //同时需要将原有的数组中的数据复制到新的数组中去

        //建议使用带参的构造器ArrayList list=new ArrayList(10);

        Jdk8类似单例的懒汉式,延迟数组创建,节省内存

        ArrayList list=new ArrayList();//底层Object[] elementData初始话为{},并没有创建长度为10的数组

        list.add(123);//第一次调用add,底层才创建了长度10的数组,并将数据123添加到elementData[0]

        后续的添加和扩容操作都一样

LinkedList ,对于频繁的插入和删除操作,使用此效率比ArrayList高   底层是使用双向链表存储

        LinkedList list = new LinkedList();内部声明了Node类型,的first和Last属性,默认值为null,其中Node定义为:体现了LinkedLsit的双向链表的说法

        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;

            }

        }

Vector 作为List接口的古老实现类 ,线程安全,效率低 底层Object[]数组elementData存储

同;三个类都实现了List接口,存储数据的特点相同,存储有序,可重复的数据

packagecom.example.lisr;

/*
List接口中的常用方法

void add(int index,Object obj):在index位置插入obj元素
boolean addAll(int index,Collection eles):在index位置插入eles中的所有元素添加
Object get(int index):获取index位置的元素
int indexOf(Object obj):返回obj在当前集合中首次出现的位置若不存在返回-1
int LastIndexOf(Object obj):返回obj在当前集合中末次出现的位置
Object remove(intindex):删除指定index位置的元素,并返回此元素
Object set(int index,Object elee):设置指定index位置的元素为elee
ListsubList(int from Index,int to Index):返回从fromIndex到toIndex位置的左闭右开子集合

总结常用方法
增:add(Object obj);
删:remove(int index)/remove(Object obj)
改:set(int index,Object ele)
查:get(int index) indexOf(Object obj)
插:add(int index,Onject obj)
长度:size()
遍历:
1.Iterator迭代器方式
while(iterator.hasNext()){
Object obj=iterator.next();
System.out.println("遍历:"+obj);
2.for-each循环
for(Object obj:list){
System.out.println(obj);
}
3.普通的循环

*/

importjava.util.ArrayList;
importjava.util.Arrays;
importjava.util.Date;
importjava.util.List;

public class List Test{

public static void main(String[] a){
ArrayList list=new ArrayList();
list.add(123);
list.add(456);
list.add("AA");
list.add(newDate());
list.add(456);
System.out.println(list);
list.add(1,"BB");
System.out.println("插入"+list);
Listlist1=Arrays.asList(1,2,3);
list.addAll(list1);
System.out.println("addall"+list+list.get(2));
}
}

(二)set接口

三个实现类 无序的不可重复

HashSet: 作为Set接口的主要实现类:线程不安全的:可以存储null值

1.无序性:不等于随机性,只是不是按照数组元素索引顺序添加

2.不可重复性:保证添加的元素按照equals()判断,不能返回true,即相同的元素只能添加一个

数组加链表的结构

3.添加数据的过程 以HashSet为例

我们向HashSet中添加元素a,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,此哈希值接着通过某种算法,计算出在HashSet底层数组中的存放位置(即索引位置),

判断数组此位置上是否已经有元素,

        如果此位置没有其他元 素,则元素a添加成功

        如果此位置上有其他元素b(或者以链表形式存在多个元素),则比较a与b的哈希值:

                如果哈希值不相同,则元素添加成功,以链表的形式存储

                如果哈希值相同,进而需要调用元素a所在类的equal()方法;

                        equals()返回true,元素a添加失败

                        Equals()返回false,则元素a添加成功,以链表形式存储

4.set接口中没有额外定义新的方法,使用的是collection 中声明的过的方法

5.要求:向set中添加的数据,其所在的类一定要重写hashCode()和equals()

要求:重写的hashCode()和equals()方法尽可能保持一致性:相等的对象必须具有相等的 散列码

LinkedHashSet :作为HashSet的子类,遍历其内部数据时,可以按照添加的顺序去遍历

TreeSet:可以按照添加对象的指定属性进行排序。

1.向TreeSet中添加,只能添加某一个类的对象,不能添加不同类的对象

2.两种排序方式:自然排序(实现Comparable接口)和定制排序(Comparator接口)

底层二叉树,中序遍历

3.自然排序中,比较两个对象是否相同的标准为:compareTo()返回0,不再是equals(),

(在元素对象中继承Comparable接口并重写compareTo方法,来针对性的比较)

Public int compareTo(Objecto){
if(o instanceof Empolyee){
Empolyeee=(Empolyee)o;
returnthis.name.compareTo(e.name);
}
//return0;
thrownewRuntimeException("传入数据类型不一致");
}

4.定制排序中,比较两个对象是否相同的标准为:compare()返回0,不再是equals()

(新建对象Comparator对象并重写方法,形参的方式传入到TreeSet)

Comparator com=new Comparator(){
@Override
Publicint compare(Objecto1,Objecto2){
if(o1 instanceof Empolyee&&o2 instanceof Empolyee){
MyDateb1=((Empolyee)o1).getBirthday();
MyDateb2=((Empolyee)o2).getBirthday();
Return b1.getYear()-b2.getYear();

}
//return0;
Throw new Runtime Exception("传入数据类型不一致");
}
};
TreeSet set=new TreeSet(com);

set接口中没有额外定义新的方法,都是使用Collection 中的方法

无序性:不等于随机性,只是不是按照数组元素索引顺序添加

不可重复性:保证添加的元素按照equals()判断,不能返回true,即相同的元素只能添加一个

<二>map 接口

Map:双列数据,存储key-value对数据我,类似函数y =f(x)

HashMap:作为map的主要实现类 :线程不安全,效率高 存储null的key和value

Jdk7 数组+链表

Jdk8 数组+链表+红黑树

HashMap底层实现原理 jdk7

HashMap map = new HashMap();

在实例化以后,底层创建了长度为16的一维数组Entry[] table.

map.put(key1,value1);

首先,计算key1所在类的hashcode方法,计算key1哈希值,通过某种算法计算以后得到Entry数组中的存放位置。

判断数组此位置上是否已经有元素,

如果此位置没有其他元 素,则元素key1-value1添加成功

如果此位置上有其他元素b(或者以链表形式存在多个元素),则比较ab的哈希值:

如果哈希值不相同,则元素添加成功,以链表的形式存储

如果哈希值相同,进而需要调用元素key1所在类的equal()方法;

equals()返回true,元素key1-value1添加失败

Equals()返回false,则元素key1-value1添加成功,使用value1 替换value2 以链表形式存储

Jdk8

1.new HashMap 底层没有创建一个长度为16的数组

2.底层数组为Node[],而非Entry[]

3.首次调用put()方法,底层创建长度为16的数组

4.jdk8 数组+列表+红黑树

当数组的某一个索引位置上的元素以链表形式存在的数据个数> 8且当前数组的长度>64此时此索引位置上的所有数据改为使用红黑树存储

LinkedHashMap:

保证在遍历map元素时,可以按照添加的顺序实现遍历。在原有的HashMap底层结构基础上,添加了一对指针,指向前一个和后一个元素

对于频繁的遍历操作,此类执行效率高于HashMap

TreeMap:保证按照添加的key-value对进行排序,实现排序遍历。此时考虑可以的自     然排序,底层是使用红黑树

想TreeMap中添加key-value,要求key必须是同一个类创建的对象

因为要按照key进行排序:自然排序,定制排序

排序方式参考treeSet;

HashTable:古老的实现类:线程安全,效率低  不能存储null的key和value

Properties:常用来处理配置文件。Key-value都是String类型

二。map结构i的理解

map中的key 无序的,不可重复的,使用set存储所有的key ,以HashMap为例其所在的类一定要重写hashCode()equals()

Map中的value :无序的,不可重复,使用Collection 存储所有的value  要求obj所在类要重写equals()方法

一个键值对,key-value构成了一个Entry对象

Map中的entry:无序的,不可重复的,使用set存储所有的entry

常用的方法:
Package com.example.maptest;

Import java.util.HashMap;
Import java.util.Map;

Public class MapTest{

Public static void main(String[]args){
Map  map=new HashMap();
//添加
map.put("AA",123);
map.put("BB",456);
map.put("CC",789);
//修改
map.put("AA",124);

System.out.println(map);

Mapmap1=newHashMap();
map1.put("CC",123);
map1.put("DD",123);

map.putAll(map1);
//Objectremove(Objectkey)移除指定key的key-value对,并返回value
Object value=map.remove("CC");
System.out.println(value);
System.out.println(map);
//voidclear();清空当前map
//map.clear();
//System.out.println(map.size());
//Objectget(Objectkey):获取指定key对应的value
System.out.println("查询:"+map.get("DD"));
//booleancontainsKey(Objectkey):是否包含指定的key
//booleancontainsValue(Objectvalue):是否包含指定的value
//intsize()返回map中key-value对的个数
//booleanisEmpty():判断当前map是否为空
//booleanequals(objectobj);判断当前map和参数对象obj是否相等

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值