java集合简单理解

集合

一,Java集合框架概述

1.什么是集合以及集合包含什么

集合可以作为一种容器,用来储存对象信息.所有集合类都位于java.util包下,但支持多线程的集合位于java.util.concurrent包中.
在这里插入图片描述

2.集合和数组的区别

集合是用来存储数据的容器,那么我们就会想到之前提到过的数组,同样是用来存储数据的,他们之间有区别吗?
在这里插入图片描述

二.Collection接口

Collection 接口-定义了存取一组对象的方法,其子接口Set和List分别定义了存储方式。

  • List 中的数据对象有顺序且可以重复。
  • Set 中的数据对象没有顺序且不可以重复。

Collection中定义的方法

方法应用

package collectionapi;

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

public class CollectionDemo {
    public static void main(String[] args) {
        Collection c=new ArrayList();
        c.add("a");
        c.add("b");
        c.add("c");
        c.add("aba");
        Collection b=new ArrayList();
        b.add("a");
        b.add("b");

        System.out.println(c);
        //System.out.println(c.contains("a"));//是否包含这个元素
        //System.out.println(c.isEmpty());//是否为空
        //c.addAll(c);
       // System.out.println(c.remove("a"));//移除某个元素
        System.out.println(c.containsAll(b));//判断b中元素是否完全包含于c 包含返回true

    }
}

1.List接口及实现类

List接口中ArrayList;LinkedList;Vector

1)ArrayList

底层数组实现,查询快,增删慢(数组实现,按地址索引查询很快,增删的话需要逐一更改地址)创建之初,在底层常见一个默认长度的数组,当数组满了之后,再想添加时,会扩容一个新数组,为原来额1.5

缺点:扩容之后,元素不能存满,浪费空间

package collectionapi;

import java.util.ArrayList;

/*
ArrayList
底层数组实现,查询快,增,删慢
创建之初,在底层创建一个默认长度的数组,当数组内容满了之后,再
在继续添加时,会扩容一个新数组,为原来的1.5倍
缺点:扩容后,元素不能存满,浪费空间
 */
public class ArrayListDemo {
    public static void main(String[] args) {

        /*
        1.调用默认无参的构造方法,创建ArrayList对象时,并没有实际的创建数组,第一次添加
        元素时创建数组,默认长度为10
        2.调用有参的构造方法,创建ArrayList对象时,创建一个指定长度数组
        this.elementData=new Object[initialCapacity]
         */
        //ArrayList<String> arrayList1=new ArrayList<String>(5);
        ArrayList<String> arrayList=new ArrayList<String>();
         arrayList.add("a");
         arrayList.add("b");
         arrayList.add("c");
         arrayList.add("d");
         arrayList.add("e");
         arrayList.add("e");
         arrayList.add("e");//当add添加元素时,数组已满,会进行扩容,扩展为原来1.5倍,返回一个新数组
        arrayList.add(3,"Q");//指定位置进行添加
        //System.out.println(arrayList.remove(3));//删除并返回指定位置元素'
        //System.out.println(arrayList.indexOf("c"));//查询元素位置
        //System.out.println(arrayList.lastIndexOf("e"));//查询元素最后出现位置
        System.out.println(arrayList.remove(3));
        System.out.println(arrayList.set(3,"d"));//改变指定位置的元素

    }
}

package collectionapi;

import java.util.ArrayList;
import java.util.Comparator;

public class ArrayListDemo2 {
    public static void main(String[] args) {
        ArrayList<String> arrayList=new ArrayList<String>();
        arrayList.add("a");
        arrayList.add("b");
        arrayList.add("c");
        arrayList.add("d");
        arrayList.add("e");

        //排序
        arrayList.sort(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return 0;
            }
        });
        System.out.println(arrayList);
    }
}
package collectionapi;

import java.util.ArrayList;

public class MyArray extends ArrayList {
    public static void main(String[] args) {
        MyArray myArray=new MyArray();
        myArray.add("a");
        myArray.add("b");
        myArray.add("c");
        myArray.add("d");
        myArray.add("e");

        myArray.removeRange(2,4);//删除指定区间元素
    }
}

package collectionapi;

import java.util.ArrayList;

public class ArrayListDemo3 {
    public static void main(String[] args) {
        ArrayList<String> arrayList=new ArrayList<String>();
        arrayList.add("a");
        arrayList.add("b");
        arrayList.add("c");
        arrayList.add("d");
        arrayList.add("e");
        ArrayList<String> arrayList1=new ArrayList<String>();
        arrayList1.add("a");
        arrayList1.add("b");
        arrayList1.add("c");
        arrayList1.add("d");
        arrayList1.add("f");

        //arrayList.addAll(arrayList1);//把数组a1加到a上
        //System.out.println(arrayList.containsAll(arrayList1));//此集合是否包含指定集合中的元素,包含返回true
        //System.out.println(arrayList.removeAll(arrayList1));//删除两个集合中相同的元素,有返回true
        System.out.println(arrayList.retainAll(arrayList1));//保留两个集合相同元素,有返回true
        System.out.println(arrayList);
    }
}

2)LinkedList

采用了链表的存储方式,插入,删除元素快,查找慢

package collectionapi.list;

import java.util.LinkedList;

/*
LinkedList
底层为链表实现,查询慢,增,删快
元素查找从第一个节点向后查找
增加,删除元素时,其他元素位置不动,只需改变指针域的值即可
 */
public class LinkedListDemo {
    //LinkedList<String> llist=new LinkedList<>();
    LinkedList<String> llist;
    public static void main(String[] args) {

        LinkedList<String> llist = new LinkedList<>();


        //LinkedList里面还提供了许多关于链表头尾操作的方法,这些方法用于模拟队列结构,栈结构操作.
        llist.addLast("a");
        llist.addLast("b");
        llist.addLast("c");
        llist.addLast("d");
        llist.addLast("e");
        llist.clear();//清除

        System.out.println(llist.pollFirst());//检索并删除此列表的第一个元素,如果此列表为空,则返回 null 。
        System.out.println(llist.peekFirst());//检索但不删除此列表的第一个元素,如果此列表为空,则返回 null 。
        System.out.println(llist.getFirst());//返回此列表中的第一个元素
        System.out.println(llist.removeFirst());//从此列表中删除并返回第一个元素
        System.out.println(llist);

        llist.addFirst("1");
        llist.offerFirst("1");//在此列表的前面插入指定的元素
        llist.offerLast("w");//在该列表的末尾插入指定的元素。
    }
}
3)Vector

底层是数组实现,线程安全

package collectionapi.list;

import java.util.Vector;
/*
线程安全 数组实现
new Vector<>(); 在创建之初 已经创建底层数组存储 默认长度为10
 */
public class VectorDemo {
    public static void main(String[] args) {
        Vector<String> vector =new Vector<>();
        vector.add("a");
        vector.add("c");
        vector.add("b");
    }
}

4)集合的迭代

集合的迭代 分别是:for循环遍历;增强for循环的遍历;以及迭代器遍历(iterator)

package collectionapi.list;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class IterationDemo {
    public static void main(String[] args) {
        //test1();
        //test2();
        //test3();
        test4();
    }
    public static void test1(){
        //for循环 可以删除集合中的元素,但是注意 下标与集合中的内容就会不对应
        List<Integer> a=new ArrayList<>();
        a.add(1);
        a.add(2);
        a.add(1);
        a.add(1);
        a.add(3);
        a.add(4);
        for (int i = 0; i <a.size() ; i++) {
            Integer A=a.get(i);
            //System.out.println(A);
            if(A.equals(1)){
                a.remove(A);
            }
        }
        System.out.println(a);
    }
    public static void test2(){
        //foreach 理论上遍历元素时,不允许删除集合中数据
        //如果删除,只能删除一次 然后立刻跳出循环
        List<Integer> b=new ArrayList<>();
        b.add(1);
        b.add(2);
        b.add(1);
        b.add(1);
        b.add(3);
        b.add(4);
        for (Integer B:b) {
            if (B.equals(1)){
                b.remove(B);
                /*
                ConcurrentModificationException 同时修改异常
                 */
                break;
            }
        }
        System.out.println(b);
    }
    public static void test3(){
        /*
        迭代遍历器1 iterator
        hasNext()判断集合中还有没有元素
        remove();删除元素,删除后里面的游标(指针,计数器)会回退一下
         */
        List<Integer> c=new ArrayList<>();
        c.add(1);
        c.add(2);
        c.add(1);
        c.add(1);
        c.add(3);
        c.add(4);
        Iterator<Integer> iter=c.iterator();
        while (iter.hasNext()){
            Integer i= iter.next();
            if (i.equals(1)){
                iter.remove();//使用迭代器中的remove();
            }
        }
        System.out.println(c);
    }
    public static void test4(){
        List<Integer> c=new ArrayList<>();
        c.add(1);
        c.add(2);
        c.add(1);
        c.add(1);
        c.add(3);
        c.add(4);
        /*
        迭代器2
         */
        ListIterator<Integer> listit=c.listIterator();
        //listit.nextIndex();//返回对 next 的后续调用所返回元素的索引。
        //listit.add(6);
        //listit.set(5);
        //listit.next();//返回列表的下一个元素
        System.out.println(listit.hasPrevious());
        while (listit.hasPrevious()){
            System.out.println(listit.previous());
        }
        System.out.println(c);
    }
}

三.Set接口

Set接口继承了Collection接口,Set中储存的元素是不重复的,且无序,没有索引 Set接口的实现类有两个HashSetTreeSet

1.HashSet

Hashset类中元素不能重复,(彼此之间调用equals方法比较,都返回false)

底层数据结构是哈希表+链表(hash表依赖于hash值储存)

package collectionapi.set;

import java.util.HashSet;

/*
set 不能存储重复元素    
HashSet 无序存储(不按添加顺序排列)
 */

public class HashSetDemo {
    public static void main(String[] args) {

        HashSet<String> h=new HashSet<>();
        h.add("a");
        h.add("a");
        h.add("b");
        h.add("c");
        h.add("w");
        h.add("g");
        h.add("t");
        h.add("重地");
        h.add("通话");
        h.add("b");
        System.out.println(h);
        /*
        1.哈希结构的底层是如何存储数据
             哈希表:哈希表本质也是数组
        2.HashSet是如何去除重复元素的
           先用元素的哈希值比较(快) 但是内容不同,hash值可能相同
           hash值相同时,再用equals()方法判断内容是否相等 (线程可靠,但是效率低)
            双保险:既保证效率有保证安全
         */
    }
}
package collectionapi.set;

import java.util.HashSet;

public class HashSetDemo2 {
    public static void main(String[] args) {
        /*
        set 不能存储重复元素
        HashSet 无序存储(不按添加顺序排列)

        HashSet如何判断元素重复
        1.每次添加内容时,会用内容的hash值来判断是否相同,但是hash值这种方法并不安全,
        可能出现内容不同,hash值相同(这种方法速度快)
        2.当出现内容不同,hash值相同时(hash碰撞 hash冲突),使用equals方法进行比较,比较内容是否
        相同(安全)

            hash值怎么来
               调用HashCode()方法
               两种情况:1.类中已经重写HashCode()方法,例如String类 根据内容来计算hash值
                      2.类中没有重写HashCode()方法,调用object类中打的HashCode()
         */


        HashSet<Student> h=new HashSet<>();
        Student s=new Student(100,"asd");
        Student s2=new Student(102,"通话");
        Student s3=new Student(102,"重地");
        Student s4=new Student(100,"asd");

        System.out.println(s.hashCode());//460141958
        System.out.println(s4.hashCode());//1163157884
        h.add(s);
        h.add(s2);
        h.add(s3);
        h.add(s4);
        System.out.println(h);
    }

}

2.TreeSet

TreeSet可以给Set集合中元素按照指定方式排序;存储的对象必须实现Comparable接口;TreeSet底层数据机构是二叉树(红黑树是一种自平衡的二叉树)

package collectionapi.set;

import java.util.TreeSet;

public class TreeSetDemo {
    /*
    Set不能存储重复元素
    TreeSet 可以按照元素的自然顺序排序
    底层是红黑树
     */
    public static void main(String[] args) {
        TreeSet<Integer> t=new TreeSet();
        t.add(3);
        t.add(6);
        t.add(2);
        t.add(4);
        System.out.println(t);
    }
}

package collectionapi.set;

import java.util.Objects;

public class Student implements Comparable<Student> {
    private int num;
    private String name;

    public Student(int num, String name) {
        this.num = num;
        this.name = name;
    }


    @Override
    public String toString() {
        return "学生{" +
                "学号=" + num +
                ", 姓名='" + name + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return num == student.num &&
                Objects.equals(name, student.name);
    }

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

    @Override
    public int compareTo(Student o) {
        return 0;
    }
}

package collectionapi.set;

import java.util.TreeSet;

public class TreeSetDemo2 {
    public static void main(String[] args) {
        /*
        Set不能存储重复元素

        TreeSet可以按照元素的自然顺序排列
        底层是红黑树
         */
        TreeSet<Student> t=new TreeSet<>();
        Student s1 = new Student(101,"bim");
        Student s2 = new Student(102,"通话1");
        Student s3 = new Student(102,"重地");
        Student s4 = new Student(101,"aim");
        t.add(s1);
        t.add(s2);
        t.add(s3);
        t.add(s4);
        System.out.println(t);
    }
}

3两种遍历方式

增强for循环和迭代器(iterator)

package collectionapi.set;

import java.util.Iterator;
import java.util.TreeSet;

public class TreeSetDemo3 {
    public static void main(String[] args) {
        /*
		  Set 不能存储重复元素

		  TreeSet 可以按照元素的自然顺序排序

		               底层是红黑树
		 */
        TreeSet<String> tset = new TreeSet<String>();
        tset.add("b");
        tset.add("a");
        tset.add("d");
        tset.add("c");
        tset.add("x");

        /*
         * Set遍历方式
         */

        //tset.stream().forEach((a)->System.out.print(a));

		     /* for (String t : tset) {
				 System.out.println(t);
			  }*/

        Iterator<String> it =  tset.iterator();
        while(it.hasNext()){
            String e = it.next();
            System.out.println(e);
        }
    }
}

四.Map接口

在这里插入图片描述

(1)映射(map)是一个存储键、键值对的对象,给定一个键,可以查询得到它的值,键和值都可以是对象
(2)键必须是唯一的,值可以重复(Map接口映射唯一的键到值)
(3)有些映射可以接收null键和null值,而有的不行
(4)下面的接口支持映射:
Map接口 映射唯一关键字给值
Map.Entry接口 描述映射中的元素(关键字/值对),这是Map的一个内部类
SortedMap接口 扩展Map以便关键字按升序保持

(5)键(Key)是以后用于检索值的对象,给定一个键和一个值,可以存储这个值到一个Map对象中,以后可以
使用对应的键来检索它
(6)Map接口定义的方法:
int size() 存储的键值对的个数
boolean isEmpty()判断容器中是不是空的
boolean containsKey() 判断容器中是否包含对应的键
boolean containsValue() 判断容器中是否包含指定的值
V get(Object value) 根据键来获取对应的值
V put(K key,V value) 把键值对数据添加到Map容器中
V remove(Object key) 删除Map容器中对应的key
Collection<V> values()获取Map容器中所有的值
Set<Map.Entry<K,V>>entrySet() 返回包含的映射关系的Set视图

(7)Map.Entry接口代表映射项(键值对)类型,是Map的嵌套类型
(8)Map接口定义的entrySet()方法返回包含映射项Entry的集合(Set),
集合中元素是Map.Entry类型(键值对封装在Map.Entry实现类对象中,然后把多个Entry实现类对象
放到Set容器中。)
(9)Map.Entry接口定义的方法:
K getKey()
V getValue()
V setValue(V value)

1.HashMap及常用API

(1)HashMap类是基于哈希表的Map接口的实现,并允许使用null键和null值

(2)构造方法:
HashMap()
HashMap(Map m)
HashMap(int capacity)
HashMap(int capacity,float fillRatio) fillRatio:加载因子

(3)HashMap实现Map并扩展AbstractMap,本身并没有增加任何新的方法

(4)散列映射不保证它的元素的顺序,元素加入散列映射的顺序并不一定是他们被迭代读出的顺序

(5) HashMap中元素的key值不能重复,即彼此调用equals方法,返回为false。排列顺序是不固定的

package collectionapi.map;

import java.util.HashMap;

public class HashMapDemo {

    public static void main(String[] args) {
		 /*
		   Map集合
		              键  值对存储
		              键不能重复,值可以重复
		   HashMap
		             键是无序的
		             可以存储一个为null的键
		  */
        HashMap<String,String> map = new HashMap<>();
        map.put("a","a");
        map.put("a","b");//如果有重复的键,后面值会把前面的覆盖掉
        map.put("b","b");
        map.put("p","b");
        map.put(null,"c");
        map.put(null,"n");
        //map.remove("a");
        //map.clear();
        System.out.println(map.containsKey("c"));
        System.out.println(map.containsValue("b"));
        System.out.println(map.isEmpty());
        System.out.println(map.size());
        System.out.println(map.get("p"));
        System.out.println(map);
    }

}
package collectionapi.map;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.HashMap;
import java.util.Set;

public class HashMapDemo2 {
    public static void main(String[] args) {

        HashMap<String,String> map = new HashMap<>();
        map.put("a","a");
        map.put("c","c");
        map.put("b","b");
        map.put("p","p");
           /*
	          Map 集合比遍历
		   */
        //map.forEach((k,v)->System.out.println(k+":"+v));

		    /*
		       keySet();先获取到map中所有的键,存储到Set集合中
		                 再对Set集合进行遍历,通过每次拿到key去获得对应的值
		     */
		       /* Set<String> keyset = map.keySet();
                for(String key : keyset){
             	   System.out.println(key+":"+map.get(key));
                }*/

        //Collection<String>  list  =  map.values();
        //System.out.println(list);

		     /*
		       entrySet() 将map集合中的键,值对封装到一个Entry对象中
		      */
        Set<Entry<String, String>> entrySet =  map.entrySet();
		     /* for(Entry<String, String> entry : entrySet){
		    	  System.out.println(entry.getKey()+":"+entry.getValue());
		     }*/

        Iterator<Entry<String, String>> it =   entrySet.iterator();
        while(it.hasNext()){
            Entry<String,String> entry = it.next();
            System.out.println(entry.getKey()+":"+entry.getValue());
        }

    }

}

2.TreeMap及常用API

TreeMap中所有的元素都保持着某种固定的顺序,如果需要得到一个有序的Map就应该使用TreeMap,key值所在类必须实现Comparable接口。

TreeMap适用于按自然顺序或自定义顺序遍历键(key)。TreeMap根据key值排序,key值需要实现Comparable接口,重写compareTo方法。TreeMap根据compareTo的逻辑,对key进行排序。键是红黑树结构,可以保证键的排序和唯一性

package collectionapi.map;

import java.util.Hashtable;
import java.util.TreeMap;

public class TreeMapDemo {
    public static void main(String[] args) {
		/*
	         键值对
	         键不重复
	          可以根据键的自然顺序排序,   指定的键的类型的类必需实现Comparable接口 ,排序使用
		 */
        TreeMap<Integer,String> tmap = new TreeMap<>();
        tmap.put(2, "a");
        tmap.put(1, "b");
        tmap.put(1, "c");
        tmap.put(3, "d");
        System.out.println(tmap);

		/*
		   无序的
		   初始容量是11
		   线程安全的
		  不允许存储为null的键
		 */
        Hashtable<String,String> ht = new Hashtable<>();
        ht.put("a", "a");
        ht.put("a", "b");
        ht.put("c", "c");
        ht.put(null, "d");
        System.out.println(ht);
    }
}

3.Map集合的遍历

方式1:根据键找值

  • 获取所有键的集合
  • 遍历键的集合,获取到每一个键
  • 根据键找值

方式2:根据键值对对象找键和值

  • 获取所有键值对对象的集合
  • 遍历键值对对象的集合,获取到每一个键值对对象
  • 根据键值对对象找键和值
4.Collections类
  1. 是集合类的工具类,与数组的工具类Arrays类似

  2. 定义了大量静态方法

package collectionapi.map;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class CollectionsDemo {
    public static void main(String[] args) {
        ArrayList<String> list=new ArrayList<>();
        list.add("x");
        Collections.addAll(list,"a","b","c","d");
        System.out.println(Collections.binarySearch(list,"c"));

        ArrayList<String> list1=new ArrayList<>();
                          list1.add("a");
                          list1.add("b");
                          list1.add("c");
                          list1.add("d");
        ArrayList<String> list2=new ArrayList<>();
                          list2.add("x");
                          list2.add("y");
                          list2.add("z");
                          Collections.copy(list1,list2);//要求目标集合的size不能小于sec源集合的size
        System.out.println(list1);

        /*List<Object> l=Collections.emptyList();
         l.add("a");
         l.add("a");*/

         Collections.fill(list1,"K");
        System.out.println(Collections.max(list1));
        Collections.replaceAll(list1,"x","X");
        Collections.reverse(list1);
        Collections.swap(list1,0,2);
        System.out.println(list1);


    }
}

创作不易,大佬们留步… 动起可爱的双手,来个赞再走呗 (๑◕ܫ←๑)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值