Java的集合框架

1.集合框架

1.1为什么使用集合

        当我们需要保存相同的数据时,需要使用一个容器来进行保存,这个容器就是数组。但是数组会存在很多的弊端,例如:只能存储相同类型的数据;声明之后不能再修改长度;数据存储是有序的、可重复的,特点单一。最重要的是,在我们实际开发中,储存的数据的类型是多种多样的,所以我们就需要一个新的容器来进行数据的存储,“集合”及时这个容器。

1.2集合的架构

1.3List集合

1.3.1添加元素

// 导入List和ArrayList包
 import java.util.ArrayList;
 import java.util.List;
 ​
         // 创建集合对象
         List list = new ArrayList();// 默认长度为10  
         list.add("星期一");
         list.add("星期二");
         list.add("星期三");
         System.out.println(list);
         list.add(1,"今天休息");// 在指定位置添加内容
         System.out.println(list);
         List list1 = new ArrayList();
         list1.add(1);
         list1.add(2);
         list.add(list1); // 将list1中的元素全部添加进list中
         System.out.println(list);

1.3.2删除元素

         list.remove(2);// 删除制定下标的元素
         System.out.println(list);
         list.clear(); // 清空集合元素
         System.out.println(list);

1.3.3修改元素

        list.set(1,"星期二放假");
         System.out.println(list);

1.3.4查找元素      

         //查找操作
         Object o = list.get(1);// 根据下标查找
         System.out.println(o);
         int size = list.size();// 获取集合元素的个数
         System.out.println(size);
         boolean s = list.contains("星期天");// 查询指定元素 以Boolean值返回
         System.out.println(s);
         int index = list.indexOf("星期一"); //查询元素在集合中第一次出现的位置
         System.out.println(index);
 ​
         // 使用for循环遍历集合中的元素
         for (int i = 0; i < list.size(); i++) {
             Object o1 = list.get(i);
             System.out.println(o1);
         }

1.4 LinkedList

LinkedList是一个链表结构

1.4.1添加元素

  // 创建LinkedList
       LinkedList linkedList = new LinkedList();
         //添加元素
       linkedList.add("星期一"); // 添加到尾部
       linkedList.addFirst("星期二");// 添加到头部
       linkedList.addLast("星期三");// 添加到尾部
       linkedList.addFirst("星期四");//添加到头部
       System.out.println(linkedList);

1.4.2删除元素

          linkedList.remove(2); // 以下标删除元素
         System.out.println(linkedList);
         linkedList.removeFirst();// 删除第一个元素
         System.out.println(linkedList);
         linkedList.removeLast();//删除最后一个元素
         System.out.println(linkedList);

1.4.3修改元素

         linkedList.set(2,"星期五");//修改制定下标的元素
         System.out.println(linkedList);

1.4.4查找元素

         int size = linkedList.size();// 查询集合长度
         System.out.println(size);
 ​
         Object o = linkedList.get(1);// 查找指定下标的元素
         System.out.println(o);
         Object first = linkedList.getFirst();// 查询第一个元素
         System.out.println(first);
         Object last = linkedList.getLast();// 查询最后一个元素
         System.out.println(last);

1.4.5LinkedList的底层源码

public LinkedList() {
    }//该类的构造方法内是空的,没有任何的代码。 但是该类中有三个属性。

	transient int size = 0; //索引
    
    transient Node<E> first;// 第一个元素对象

    transient Node<E> last;// 表示最后一个元素对象
==============add的源码==========E:可以理解为object=========
    public boolean add(E e) {
        linkLast(e);
        return true;
    }

	void linkLast(E e) {
        final Node<E> l = last;
        // l:上一个节点  e:数据  null:下一个节点
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }
============Node的源码============================
    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;
        }
    }
==============get()获取元素================
    public E get(int index) {
        checkElementIndex(index); // 检查index的下标是否正确
        return node(index).item;// 返回index下标的Node对象
    }
=============node(index)====================
    Node<E> node(int index) {
		// >>:位运算,二进制运算  size >> 1 :相当于size/2
        if (index < (size >> 1)) {// 前半部分
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {	// 后半部分
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }

LinkedList查询效率低,是因为它查找数据时需要一个节点一个节点的向后查找

1.5 Set集合

1.5.1 HashSet集合

1.5.1.1创建HashSet对象

// 导入HashSet包
import java.util.HashSet;

public class Test02 {
    public static void main(String[] args) {
        HashSet hashSet = new HashSet();
        HashSet hashSet1 = new HashSet(16); // 设置初始容器的大小
         // loadFactor:---> 0.7f表示负载因子,当空间使用到70%时,要求扩容
        HashSet hashSet2 = new HashSet(10,0.7f);       
    }
}

1.5.1.2添加元素

// 添加元素
		hashSet.add("星期一");
        hashSet.add("星期二");
        hashSet.add("星期三");
        hashSet.add("星期四");
        System.out.println(hashSet);
        HashSet set = new HashSet();
        set.add("一月");
        set.add("二月");
        set.add("三月");
        hashSet.addAll(set);
        System.out.println(hashSet);

 1.5.1.3 删除元素

// 删除元素
		hashSet.remove("一月"); // 因为是乱序放入,所以删除元素需要指定该元素
        System.out.println(hashSet);
 		hashSet.clear(); // 清空集合中的所有元素
        System.out.println(hashSet);

 

 1.5.1.4 查找元素

 // 查找元素
        boolean empty = hashSet.isEmpty();// 判断集合是否为空,以布尔值返回
        System.out.println(empty);
        boolean b = hashSet.contains("三月");// 判断该元素是否在集合中,以布尔值返回
        System.out.println(b);

1.5.1.5 hashSet的遍历

//遍历
// foreach 遍历
        for (Object o:hashSet){
            System.out.println(o);
        }
// 迭代器遍历
        Iterator iterator = hashSet.iterator(); // 获取迭代器对象
        while (iterator.hasNext()){ // 判断指针是否能够移动
            Object next = iterator.next(); // 指针移动并获取当前的元素
            System.out.println(next);
        }

1.5.1.6 hashSet的源码


public HashSet() {
        map = new HashMap<>();
    }
 //在创建一个HashSet的对象时,底层创建的是HashMap。所以HashMap的底层原理就是hashset的底层原理。

1.5.2 TreeSet集合

TreeSet中的方法和HashSet中的方法一模一样,只是他们的实现不一样。 TreeSet 基于TreeMap 实现。TreeSet可以实现有序集合,但是有序性需要通过比较器实现。

// 存储String类型
		TreeSet treeSet = new TreeSet();
        treeSet.add("周二");
        treeSet.add("周一");
        treeSet.add("周三");
        treeSet.add("周二");
        treeSet.add("周三");
        System.out.println(treeSet);

// 存储一个对象类型
public class Test04 {
    public static void main(String[] args) {
        TreeSet treeSet = new TreeSet();//TreeSet不允许重复元素
        treeSet.add(new Student("孙悟空",18));
        treeSet.add(new Student("猪八戒",17));
        treeSet.add(new Student("沙僧",17));
        treeSet.add(new Student("白龙马",16));
        System.out.println(treeSet);
    }
}
// 发现: TreeSet中的元素必须实现Comparable接口 方可放入TreeSet

 在String中实现了Comparable接口才能接收数据,所以需要在Student类中也实现该接口

//实现Comparable接口解决问题
import java.util.TreeSet;

public class Test04 {
    public static void main(String[] args) {
        TreeSet treeSet = new TreeSet();//TreeSet不允许重复元素
        treeSet.add(new Student("孙悟空",18));
        treeSet.add(new Student("猪八戒",17));
        treeSet.add(new Student("沙僧",17));
        treeSet.add(new Student("白龙马",16));
        System.out.println(treeSet);
    }
}
class Student implements Comparable{
    // 设置私有属性
    private String name;
    private Integer age;

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public Student(String name,Integer age){
        this.name = name;
        this.age = age;
    }
    public Student(){

    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public int compareTo(Object o) {
        Student student = (Student) o;
        System.out.println(this+"=======>"+o);
        // age作为对比对象,this.age大则放后面
        if (this.age>student.age){
            return 1;
        }
        // age作为对比对象,this.age小则放前面
        if (this.age<student.age){
            return -1;
        }
        // age作为对比对象,this.age相同则不写入集合
        return 0;
    }
}

第二种解决方式,也是最常使用的,就是在创建TreeSet时指定其排序规则,自己对其排序规则进行定义,这样就能避免对已定义好的类进行修改。

//定义MyComparator类,为TreeSet指定排序规则
import java.util.Comparator;

public class MyComparator implements Comparator {
    @Override
    public int compare(Object o1, Object o2) {
        Student s1 = (Student) o1;
        Student s2 = (Student) o2;
        if (s1.getAge()>s2.getAge()){
            return 1;
        }else if (s1.getAge()<s2.getAge()){
            return -1;
        }else {
            return 0;
        }
    }
}

import java.util.TreeSet;

public class Test04 {
    public static void main(String[] args) {
        // 调用MyComparator类为TreeSet指定排序规则
        TreeSet treeSet = new TreeSet(new MyComparator());
        treeSet.add(new Student("孙悟空",18));
        treeSet.add(new Student("猪八戒",17));
        treeSet.add(new Student("沙僧",17));
        treeSet.add(new Student("白龙马",16));
        System.out.println(treeSet);
    }
}
class Student {
    // 设置私有属性
    private String name;
    private Integer age;

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public Student(String name,Integer age){
        this.name = name;
        this.age = age;
    }
    public Student(){

    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

1.6 Map

map中得每个元素属于键值对模式。 如果往map中添加元素时,需要添加key 和 value. 它也属于一个接口,该接口常见得实现类有: HashMap.

1.6.1创建Map对象

import java.util.HashMap;
import java.util.Map;

public class Test01 {
    public static void main(String[] args) {
        Map map = new HashMap();// 默认初始大小为16,负载因子为0.75,可自己进行修改
        Map map1 = new HashMap(20);//设置初始空间大小
        Map map2 = new HashMap(20,0.7f);//设置初始大小和负载因子
        
    }
}

1.6.2添加元素

 //添加操作 	  key   value
        map.put("孙悟空",500);
        map.put("猪八戒",600);
        map.put("沙悟净",600);
        map.put("白龙马",400);
        System.out.println(map);
        map.put("猪八戒",18);
        System.out.println(map);

		map1.put("张三",18);
        map1.put("李四",18);
        map.putAll(map1);// 将map1中元素全部添加到map中
        System.out.println(map);
        map.putIfAbsent("孙悟空",20);// 如果指定的key存在则不添加,不存在则添加
        System.out.println(map);

1.6.3删除元素

//删除操作
        map.remove("白龙马");//根据指定的key值进行与对应元素的移除
        System.out.println(map);
        map.clear();// 清空容器
        System.out.println(map);

 

1.6.4修改元素

// 修改元素
// 通过对应的key值修改元素,也可以直接使用put进行添加,只要key值相同就可以直接进行覆盖
        map.replace("白龙马",18);
        System.out.println(map);

 

1.6.5查找元素

// 查找元素
        boolean s = map.containsKey("孙悟空");//根据指定key值查找元素,返回Boolean值
        System.out.println(s);
        Object o = map.get("孙悟空");//根据指定的key值获取对应的value值
        System.out.println(o);
        Object f = map.get("唐僧");// key值不存在,对应的value值为null
        System.out.println(f);
		Set keys = map.keySet();//返回map中的所有key
        System.out.println(keys);

        //遍历map
        for (Object k:keys){
            Object o1 = map.get(k);
            System.out.println(o1);// 根据获得key值,输出对应的value值

        }

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值