【JAVA】集合

今天开始学java的集合相关知识。

  1. 集合概念
  2. 集合 API
  3. Collection接口
  4. List 接口及实现类
  5. List接口集合迭代
  6. Set 接口
  7. Set 接口集合迭代
  8. Map 接口
  9. Collections类

集合的概念 

在我们之前所学的知识中,可以存储一组元素的工具有数组,但数组一旦定义了长度就不能更改,优点是数据查找周期短,但我们经常会存储一些会变长的数据,这时我们就需要可以动态增长长度的容器,那就可以使用集合(容器)。

集合 API

Java中集合是由很多接口、抽象类和实现类组成的。

 Collection接口

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

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

public class Demo1 {
    /*
        集合
        数组一旦定义了长度就不能更改,有点是数据查找周期短
        集合是一个可以动态增长长度的容器,一个集合应该只存放一种类型数据(只能存放引用类型数据)

     */
    public static void main(String[] args) {
        Collection<String> a1=new ArrayList<>();
        a1.add("a");
        a1.add("b");
        a1.add("c");
        a1.add("d");

        Collection<String> a2=new ArrayList<>();
        a2.add("d");
        a2.add("e");
        a2.add("f");
        a2.add("b");

        a1.addAll(a2);//将a2元素加入a1
        a1.remove("c");//移除指定元素
        a1.removeAll(a2);//移除a1中与a2中相同的元素

        System.out.println(a1.size());//输出长度
        System.out.println(a1.isEmpty());//判断是否为空
        System.out.println(a1.equals(a2));//比较内容是否相同
        System.out.println(a1.contains("a"));//判断是否包含指定元素

        System.out.println(a1);
        System.out.println(a2);

        String[] s=a2.toArray(a1.toArray(new String[a2.size()]));//将集合转换为String数组
        Object []o=a2.toArray();//将集合转换为Object数组
    }
}

List 接口及实现类

List接口继承了Collection接口,有三个实现类,分别是:ArrayList类,LinkedList类,Vector类。是单列集合,可以存放重复的元素。

这三个实现类分别的作用和特点是:

ArrayList:底层创建是一个Object数组,会先创建一个长度为10的数组,需要连续的内存空间,内存使用效率低。当插入元素超过数组长度时,会新创建一个长度为原数组长度1.5倍的数组(使用底层grow()方法)。特点是数据插入,删除周期长,但查询速度快

LinkedList:底层是一个链表,内存使用效率高。特点是插入,删除周期短,但查询周期长。

Vector: 底层是数组,相较于ArrayList和LinkedList有线程安全的特点。

下面分别是这三个实现类的示例代码:

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

public class Demo2 {
    /*
    ArrayList
    底层创建是一个Object数组,会先创建一个长度为10的数组,需要连续的内存空间,内存使用效率低
    当插入元素超过数组长度时,会新创建一个长度为原数组长度1.5倍的数组(使用底层grow()方法)
    特点是数据插入,删除周期长,但查询速度快
     */
    public static void main(String[] args) {
        //List<String> a=new ArrayList<>();
        ArrayList<String> a=new ArrayList<>();
        a.add("a");
        a.add("b");
        a.add("c");
        a.add("d");
        a.add("e");
        a.add("f");
        a.add("X");
        a.add("X");
        a.add("X");
        a.add("X");
        a.add("X");
        a.add("X");

        System.out.println( a.isEmpty());//判断是否为空
        a.remove(2);//移除指定位置的元素
        System.out.println(a.size());//数组长度
        System.out.println(a.get(4));//返回指定位置元素
        a.set(1,"A");//替换

        System.out.println(a);
    }
}
import java.util.LinkedList;

public class Demo4 {
    /*
    LinkedList
    底层是一个链表,内存使用效率高
    特点是插入,删除周期短,但查询周期长
     */
    public static void main(String[] args) {
        LinkedList<String> a=new LinkedList<>();
        a.add("a");
        a.add("b");
        a.add("c");
        a.add("d");
        a.add("a");

        a.remove(2);//删除指定元素并返回该元素
        System.out.println(a.get(3));//输出指定元素
        a.set(1,"X");//替换指定元素

        System.out.println(a);

    }
}
import java.util.Vector;

public class Demo3 {
    /*
    Vector
    底层是数组,相较于ArrayList和LinkedList有线程安全的特点
     */
    public static void main(String[] args) {
        Vector<String> a=new Vector<>();
        a.add("a");
        a.add("b");
        a.add("c");
        a.add("d");
        a.add("e");
        a.add("a");
        a.add("a");


        System.out.println(a.get(0));

    }
}

List接口集合迭代

List接口集合迭代有四种方式:for循环,增强for循环,Iterator迭代器,ListIterator迭代器(只支持对List接口下的实现类)。

 下面是使用方法:

import java.util.ArrayList;
import java.util.Iterator;

public class Demo5 {
    /*
    Iterator
    迭代器迭代,返回一个ArrayList中的内部类对象,实现Iterator接口
    次内部类专门对集合进行遍历时的控制
    为集合设计的遍历工具
     */
    public static void main(String[] args) {
        ArrayList<String> a=new ArrayList<>();
        a.add("a");
        a.add("b");
        a.add("c");
        a.add("d");
        a.add("e");
        a.add("f");
        a.add("X");
        a.add("X");
        a.add("X");
        a.add("X");
        a.add("X");
        a.add("X");
        Iterator<String> iterator=a.iterator();
        while (iterator.hasNext()){//hasNext()用来判断Iterator是否还有后续
            String b=iterator.next();
            if (b.equals("X")){
                iterator.remove();
            }
        }
        System.out.println(a);
    }
}
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;

public class Demo10 {

        /*
        ListIterator
        为List接口下的集合设计的迭代器
         */
        public static void main(String[] args) {
            ArrayList<String> a=new ArrayList<>();
            a.add("a");
            a.add("b");
            a.add("c");
            a.add("d");
            a.add("e");
            a.add("f");
            a.add("X");
            a.add("X");
            a.add("X");
            a.add("X");
            a.add("X");
            a.add("X");
            ListIterator<String> listiterator=a.listIterator(2) ;//可以从指定的位置开始遍历
            while (listiterator.hasNext()){//hasNext()用来判断Iterator是否还有后续
                String b=listiterator.next();
                System.out.println(b);
            }
            System.out.println();
            while (listiterator.hasPrevious()){//hasNext()用来判断Iterator是否还有后续
                String b=listiterator.previous();//从后向前遍历
                System.out.println(b);
            }
            System.out.println(a);
        }
    }


Set接口

Set接口继承Collection接口,也是单列集合,但不能存放相同元素,是无序的,并且Set中的元素是没有索引的。set有两个实现类:HashSet和TreeSet。

HashSet:不能存放重复元素,用equals()方法来比较存放,是无序的。底层数据是依赖哈希表和链表。

TreeSet:不能存放重复元素。底层数据是二叉树,有序的(存储的对象必须实现Comparable接口)。

如何排序:HashCode()和equals()

Hashcode():先用HashCode进行比较,将元素转换成一个int值进行比较,如果值相同,再使用equals()进行比较。

equals():比较元素的内容,最安全。

import java.util.HashSet;

public class Demo6 {
    /*
    HashSet
    无序的,存放不同的元素,
    使用equals方法比较,都返回false
    底层数据结构是哈希表和链表
    哈希表依赖于哈希值存储
     */
    public static void main(String[] args) {
        HashSet<String> hashSet=new HashSet<>();
        hashSet.add("a");
        hashSet.add("b");
        hashSet.add("c");
        hashSet.add("d");
        hashSet.add("e");
        hashSet.add("e");
        hashSet.add("e");

        System.out.println(hashSet);
    }
}
import java.util.TreeSet;

public class Demo7 {
    /*
    TreeSet
    底层数据是二叉树
    存放不同元素,有序的(存储的对象必须实现Comparable接口)
     */
    public static void main(String[] args) {
        TreeSet<String> treeSet=new TreeSet<>();
        treeSet.add("x");
        treeSet.add("a");
        treeSet.add("e");
        treeSet.add("f");
        treeSet.add("c");
        treeSet.add("a");

        System.out.println(treeSet);

        Car car1=new Car(1,"奥迪");
        Car car2=new Car(2,"宝马");
        Car car3=new Car(3,"雷克萨斯");
        Car car4=new Car(4,"兰博基尼");

        TreeSet<Car> treeSet1=new TreeSet<>();
        treeSet1.add(car2);
        treeSet1.add(car4);
        treeSet1.add(car1);
        treeSet1.add(car3);

        System.out.println(treeSet1);
    }
}

Set 接口集合迭代

Set 接口集合迭代的方式有两种:增强for循环,迭代器迭代。

HashSet的迭代:

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class Demo17 {
    /*
    Set 接口集合迭代
    Set 接口集合迭代的方式有两种:增强for循环,迭代器迭代。
     */
    public static void main(String[] args) {
        Set<String> set=new HashSet<>();
        set.add("a");
        set.add("b");
        set.add("c");
        set.add("d");
        set.add("a");

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

TreeSet的迭代:

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class Demo18 {
    public static void main(String[] args) {
        Set<String> set=new TreeSet<>();
        set.add("a");
        set.add("b");
        set.add("c");
        set.add("d");
        set.add("a");

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

 

Map 接口

双列集合,一个键指向一个值,键不能重复,但是值可以重复。

Map接口的三个实现类是HashMap、HashTable、TreeMap。

HashMap:底层结构是java8,有三种数据结构:1.数组、2.链表、3.红黑树;存放键是无序的,可以存放一个null键。遍历方式有两种:一是通过键找值,通过遍历键来遍历值;二是根据键值对对象找键和值,通过遍历所有键值对对象的集合,获取每一个键值对对象,找到对象的键和值。

HashMap添加键的过程:添加一个元素时,会通过Hash计算得一个hash值,封装到一个Node对象中,将对象存储到对应位置。但有新元素存入时,没有相同地址的元素存入新地址,相同元素的地址存入存入之前元素的后一位,当链表的长度达到8,且哈希数组的长度达到64时,链表会转为红黑树。哈希数组的默认长度为16,负载因子为0.75,如果哈希数组发生扩容,每次扩容为原来的两倍。

Hashtable:相较HashMap,实现了线程安全、同步。不能存储null值。

TreeTable:存放的键有序。存储的对象必须实现Comparable接口。

import java.util.HashMap;
import java.util.TreeMap;

public class Demo9 {
    /*
    HashMap
    双列集合,键不能重复,值可以重复,不能存放重复元素,
    HashMap是如何排序的
    HashCode()和equals();
    Hashcode():先用HashCode进行比较,将元素转换成一个int值进行比较,如果值相同,再使用equals()进行比较
    equals():比较元素的内容,最安全
     */
    public static void main(String[] args) {
        TreeMap<Integer,String> map=new TreeMap<>();
        map.put(2,"金毛");
        map.put(1,"柯基");
        map.put(4,"哈士奇");
        map.put(2,"金毛");
        System.out.println(map);

        Dog dog1=new Dog(2,"金毛");
        Dog dog2=new Dog(1,"柯基");
        Dog dog3=new Dog(4,"哈士奇");
        Dog dog4=new Dog(2,"金毛");
        TreeMap<Dog,String> map2 = new TreeMap<>();
        map2.put(dog2,"123");
        map2.put(dog3,"223");
        map2.put(dog1,"323");
        map2.put(dog4,"423");
        System.out.println(map2);

        
    }
}

import java.util.Objects;

public class Dog implements Comparable<Dog>{
    int age;
    String name;

    public Dog(int age, String name) {
        this.age = age;
        this.name = name;
    }

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

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


    @Override
    public int compareTo(Dog o) {
        return this.age-o.age;
    }
}
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Demo11 {
    /*
    HashMap的遍历
    1.通过键找值
    2.通过键值对对象找键和值(推荐,尤其在容量大时)
     */
    public static void main(String[] args) {
        HashMap<Integer,String> hashMap=new HashMap<>();
        hashMap.put(2,"奥迪");
        hashMap.put(1,"宝马");
        hashMap.put(3,"雷克萨斯");

        System.out.println(hashMap);

       for (int s:hashMap.keySet()) {
           String a= hashMap.get(s);
          System.out.println(s+"="+a);
      }

        Set<Map.Entry<Integer,String>> set=hashMap.entrySet();
        for (Map.Entry<Integer,String>mappentry:set){
            System.out.println(mappentry.getKey()+"="+mappentry.getValue());
        }

    }
}

Collections类

Collections为集合提供的一个工具类,类似于Arrays数组。

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;

public class Demo12 {
    /*
    Collections
    为集合提供的一个工具类,类似于Arrays数组

    int...a
    可变长度参数
    要写在参数列表的最后,一个参数列表只能有一个可变长度参数
     */
    public static void main(String[] args) {
        //HashMap<Integer,String> hashMap=new HashMap<>();
        ArrayList<Integer> arrayList=new ArrayList<>();
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(4);
        ArrayList<Integer> arrayList2=new ArrayList<>();
        arrayList2.add(0);
        arrayList2.add(0);
        arrayList2.add(0);
        arrayList2.add(0);
        arrayList2.add(0);
        Collections.addAll(arrayList,3);//将指定元素添加到指定集合
        Collections.binarySearch(arrayList,2);//使用二分查找查找指定元素
        Collections.sort(arrayList);//排序
        Collections.swap(arrayList,3,1);//将数组内元素位置替换
        Collections.copy(arrayList2,arrayList);//将数组2的元素复制到数组1中,注意:数组1的size要比数组二大
        Collections.emptyList();//返回一个空数组,不能添加数据,常用来进行逻辑比较
        Collections.fill(arrayList,6);//用指定元素替换指定集合中所有元素
        System.out.println(Collections.max(arrayList2));//输出集合中最大元素
        System.out.println(Collections.min(arrayList2));//输出集合中最小元素
        Collections.reverse(arrayList2);//反转指定集合的元素顺序
        Collections.shuffle(arrayList2);//对指定集合随机排序

        System.out.println(arrayList);
        System.out.println(arrayList2);

        test(10,1,2,3,4,5,6);

    }
    public static void test(int a,int...b){
        System.out.println(a);
        System.out.println(b);
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值