Java集合、API、Collection接口及其子类方法、Collections类

1.集合概念

​ 储存一个班的成员信息,假设一个班容纳30个人。

​ 当我们需要保存这样一组元素的时候,我们需要使用一个容器,数组就是这样一个容器。

​ 但是数组有缺点:数组一旦定义,长度就不能再变化。

​ 在开发实践中,经常需要保存一些变长的数据集合,我们需要能够动态增长长度的容器来保存我们的数据。

​ 而我们需要对数据的保存的逻辑可能各种各样,于是就有了各种各样的数据结构。Java中对于各种数据结构的实现,就是我们用到的集合。

2.集合API

​ Java的集合框架是由很多接口、抽象类、具体类组成的,位于java.util包

在这里插入图片描述

3.Collection接口

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

​ Set 中的数据对象无序且不重复。

​ List中的数据对象有序且重复

​ 在Collection中定义了一些集合中共有方法:

​ boolean add(object element);

​ boolean remove(object element);

​ boolean clear();

​ int size();

​ boolean isEmpty();

​ boolean contains(object element);

​ boolean retainAll(Collection c);求交集,集合数据发生变化就返回true,不变返回false;

public class CollectionDemo {
    public static void main(String[] args) {
        //泛型通过泛型语法为集合设置一个类型,只能储存设置的数据类型
        //集合是容器可以储存任何类型(只能是引用类型)
        Collection<String> collection = new ArrayList<>();
        collection.add("w");
        collection.add("s");
        collection.add("a");
        collection.add("f");
        Collection<String> collection1 = new ArrayList<>();
        collection1.add("a");
        collection1.add("j");
        collection1.add("k");
        collection1.add("l");
        System.out.println(collection.contains("w"));   //contains()是否包含 方法
        System.out.println(collection.equals(collection1)); //equal() 比较内容是否相同方法
        System.out.println(collection.isEmpty()); //判断是否为空
        System.out.println(collection.remove("w"));//remove() 删除某个字符串
        System.out.println(collection);
        System.out.println(collection.size());  //求长度 数组中.length属性 字符串中 .length()方法  集合中 .size()方法
        //System.out.println(collection.addAll(collection1)); //addAll() 将另一个集合全部添加进来
        //collection1.clear(); //清除
        System.out.println(collection.retainAll(collection1)); //求交集 如果有变化就是true 如果不变完全相同则为false
        System.out.println(collection);
        collection.toArray();
        Object[] a = collection1.toArray(new String[collection1.size()]);  //将集合转化为数组
        System.out.println(Arrays.toString(a));
    }
}

4.List接口及实现类

1)List继承了Collection接口,有三个实现类

​ ArrayList 数组列表,数据采用数组方式储存。

​ LinkedList 链表

​ Vector 数组列表,添加同步锁,线程安全的

2)ArrayList和LinkedList优点

​ ArrayList实现了长度可变的数组,在内存中分配连续的空间。

遍历元素和随机访问元素的效率比较高
在这里插入图片描述
LinkedList采用链表储存方式。

插入、删除元素时效率比较高

在这里插入图片描述

3)ArrayList的常用方法

​ add(int index,E element)

​ get(int index)

​ indexOf(object o)

​ lastIndexOf(object o)

​ remove(int index) 删除并返回指定位置元素

​ removeRange(int fromIndex,int toIndex) 删除指定区间的元素(子类继承使用)

​ set(int index,E element)

public class ArrayListDemo4 {
    public static void main(String[] args) {
        //去除重复元素
        ArrayList<String> arrayList = new ArrayList();
        arrayList.add("a");
        arrayList.add("b");
        arrayList.add("c");
        arrayList.add("c");
        arrayList.add("c");
        arrayList.add("d");
        arrayList.add("e");
        arrayList.add("c");
        System.out.println(arrayList);
        for(int i=0;i<arrayList.size();i++){
            for(int j =i+1;j<arrayList.size();j++){
                if(arrayList.get(i)==arrayList.get(j)){
                    arrayList.remove(j);
                    j--;
                }
            }
        }
        System.out.println(arrayList);
    }
}

4)LinkedList的常用方法

​ add(int index,object element)

​ addFirst(object element)

​ addLast(ojbect element)

​ get(int index)

​ removeFirst()

​ removeLast()

​ remove(int index)

​ getFrist()

​ getLast()

public class LinkedListDemo1 {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("a");    //默认加到后面
        linkedList.addFirst("b");   //将元素加到前面
        linkedList.addLast("c");    //将元素加到后面
        linkedList.add("d");
        System.out.println(linkedList.get(2));
        System.out.println(linkedList);
        System.out.println(linkedList.getFirst());
        System.out.println(linkedList.getLast());
        linkedList.remove(3);
        System.out.println(linkedList.removeFirst());
        System.out.println(linkedList.removeLast());
    }
}

5.List接口集合迭代

1)for循环遍历

public class ArrayList_one {
    public static void main(String[] args) {
        ArrayList<String> al = new ArrayList<>();
        al.add("No one");
        al.add("No two");
        al.add("No one");
        for(int i=0;i<al.size();i++){
            System.out.println(al.get(i));
        }
    }
}

2)增强for循环的遍历

public class HM1 {
    public static void main(String[] args) {
        HashSet<String> hs = new HashSet<>();
        Scanner scanner = new Scanner(System.in);
        Map<String, String> map = new HashMap<>();
        map.put("1930","乌拉圭");
        map.put("1934","意大利");
        map.put("1938","意大利");
        map.put("1950","乌拉圭");
        map.put("1954","西德");
        map.put("1958","巴西");
        map.put("1962","巴西");
        map.put("1966","英格兰");
        map.put("1970","巴西");
        map.put("1974","西德");
        map.put("1978","阿根廷");
        map.put("1982","意大利");
        map.put("1986","阿根廷");
        map.put("1990","西德");
        map.put("1994","巴西");
        map.put("1998","法国");
        map.put("2002","巴西");
        map.put("2006","意大利");
        map.put("2010","西班牙");
        map.put("2014","德国");
        map.put("2018","法国");
        //map.get(); 根据键输出值
        System.out.println("输入一个年份获取该年夺得的世界杯,格式例如:2002");
        String s = scanner.next();
        if(map.containsKey(s)){
            System.out.println("该年夺得世界杯的是:"+map.get(s));
        }else{
            System.out.println("这年没世界杯");
        }
        System.out.println("输入一个国家获得大力神杯的年份,格式例如:巴西");
        String s1 = scanner.next();
        if(map.containsValue(s1)){
            System.out.println("该年夺得世界杯的是:");
            for(String w:map.keySet()){
                if(map.get(w).equals(s1)){
                    hs.add(w);
                }
            }
            System.out.print(hs);
        }else{
            System.out.println("该国没得世界杯");
        }
    }
}

3)迭代器遍历(Iterator)

public class IteratirDemo {
    public static void main(String[] args) {
        ArrayList<String> al= new ArrayList<>();
        al.add("b");
        al.add("a");
        al.add("c");
        al.add("d");
        al.add("d");
        al.add("d");
        al.add("d");
        Iterator<String> it = al.iterator();
        while(it.hasNext()){
            String e = it.next();
            if(e.equals("d")){
                it.remove();
            }
        }
        System.out.println(al);
        ListIterator<String> it1= al.listIterator();
        while(it1.hasPrevious()){
            String e = it1.next();
            if(e.equals("b")){
                it1.remove();
            }
        }
        System.out.println(al);
    }
}

6.Set接口

  • Set接口继承了Collection接口。

    Set中所有储存的元素是不重复的,但是是无序的,Set中的元素是没有索引的

1)HashSet

​ HashSet类中的元素不能重复,即彼此调用equals方法比较,都返回false

​ 底层数据结构是哈希表+链表

​ 哈希表依赖于哈希值储存

public class Car {
    private int no;
    private String name;
    public Car(int no, String name) {
        this.no = no;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Car{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Car car = (Car) o;
        return no == car.no &&
                Objects.equals(name, car.name);
    }
    @Override
    public int hashCode() {
        return Objects.hash(no, name);
    }
}

public class HashSetDemo2 {
    public static void main(String[] args) {
        Car car1 = new Car(1,"劳斯莱斯");
        Car car2 = new Car(2,"法拉利");
        Car car3 = new Car(3,"兰博基尼");
        Car car4 = new Car(1,"劳斯莱斯");
        HashSet<Car> hs = new HashSet<>();
        hs.add(car1);
        hs.add(car2);
        hs.add(car3);
        hs.add(car4);
        System.out.println(hs);
    }
}
//结果是:[Car{no=2, name='法拉利'}, Car{no=3, name='兰博基尼'}, Car{no=1, name='劳斯莱斯'}]

HashSet去重原理

<1>第一种HashSet的泛型是基本数据类型

​ int类型本身的数据符合HashCode

​ float类型是32位二进制组成只需要转成int类型

​ long类型由64位二进制组成,Hashcode的解决是将long类型的高32位与低32位进行异或运算取结果的低32位,最后转换为整形。

​ double 会先将二进制转成long类型的二进制,然后再将long类型转成int

​ Boolean类型 最简单 只有true和false两种 那么只规定两个数字作为HashCode就可以

​ String类型 计算哈希值是把字符串拆分成字符数组,然后分别去计算每个字符的值进行累加,最后返回。

<2>第二种自定义对象

在这里插入图片描述
​ 去重原理解析:1.创建一个默认长度16的数组,数组名table

​ 2.根据元素的哈希值跟数组的长度求余计算出应存入的位置(哈希算法)

​ 3.判断当前位置是否为null,如果是null直接存入

​ 4.如果位置不为null.表示有元素,则调用equals方法比较

​ 5.如果一样,则不存,如果不一样,则存入数组。

自定义对象需要重写系统的hashCode方法和equals方法

​ 如果重写了系统的hashCode方法和equals方法,那么就只允许添加第一个对象,相同的第二个对象是不会添加的,这是因为 通过 对象属性计算的hash值 ,因为对象里面的属性都一直,那么 hash值是一致的,euqals判断也一致,所以就不会进行添加。

2)TreeSet

​ 可以给Set集合中的元素进行指定方式的排序。储存的对象必须实现comparable接口。

​ TreeSet底层数据结构是二叉树(红黑树是一种自平衡的二叉树)

public class TreeSetDemo {
    public static void main(String[] args) {
        Car car1 = new Car(3,"大众3",300000);
        Car car2 = new Car(2,"大众2",350000);
        Car car3 = new Car(1,"大众1",3400000);
        Car car4 = new Car(1,"大众1",3400000);
        TreeSet<Car> ts = new TreeSet<>();
        ts.add(car2);
        ts.add(car3);
        ts.add(car1);
        ts.add(car4);
        System.out.println(ts);//[Car{no=1, name='大众1', price=3400000}, Car{no=2, name='大众2', price=350000}, Car{no=3, name='大众3', price=300000}]
    }
}

7.Set接口集合迭代

​ 遍布方式有两种

1)增强for循环

2)迭代器遍历

8.Map接口

1)Map接口概述

​ 将键映射到值的对象

​ 一个映射不能包含重复的键

​ 每个键最多只能映射到一个值

2)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()

V get(Object key)

Collection values()

Set keySet()

Set<Map.Entry<K,V>> entrySet()

3)HashMap

​ HashMap中元素的key值不能重复,排序顺序是不固定的,可以储存一个为null的键。

4)TreeMap

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

适用于按自然顺序或自定义顺序遍历键(key)

​ TreeMap根据key值排序,key值需要实现comparable接口,重写compareto方法。TreeMap根据compareto的逻辑,对key进行排序。

​ 键是红黑树结构,可以保证键的排序和唯一性

5)HashTable

​ 实现了同步。

​ 不能储存为null的键。

6)Map集合遍历

​ 方式1:根据键找值

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

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

  • 获取所有键值对对象的集合
  • 遍历键值对对象的集合,获取到每一个键值对对象
  • 根据键值对对象找键和值
public class HashMapDemo2 {
    public static void main(String[] args) {
        HashMap<String,String> hm = new HashMap<>();
        hm.put("q","qqq");
        hm.put("w","www");
        hm.put("e","eee");
        //哈希图遍历  Map.Entry<>     entrySet();
        Set<Map.Entry<String,String>> entry = hm.entrySet();
        for(Map.Entry<String,String> ment: entry){
            System.out.println(ment.getKey()+"="+ment.getValue());
        }

        Set<String> hs = hm.keySet();
        for(String h :hs){
            String value = hm.get(h);
            System.out.println(h+"="+value);
        }
    }
}

9.Collections类

​ Collections是集合类的工具类,于数组的工具类Arrays类似

​ addAll(Col lection<? super T> c, T… elements);

​ binarySearch(List<? extends Comparable<? super T>> l ist, T key)

​ sort(List list)

​ sort(List list, Comparator<? super T> c)

​ swap(List<?> list, int i, int j)

​ copy(List<? super T> dest, List<? extends T> src) ; 注意 dest size需大于等于src.size

​ emptyList() 返回为空的集合,不能添加数据

​ fill(List<? super T> l ist, T obj)

​ max(Col lection<? extends T> col l)

​ min(Col lection<? extends T> col l)

​ replaceAll(List list, T oldVal, T newVal)

​ reverse(List<?> list)

​ shuffle(List<?> list) 随机排序

​ copy(dest,src)集合复制

public class CollectionsDemo {
    public static void main(String[] args) {
        ArrayList<Integer> al = new ArrayList<>();
        al.add(1);
        al.add(4);
        al.add(3);
        al.add(5);
        //排序sort();
        List<Integer> list = new ArrayList<>();
        list.add(6);
        list.add(7);
        list.add(8);
        Collections.copy(al,list);
        Collections.sort(al);
        System.out.println(al);
        //binarySearch 二分查找先排序
        System.out.println(Collections.binarySearch(al,3));
        System.out.println(Collections.max(al));
        System.out.println(Collections.min(al));
        System.out.println(al);
        System.out.println(list);
        Collections.fill(al,1);	
        System.out.println(al);
        Collections.shuffle(list);
        System.out.println(list);
        Collections.swap(list,2,1);
        System.out.println(list);
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

⁢⁢Mrx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值