您好,欢迎访问代理记账网站
移动应用 微信公众号 联系我们

咨询热线 -

电话 15988168888

联系客服
  • 价格透明
  • 信息保密
  • 进度掌控
  • 售后无忧

JAVA自学笔记(集合)

集合

1、集合

  • 概念:对象的容器,实现类对对象常用的操作,类似数组功能。

  • 和数组的区别:

    • 数组长度固定,集合长度不固定。

    • 数组可以存储基本类型和引用类型,集合只能存储引用类型。

  • 位置:java.util*

2、collection父接口

  • 注意事项:1.在迭代器中,不能连续调用it.next() 2.在迭代过程中不能使用collection.remove(),可以使用迭代器的删除,it.remove()

  • 特点:代表一组任意类型的对象,无序、无下标、不能重复

  • 迭代器迭代过程中,不能使用collection的删除方法,可以使用iterator(迭代器)的删除方法

  • 方法:

    • public static void main(String[] args) {
          //创建集合
          Collection collection = new ArrayList();
          //添加元素   add
          collection.add("苹果");
          collection.add("xigua");
          collection.add(3306);
          collection.add('a');
          //获取集合元素个数  collection.size
          System.out.println("删除前元素个数:"+collection.size());   //删除前元素个数:4
          //遍历元素
          //通过加强for进行便利
          System.out.println("----------通过加强for进行便利-----------");
          for (Object o:collection) {
              System.out.println(o);  //苹果   xigua   3306   a
          }
          //通过迭代器遍历  iterator   
          System.out.println("----------通过加强Iterator进行便利-----------");
          Iterator iterator = collection.iterator();
          while (iterator.hasNext()){
              Object o = iterator.next();
              System.out.println(o);    //苹果  xigua  3306  a
          }
      ​
          //删除元素  remove    iterator.remove
          collection.remove("苹果");
          System.out.println("删除后元素个数:"+collection.size());   //删除后元素个数:3
          //判断元素是否存在   collection.contains
          System.out.println(collection.contains("xigua"));   //true
           //清除数据
              collection.clear();
              System.out.println(collection.size());   //0
      }
      ​

3、List子接口

  • 特点:有序(添加的顺序和便利的顺序一样)、有下标、元素可以重复

  • 方法:

    • public static void main(String[] args) {
          List list = new ArrayList();
          //添加元素
          list.add("孙二");
          list.add("张三");
          list.add("李四");
          //通过下标向集合添加元素
          list.add(0,"赵大");
          System.out.println(list.toString());   //[赵大, 孙二, 张三, 李四]
      ​
          //获取下标为2的元素
          Object o = list.get(2);
          System.out.println(o);  //张三  下标为2,第三个元素
      ​
          //将下标为2的 张三 改为  王三
          list.set(2,"王三");
          System.out.println(list.get(2));   //王三
      ​
          //遍历数组
          //使用for循环遍历集合,因为List集合有下标
          System.out.println("------使用for循环遍历集合,因为List集合有下标------");
          for(int i = 0;i<list.size();i++){
              System.out.print(list.get(i)+"\t"); //赵大  孙二   王三 李四
          }
          System.out.println();
          //使用增强for遍历List集合
          System.out.println("-----使用增强for遍历List集合--------");
          for (Object o1: list) {
              System.out.print(o1+"\t");   //赵大  孙二 王三 李四
          }
          System.out.println();
          //使用迭代器listiterator遍历集合
          ListIterator iterator = list.listIterator();
          //顺序遍历数组
          System.out.println("-------顺序遍历数组-------");
          while (iterator.hasNext()){
              System.out.print(iterator.nextIndex()+":"+iterator.next());  //0:赵大1:孙二2:王三3:李四
          }
          System.out.println();
          System.out.println("-------逆序遍历数组-------");
          while (iterator.hasPrevious()){
              System.out.print(iterator.previousIndex()+":"+iterator.previous());  //3:李四2:王三1:孙二0:赵大
          }
          System.out.println();
          //判断元素是否存在
          System.out.println(list.contains("张三"));   //false
      ​
          //判断集合是否为空
          System.out.println(list.isEmpty());   //false
          list.add("小莲花");
          list.add("小翠");
          System.out.println(list.toString());   //[赵大, 孙二, 王三, 李四, 小莲花, 小翠]
          //subList获取一个子集合  含头不含尾
          List list1 = list.subList(list.size()-2,list.size());
          System.out.println(list1.toString());   //[小莲花, 小翠]
      ​
      }

ArrayList源码分析(查询快,增删慢,数组结构)

  • 默认容量大小DEFAULT_CAPACITY:10

  • 初始化调用无参构造ArrayList集合,数组长度是0

  • 如果没有向集合中添加任何元素,默认容量是:0

  • 添加第一个元素之后,数组容量扩容为10

  • 存放元素的数组:elementData

  • size:实际元素个数

  • 扩容原理:扩容为原来的1.5倍,原大小使用二进制表示,然后右移,最后相加

  • 使用System.arraycopy实现复制方法,将原集合的数据拷贝到扩容后的集合

  • add() 添加元素

    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
    ​
    private void add(E e, Object[] elementData, int s) {
            if (s == elementData.length)
                elementData = grow();
            elementData[s] = e;
            size = s + 1;
        }
    ​
    ​

ArrayList常用方法

  • ArrayList.remove(Object o),只会删除第一个遇到的相同元素,并且返回true

public static void main(String[] args) {
    Student s1 = new Student("小翠",15,"女");
    Student s2 = new Student("小莲花",17,"女");
    Student s3 = new Student("小月",19,"女");
    Student s4 = new Student("厚本",29,"女");
    ArrayList arrayList = new ArrayList();
    //添加元素
    arrayList.add(s4);
    arrayList.add(s1);
    arrayList.add(s2);
    arrayList.add(s3);
    System.out.println(arrayList.toString());  //[Student{name='厚本', age=29}, Student{name='小翠', age=15},
                                       // Student{name='小莲花', age=17},Student{name='小月', age=19}]
    //删除元素
    arrayList.remove(new Student("厚本",29,"女"));
    System.out.println(arrayList.toString());      //[Student{name='小翠', age=15}, Student{name='小莲花', age=17},
                                           // Student{name='小月', age=19}]
​
    //查找位置
    System.out.println(arrayList.indexOf(new Student("小翠",15,"女")));   //0
}

LinkedList集合方法

LinkedList linkedList = new LinkedList();
Student s1 = new Student("小翠",15,"女");
Student s2 = new Student("小莲花",17,"女");
Student s3 = new Student("小月",19,"女");
Student s4 = new Student("厚本",29,"女");
//添加元素
linkedList.add(s1);
linkedList.add(s2);
linkedList.addFirst(s3);//将元素添加到第一个
linkedList.add(s4);
System.out.println(linkedList.toString());
//删除元素
linkedList.remove(s4);  //使用equals
System.out.println(linkedList.toString());
//迭代器遍历元素
System.out.println("--------迭代器遍历元素--------");
Iterator iterator = linkedList.iterator();
while (iterator.hasNext()){
    System.out.println(iterator.next().toString());
}
​
//列表迭代器
System.out.println("--------列表迭代器遍历元素--------");
ListIterator listIterator = linkedList.listIterator();
System.out.println("   -----列表迭代器先序遍历元素----");
while (listIterator.hasNext()){
    System.out.println(listIterator.previousIndex()+":"+listIterator.next().toString());
}
System.out.println("   -----列表迭代器后序遍历元素----  ");
while (listIterator.hasPrevious()){
    System.out.println(listIterator.previousIndex()+":"+listIterator.previous().toString());
}
//判断
System.out.println(linkedList.contains(s1));
System.out.println(linkedList.isEmpty());
​
//查找位置
System.out.println(linkedList.indexOf(s1));

队列

**
 * 队列:先进先出,数据结构的一种
 * Queue:队列的接口,LinkedList实现
 * 核心操作
 *     入队:offer()
 *     出队:poll()
 */
public class DemoQueue {
    public static void main(String[] args) {
        //创建队列
        Queue queue = new LinkedList();
        //入队(添加元素)
        queue.offer("北京1");
        queue.offer("上海2");
        queue.offer("深圳3");
        System.out.println("元素个数:"+ queue.size());   //元素个数:3
        System.out.println("直接打印:"+queue.toString());   //直接打印:[北京1, 上海2, 深圳3]
        //出队(删除元素)
        System.out.println("-----出队-----");
        int size = queue.size();
        for (int i =0;i<size;i++){
            System.out.println(queue.poll());   //北京1   上海2   深圳3
        }
        System.out.println("出队后的个数:"+queue.size());  //出队后的个数:0
    }
}

/**
 * 栈:先进后出的一种数据结构
 * 可以使用LinkedList代替,LinkedList也实现了栈结构
 * Stack类:继承Vector
 * 出栈必须使用一个变量来获取栈的长度,因为出栈的过程中,栈的元素个数一直在减少
 * 核心操作
 *    push();进栈
 *    pop();出栈
 */
public class DemoStack {
    public static void main(String[] args) {
        //创建一个栈
        Stack stack = new Stack();
        //进栈  (添加元素)
        stack.push("北京1");
        stack.push("上海2");
        stack.push("深圳3");
        System.out.println("元素个数:"+stack.size());   //元素个数:3
        System.out.println("直接打印:"+stack.toString());   //直接打印:[北京1, 上海2, 深圳3]
        //出栈(删除元素)
        System.out.println("-----出栈-----");
        int size = stack.size();
        for(int i = 0;i<size;i++){
            String s = (String)stack.pop();
            System.out.println(s);    //深圳3   上海2   北京1
        }
        System.out.println("出栈之后的元素个数:"+stack.size());  //出栈之后的元素个数:0
    }
}

泛型

概念:

  • 参数化类型、类型安全的集合,强制集合元素的类型必须一致

特点:

  • 编译时即可检查,而非运行时抛出异常

  • 访问时,不必类型转化(拆箱)

  • 不同泛型之间引用不能相互赋值

优点

  • 提高代码的重用性

  • 防止类型转换异常,增加代码安全性

泛型的使用:泛型类

  • 泛型类:在类名的后面添加<T,E,K,V.....>type,value,key,element

  • <T>表示类型占位符,代表一种引用类型。多个占位符之间使用逗号隔开

  • 静态方法不能使用泛型,泛型只有在创建对象是才确定类型,静态方法通过类名.访问。

泛型方法:

  • 在方法返回值的前面添加<T,....>

  • 调用方法时确定类型

泛型接口:在接口名后面添加<T,....>

  • <T,...>表示类型占位符,代表一种引用类型。多个占位符之间使用逗号隔开

  • 泛型接口不能创建泛型常量,常量必须进行赋值,创建接口时,才能确定泛型类型,

注意

  • 泛型不能在类中声明静态属性

    • static修饰的属性是静态属性,先于对象,泛型类型取决于创建对象是传入的实际类型

  • 泛型不能再类中初始化对象或者数组,但是可以声明引用或者数组

    • 实例化对象需要分配空间,没有确定类型不能开辟空间

    • 初始化数组时需要给元素进行分配空间,泛型类型不确定,无法分配空间

  • 在类中不能使用泛型声明参数相同的个数重载

  • 使用不同实际类型创建出的泛型类对象的引用不可以互相赋值

  • 泛型的类型不能作为重载的依据

    • 泛型的限制:

      • 泛型上限:? extends Student ?代表Student类型或者Student类型的子类

      • 泛型下限: ? supper Student ?代表Student类型或者Student类型的父类

      • public static void main(String[] args) {
            ArrayList<String> name = new ArrayList<>();
            name.add("张三");
            name.add("张si");
            name.add("张wu");
            show(name);
            ArrayList<Integer> num = new ArrayList<>();
            num.add(100);
            num.add(200);
            num.add(300);
            show(num);
        }
        public static void show(ArrayList<?>  list){  //?  表示任意类型
            for(int i =0;i<list.size();i++){
                System.out.println(list.get(i));
            }
        }

Collections工具类

//创建集合
ArrayList<Integer> nums = new ArrayList<>();
nums.add(16);
nums.add(17);
nums.add(14);
nums.add(11);
nums.add(20);
//sort排序
System.out.println("排序之前:"+nums.toString());   //排序之前:[16, 17, 14, 11, 20]
Collections.sort(nums);
System.out.println("排序之后:"+nums.toString());   //排序之后:[11, 14, 16, 17, 20]

//二分查找
int pos = Collections.binarySearch(nums,20);
if(pos>=0){
    System.out.println("找到了"+pos);   //找到了4
}else {
    System.out.println("没找到");
}
//copy复制
ArrayList<Integer> dest = new ArrayList<>();
for(int i=0;i<nums.size();i++){
    dest.add(0);
}
Collections.copy(dest,nums);
System.out.println("dest:" + dest.toString());    //dest:[11, 14, 16, 17, 20]

//reverse  反转
Collections.reverse(nums);
System.out.println("反转之后:"+ nums);   //反转之后:[20, 17, 16, 14, 11]

//shuffle随机打乱
Collections.shuffle(nums);
System.out.println("打乱之后:"+nums);  //打乱之后:[16, 14, 20, 17, 11]

Set 接口

特点

  • 无序(取出元素的顺序和存入的顺序不一样)、无下标、元素不可重复

方法

  • 全部继承自Collection中的方法

    public static void main(String[] args) {
        //创建集合
        Set<String> set = new HashSet<>();
        //添加元素
        set.add("北京");
        set.add("深圳");
        set.add("北京");
        set.add("上海");
        set.add("北京");
        System.out.println("元素个数:"+set.size());
        System.out.println("直接打印:"+set.toString());
    
        //删除
         set.remove("北京");
        //遍历
        //3.1增强for
        for (String s:set) {
            System.out.println(s);
        }
        //3.2迭代器
        Iterator iterator =set.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        //判断是否存在和判断是否为空
        System.out.println(set.contains("北京"));
        System.out.println(set.isEmpty());

HashSet

  • 存储结构 :哈希表(数组+链表)

  • 基于hashCode、equals实现元素不重复:当输入元素的哈希值相同时,会调用equals进行确认,结果为true,拒绝后者进入。

public static void main(String[] args) {
    //创建集合
    HashSet<Student> hashSet = new HashSet<>();
    Student s1 = new Student("张三",15,"男");
    Student s2 = new Student("李四",15,"男");
    Student s3 = new Student("王五",15,"男");
    //添加元素
    hashSet.add(s1);
    hashSet.add(s2);
    hashSet.add(s3);
    hashSet.add(new Student("王五",15,"男"));
    System.out.println("元素个数:"+hashSet.size());
    System.out.println("直接打印:"+ hashSet.toString());
    //删除
    hashSet.remove(new Student("李四",15,"男"));
    System.out.println("删除之后元素个数:"+hashSet.size());
    System.out.println("删除之后直接打印:"+ hashSet.toString());
    //遍历
    //3.1增强for
    for (Student s : hashSet) {
        System.out.println(s.toString());
    }
    //3.2迭代器
    Iterator<Student> iterator = hashSet.iterator();
    while (iterator.hasNext()){
        System.out.println(iterator.next());
    }
    //判断
    System.out.println(hashSet.contains(s1));
    System.out.println(hashSet.isEmpty());

TreeSet

  • 基于排序顺序实现元素不重复

  • 实现了SortedSet接口,对集合元素自动排序

  • 元素对象的类型必须实现Comparable接口,指定排序规则。

  • 通过CompareTo方法确定是否为重复元素。左边比根小,右边比根小

  • 需求:元素必须实现comparable接口,compareTo()返回零代表重复元素


分享:

低价透明

统一报价,无隐形消费

金牌服务

一对一专属顾问7*24小时金牌服务

信息保密

个人信息安全有保障

售后无忧

服务出问题客服经理全程跟进