当前位置: 首页 > news >正文

Java入门基础16:集合框架1(Collection集合体系、List、Set)

集合体系结构

Collection是单列集合的祖宗,它规定的方法(功能)是全部单列集合都会继承的。

collection集合体系

Collection的常用方法

package com.itchinajie.d1_collection;import java.util.ArrayList;
import java.util.HashSet;/*
* 目标:认识Collection体系的特点。
* */
public class CollectionTest1 {public static void main(String[] args) {//简单确认一下Collection集合的特点。ArrayList<String> list=new ArrayList<>();//有序 可重复 有索引list.add("java1");list.add("java2");list.add("java1");list.add("java2");System.out.println(list);HashSet<String>set = new HashSet<>();set.add("java1");set.add("java2");set.add("java1");set.add("java2");set.add("java3");System.out.println(set);}
}package com.itchinajie.d1_collection;import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;public class CollectionTest2API {public static void main(String[] args) {Collection<String> c = new ArrayList<>();// 多态写法//1.public boolean add(Ee):添加元素,添加成功返回true。c.add("java1");c.add("java1");c.add("java2");c.add("java2");c.add("java3");System.out.println(c);//2.public void clear():清空集合的元素。//c.clear();//system.out.println(c);//3.public boolean isEmpty():判断集合是否为空是空返回true,反之。System.out.println(c.isEmpty()); // false//4.public int size():获取集合的大小。System.out.println(c.size());//5.public boolean contains(object obj):判断集合中是否包含某个元素。System.out.println(c.contains("java1")); // trueSystem.out.println(c.contains("Java1")); // false//6.public boolean remove(Ee):删除某个元素:如果有多个重复元素默认删除前面的第一个!System.out.println(c.remove( "java1"));System.out.println(c);//7.public Object [] toArray();把集合转换成数组Object[] arr = c.toArray();System.out.println(Arrays.toString(arr));String[] arr2 = c.toArray(new String[c.size()]);System.out.println(Arrays.toString(arr2));System.out.println("------------------------------------");//把一个集合的全部数据倒入到另一个集合中去。Collection<String>c1 = new ArrayList<>();c1.add("java1");c1.add("java2");Collection<String> c2 = new ArrayList<>();c2.add("java3");c2.add("java4");c1.addAll(c2);//就是把c2集合的全部数据倒入到c1集合中去。System.out.println(c1);System.out.println(c2);}
}

Collection的遍历方式

迭代器

迭代器是用来遍历集合的专用方式(数组没有迭代器),在到ava中迭代器的代表是Iterator

package com.itchinajie.d2_collection_traverse;import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;/*
* 目标:Collection集合遍历方式一:使迭代器Iterator遍历
* */
public class CollectionDemo1 {public static void main(String[] args) {Collection<String> c = new ArrayList<>();c.add("赵敏");c.add("小昭");c.add("素素");c.add("灭绝");System.out.println(c);//c=[赵敏,小昭,素素,灭绝]//                                       it//使用迭代器遍历集合//1、从集合对象中获取迭代器对象。Iterator<String> it = c.iterator();
//        System.out.println(it.next());
//        System.out.println(it.next());
//        System.out.println(it.next());
//        System.out.println(it.next());//System.out.println(it.next());//出现异常的//2、我们应该使用循环结合迭代器遍历集合。while (it.hasNext()){
//            String ele = it.next();
//            System.out.println(ele);System.out.println(it.next());}}
}

增强for

增强for可以用来遍历集合或者数组。

增强for遍历集合,本质就是迭代器遍历集合的简化写法。

package com.itchinajie.d2_collection_traverse;import java.util.ArrayList;
import java.util.Collection;/** 目标:Collection集合遍历方式二:增强for* */
public class CollectionDemo2 {public static void main(String[] args) {Collection<String> c = new ArrayList<>();c.add("赵敏");c.add("小昭");c.add("素素");c.add("灭绝");System.out.println(c);//c=[赵敏,小昭,素素,灭绝]//                    ele//使用增强for遍历集合或者数组。for (String ele : c){System.out.println(ele);}String[] names = {"迪丽热巴","古力娜扎","稀奇哈哈"};for (String name : names){System.out.println(name);}}
}

Lambda表达式

得益于刊DK8开始的新技术Lambda表达式,提供了一种更简单、更直接的方式来遍历集合。

package com.itchinajie.d2_collection_traverse;import java.util.ArrayList;
import java.util.Collection;/*
* 目标:Collection集合的遍历方式三:JDK8开始新增的lambda表达式(forEach方法)
* */
public class CollectionDemo3 {public static void main(String[] args) {Collection<String> c = new ArrayList<>();c.add("赵敏");c.add("小昭");c.add("殷素素");c.add("周芷若");System.out.println(c);//[赵敏,小昭,般素素,周芷若]//        s//default void forEach(Consumer<?superT>action): 结合Lambda表达式遍历集合://        c.forEach(new Consumer<String>() {
//            @Override
//            public void accept(String s) {
//                System.out.println(s);
//            }
//        });
//        //简化
//        c.forEach((String s) -> {
//                System.out.println(s);
//        });//简化
//        c.forEach( s -> {
//            System.out.println(s);
//        });//简化
//        c.forEach( s -> System.out.println(s));c.forEach( System.out::println);}
}

List系列集合

List集合的特有方法 List集合因为支持索引,所以多了很多与索引相关的方法,当然,Collection的功能List也都继承了。

List集合的特有方法

package com.itchinajie.d3_collection_list;import java.util.ArrayList;
import java.util.List;/**目标:掌握List系列集合的特点,以及其提供的特有方法。*/
public class ListTest1 {public static void main(String[] args) {//1.创建一个ArrayList集合对象(有序、可重复、有索引)List<String> list = new ArrayList<>();// 一行经典代码list.add("蜘蛛精");list.add("至尊宝");list.add("至尊宝");list.add("牛夫人");System.out.println(list);//【蜘蛛精,至尊宝,至尊宝,牛夫人]//2.public void add(int index,E element):在某个索引位置插入元素。list.add( 2,"紫霞仙子");System.out.println(list);//3.public E remove(int index):根据索引删除元素,返回被删除元素System.out.println(list.remove(2));System.out.println(list);//4.public E get(int index):返回集合中指定位置的元素。System.out.println(list.get(3));//5.public E set(int index,E element):修改索引位置处的元素,修改成功后,会返回原来的数据System.out.println(list.set(3,"牛魔王"));System.out.println(list);}
}

遍历方式

List集合支持的遍历方式:

1、for循环(因为List集合有索引)

2、迭代器

3、增强for循环(foreach遍历)

4、Lambda表达式

package com.itchinajie.d3_collection_list;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;/*
* List集合支持的遍历方式:
1、for循环(因为List集合有索引)
2、迭代器
3、增强for循环
4、Lambda表达式
* */
public class ListTest2 {public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("糖宝宝");list.add("蜘蛛精");list.add("至尊宝");//(1)for循环for (int i=0;i<list.size();i++){//i=012String s = list.get(i);System.out.println(s);}//(2)迭代器Iterator<String> it = list.iterator();while (it.hasNext()){System.out.println(it.next());}//(3)增强for循环(foreach循环)for (String s : list) {System.out.println(s);}//(4)JDK1.8开始之后的Lambda表达式list.forEach(s -> {System.out.println(s);});}
}

ArrayList集合的底层原理

特点

1、基于数组实现的

2、查询速度快(注意:是根据索引查询数据快):查询数据通过地址值和索引定位,查询任意数据耗时相同。

3、删除效率低:可能需要把后面很多的数据进行前移。

4、添加效率极低:可能需要把后面很多的数据后移,再添加元素;或者也可能需要进行数组的扩容。

底层原理

1、利用无参构造器创建的集合,会在底层创建一个默认长度为0的数组;

2、添加第一个元素时,底层会创建一个新的长度为10的数组;

3、存满时,会扩容1.5倍;

4、如果一次添加多个元素,1.5倍还放不下,则新创建数组的长度以实际为准。

ArrayList集合的应用原理

1、ArrayList适合:根据索I查询数据 ,比如根据随机索引数据(高效)!或者数据量 不是很大时!

2、ArrayList不适合:数据量大的同时 ,又要频繁的进行增删操作!

LinkedList集合的底层原理

基于双链表实现的。

什么是链表?有啥特点?

单项链表:链表的特点1: 查询慢,无论查询哪个数据都要从头开始找;
                  链表的特点2: 链表增删相对快。

双向链表(基于双链表实现):基于双链表实现的。
特点:查询慢,增删相对较快,
但对首尾元素进行增删改查的速度是极快的。

新增首尾操作的特有方法

LinkedList集合的应用场景

1、用来设计队列

2、用来设计栈

package com.itchinajie.d3_collection_list;import java.util.LinkedList;/**目标:掌握List系列集合的特点,以及其提供的特有方法。*/
public class ListTest3 {public static void main(String[] args) {//1、创建一个队列。LinkedList<String> queue = new LinkedList<>();//入队queue.addLast("第1号人");queue.addLast("第2号人");queue.addLast("第3号人");queue.addLast("第4号人");System.out.println(queue);//出队System.out.println(queue.removeFirst());System.out.println(queue.removeFirst());System.out.println(queue.removeFirst());System.out.println(queue);System.out.println("------------------------------------");//2、创建一个栈对象。LinkedList<String> stack = new LinkedList<>();//压栈
//        stack.addFirst("第1颗子弹");
//        stack.addFirst("第2颗子弹");
//        stack.addFirst("第3颗子弹");
//        stack.addFirst("第4颗子弹");stack.push("第1颗子弹");stack.push("第2颗子弹");stack.push("第3颗子弹");stack.push("第4颗子弹");System.out.println(stack);//出栈
//        System.out.println(stack.removeFirst());
//        System.out.println(stack.removeFirst());System.out.println(stack.pop());System.out.println(stack.pop());System.out.println(stack);}
}

set系列集合

package com.itchinajie.d4_collection_set;import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;/*
* 目标:整体了解一下Set系列集合的特点
* */
public class SetTest1 {public static void main(String[] args) {//1、创建一个Set集合的对象//Set<Integer>set =new HashSet<>();//创建了一个HashSet的集合对象。 一行经典代码 HashSet:无序不重复无索引,// 不支持索引操作,一般只会无序一次// Set<Integer> set = new LinkedHashSet<>();//有序 不重复 无索引Set<Integer> set =new TreeSet<>();//可排序(升序) 不重复 无索引set.add(666);set.add(555);set.add(555);set.add(888);set.add(888);set.add(777);set.add(777);System.out.println(set);}
}

HashSet

哈希值

就是一个int类型的数值,Java中每个对象都有一个哈希值。
Java中的所有对象,都可以调用Obejct类提供的hashCode方法,返回该对象自己的哈希值。

package com.itchinajie.d4_collection_set;
/***目标:了解一下哈希值。*Java中的所有对象,都可以调用Obejct类提供的hashCode方法,返回该对象自己的哈希值。* public int hashcode():返回对象的哈希值。*同一个对象多次调用hashCode方法返回的哈希值是相同的。*不同的对象,它们的哈希值一般不相同,但也有可能会相同(哈希碰撞)。*/
public class SetTest2 {public static void main(String[] args) {Student s1 = new Student("蜘蛛精",25,169.5);Student s2 = new Student("紫霞",24,166.5);System.out.println(s1.hashCode());System.out.println(s1.hashCode());System.out.println(s2.hashCode());String str = new String("abc");String str2 = new String("acD");System.out.println(str.hashCode());System.out.println(str2.hashCode());}
}

对象哈希值的特点

同一个对象多次调用hashCode()方法返回的哈希值是相同的。
不同的对象,它们的哈希值一般不相同,但也有可能会相同(哈希碰撞)。

HashSet的底层原理

了解一下数据结构(树)

1、普通二叉树(无用)

2、二叉查找树(二叉排序树)

小的存左边, 大的存右边, 一样的不存。

3、平衡二叉树(java常用)

4、java用的红黑树

深入理解HashSet集合去重复的机制。

HashSet集合默认不能对内容一样的两个不同对象去重复!

比如内容一样的两个学生对象存入到HashSet集合中去,HashSet集合是不能去重复的!

如何让HashSet集合能够实现对内容一样的两个不同对象也能去重复???

如果希望Set集合认为2个内容一样的对象是重复的 必须重写对象的hashCode()和equals()方法。

package com.itchinajie.d4_collection_set;import java.util.Objects;public class Student implements Comparable<Student>{private String name;private int age;private double height;
//方式一:让自定义的类(如学生类)实现Comparable接口,重写里面的compareTo方法来指定比较规则。@Overridepublic int compareTo(Student o) {//约定1:  如果左边的对象 大于 右边对象 请您返回正整数//约定2:  如果左边的对象 小于 右边对象 请您返回负整数//约定3:  如果左边的对象 等于 右边对象 请您返回0//按照年龄升序排序
//        if (this.age > o.age) {
//            return 1;
//        }else if (this.age < o.age){
//            return -1;
//        }
//        return 0;//return this.age - o.age;//升序return o.age - this.age;//降序}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public double getHeight() {return height;}public void setHeight(double height) {this.height = height;}public Student() {}public Student(String name, int age, double height) {this.name = name;this.age = age;this.height = height;}//容一样就只要两个对象内返回true@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return age == student.age && Double.compare(height, student.height) == 0 && Objects.equals(name, student.name);}//只要两个对象内容一样,返回的哈希值就是一样的。@Overridepublic int hashCode() {return Objects.hash(name, age, height);}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", height=" + height +'}';}
}package com.itchinajie.d4_collection_set;import java.util.HashSet;
import java.util.Set;public class SetTest3 {public static void main(String[] args) {Set<Student> students = new HashSet<>();Student s1 = new Student("至尊宝", 28, 169.6);Student s2 = new Student("蜘蛛精", 23, 169.6);Student s3 = new Student("蜘蛛精", 23, 169.6);System.out.println(s2.hashCode());System.out.println(s3.hashCode());Student s4 = new Student("牛魔王", 48, 169.6);students.add(s1);students.add(s2);students.add(s3);students.add(s4);System.out.println(students);}
}

LinkedHashSet

特点:有序、不重复、无索引。

底层原理

TreeSet

特点:不重复、无索引、可排序(默认升序排序,按照元素的大小,由小到大排序。

底层是基于红黑树实现的排序。

package com.itchinajie.d4_collection_set;import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;/*
* 目标:掌握TreeSet集合的使用
* */
public class SetTest4 {public static void main(String[] args) {Set<Integer> set1 = new TreeSet<>();set1.add(6);set1.add(5);set1.add(5);set1.add(7);System.out.println(set1);//方式一:让自定义的类(如学生类)实现Comparable接口,重写里面的compareTo方法来指定比较规则。//方式二:通过调用TreeSet集合有参数构造器,可以设置Comparator对像(比较器对象,用于指定比较规则)。// new 一个TreeSet的比较器对象的有参构造器,生成一个比较器对象,然后重写对象的匿名内部类//day04_oop -> src -> com.itchinajie -> d5_arrays 中讲过自定义排序规则//TreeSet就近选择自己自带的比较器对象进行排序Set<Student> students = new TreeSet<>(( o1,  o2) -> Double.compare(o1.getHeight(), o2.getHeight()));students.add(new Student("蜘蛛精",23,169.7));students.add(new Student("紫霞",22,169.8));students.add(new Student("至尊宝",26,165.5));students.add(new Student("牛魔王",22,183.5));System.out.println(students);}
}

自定义排序规则

小结

注意:集合的并发修改异常

package com.itchinajie.d5_collection_exception;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class collection_exception {public static void main(String[] args) {//需求:找出集合中全部带“李”的名字,并从集合中删除。List<String>  list = new ArrayList<>();list.add("王麻子");list.add("小李子");list.add("李爱花");list.add("张全蛋");list.add("晓李");list.add("李玉刚");System.out.println(list);//[王麻子,小李子,李爱花,张全蛋,晓李,李玉刚]//System.out.println("--------------------------------------");//需求:找出集合中全部带“李"的名字,并从集合中删除。
//        Iterator<String>it = list.iterator();
//        while (it.hasNext()){
//            String name = it.next();
//            if(name.contains("李")){
//                list.remove(name);
//            }
//        }
//        System.out.println(list);//报错//System.out.println("--------------------------------------");//使用for循环遍历集合并删除集合中带李字的名字//[王麻子,小李子,李爱花,张全蛋,晓李,李玉刚]
//        for (int i=0;i<list.size();i++){
//            String name = list.get(i);
//            if(name.contains("李")){
//                list.remove(name);
//            }
//        }
//        System.out.println(list);//出bug,需要在他的基础上加个i--//System.out.println("--------------------------------------");//怎么解决呢?//使用for循环遍历集合并刷除集合中带李字的名字//[王麻子,小李子,李爱花,张全蛋,晓李,李玉刚]//i
//        for (int i = 0;i<list.size();i++){
//            String name = list.get(i);
//            if(name.contains("李")) {
//                list.remove(name);
//                i--;
//            }
//        }
//        System.out.println(list);//加个i--也可以//倒着删除也可以System.out.println("--------------------------------------");//用迭代器正常删除的方式需求:找出集合中全部带“李”的名字,并从集合中删除。Iterator<String> it = list.iterator();while (it.hasNext()) {String name = it.next();if (name.contains("李")) {//List.remove(name);//并发修改异常的错误。it.remove();//删除迭代器当前遍历到的数据,每删除一个数据后,相当于也在底层做了i--}}System.out.println(list);//System.out.println("--------------------------------------");//使用增强for循环遍历集合并删除数据,没有办法解决bug的//由于增强for循环遍历集合就是迭代器遍历集合的简化写法,因此,使用增强fo循环遍历集合,又在同时删//除集合中的数据时,程序也会出现并发修改异常的错误
//        for (String name : list){
//            if(name.contains("")){
//                list.remove(name);
//            }
//        }
//        System.out.println(list);//System.out.println("--------------------------------------");//使用lambda表达式也不行
//        list.forEach(name ->{
//            if(name.contains("李")){
//            list.remove(name);
//            }
//        });
//        System.out.println(list);}
}

(本章图片均来自于黑马程序员视频)

http://www.lryc.cn/news/424607.html

相关文章:

  • Qt如何调用接口
  • Android14之解决编译libaaudio.so报错问题(二百二十七)
  • 【专题】2024年7月人工智能AI行业报告合集汇总PDF分享(附原数据表)
  • 干货分享|如何使用Stable Diffusion打造会说话的数字人?
  • OrangePi AIpro学习4 —— 昇腾AI模型推理 C++版
  • vue js 多组件异步请求解决方案
  • 【Android】不同系统版本获取设备MAC地址
  • 残差网络--NLP上的应用
  • 1章4节:数据可视化, R 语言的静态绘图和 Shiny 的交互可视化演示(更新2024/08/14)
  • 浅谈个人用户如何玩转HTTP代理
  • 动手研发实时口译系统
  • C#(asp.net)电商后台管理系统-计算机毕业设计源码70015
  • Unity 中创建动画的教程
  • 2024年最全渗透测试学习指南,小白也能轻松hold住!零基础到精通,看完这篇就够了!
  • 有道云docx转换markdown,导入hugo发布到github page,多平台发布适配
  • 如何理解:进程控制
  • 工业互联网边缘计算实训室解决方案
  • Android全面解析之Context机制(一) :初识Android context
  • 气象百科——气象监测站的介绍
  • 学懂C++(三十):高级教程——深入解析 C++ Windows API 的多线程支持
  • 苹果笔记本电脑可以玩steam游戏吗 MacBook支持玩steam游戏吗 在Steam上玩黑神话悟空3A大作 苹果Mac怎么下载steam
  • 海康摄像头(测温型)桌面客户端开发分享
  • 骑行耳机哪个品牌性价比高?精选五大畅销骑行耳机推荐!
  • libcurl8.9.1 上传json
  • 什么是暗水印?企业暗水印如何实施?企业保护利器
  • Qt 系统相关 - 文件
  • Android Toast居中显示方法二
  • Vue启动时报异常 ‘error:03000086:digital envelope routines::initialization error‘
  • C#委托—马工教你轻松玩转委托
  • 当下最强的 AI art 生成模型 Stable Diffusion 最全面介绍