【愚公系列】2023年10月 Java教学课程 046-集合对象Collection

2023-10-28 01:20

本文主要是介绍【愚公系列】2023年10月 Java教学课程 046-集合对象Collection,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

🏆 作者简介,愚公搬代码
🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,阿里云专家博主,腾讯云优秀博主,掘金优秀博主,51CTO博客专家等。
🏆《近期荣誉》:2022年CSDN博客之星TOP2,2022年华为云十佳博主等。
🏆《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。
🏆🎉欢迎 👍点赞✍评论⭐收藏

文章目录

  • 🚀一、Collection集合
    • 🔎1.集合概述
    • 🔎2.Collection集合的体系特点
    • 🔎3.Collection集合常用API
    • 🔎4.Collection集合的遍历
    • 🔎5.Collection集合存储自定义类型的对象
  • 🚀二、Collection集合补充知识
    • 🔎1.Collection体系的特点、使用场景总结
    • 🔎2.Collections
      • 🦋2.1 概念
      • 🦋2.2 Collections常用的API
      • 🦋2.3 自定义排序
    • 🔎3.集合的嵌套
    • 🔎4.综合案例
  • 🚀感谢:给读者的一封信


🚀一、Collection集合

🔎1.集合概述

Java中数组和集合都是用来存储一组元素的数据结构,但是它们有以下区别:

  1. 数据类型不同:数组可以存储基本数据类型和对象类型,而集合只能存储对象类型。

  2. 大小可变性:数组的大小一旦确定就不可改变,而集合的大小是可变的。

  3. 存储方式不同:数组在内存中是一段连续的地址空间,而集合则是使用链表或树等数据结构存储。

  4. 支持的操作不同:对于数组,只能使用下标访问元素,而集合可以使用迭代器或foreach语句来访问元素。

  5. 集合提供了更多的功能:集合可以提供更多的功能,比如添加、删除、查找、排序等,而数组只有基本的访问和修改操作。

数组和集合都有各自的优缺点,需要根据不同的需求来选择使用哪种数据结构。

以下是Collection的相关案例:

/**目标:明确Collection集合体系的特点*/
public class CollectionDemo1 {public static void main(String[] args) {// ArrayList: 有序 可重复 有索引// HashSet:   无序 不重复  无索引Collection list = new HashSet(); // 多态。list.add("Java");list.add("Java");list.add("Mybatis");list.add(23);list.add(23);list.add(false);list.add(false);System.out.println(list);System.out.println("-----------------------------");Collection<String> list1 = new HashSet<>(); // 多态。list1.add("Java");list1.add("Java");list1.add("Mybatis");}
}

🔎2.Collection集合的体系特点

Java中的集合类体系结构是一个由多个接口和类组成的层次结构,包括以下核心接口和类:

  1. Collection接口:是所有集合类的根接口,提供了基本的集合操作,如添加、删除、遍历等。

  2. List接口:继承自Collection接口,提供了有序、可重复的集合操作,如查找、插入、替换等。

  3. Set接口:继承自Collection接口,提供了无序、不可重复的集合操作,如查找、添加、删除等。

  4. Map接口:不属于Collection接口的一部分,提供了键值对的映射操作,可以通过键快速查找对应的值。

以上接口都有多个实现类,其中常见的有:

  1. ArrayList类:实现了List接口,基于数组实现,支持动态扩容。

  2. LinkedList类:实现了List接口,基于双向链表实现,支持高效的插入和删除操作。

  3. HashSet类:实现了Set接口,基于哈希表实现,支持快速的查找、添加和删除操作。

  4. TreeSet类:实现了SortedSet接口,基于红黑树实现,提供了有序的集合操作。

  5. HashMap类:实现了Map接口,基于哈希表实现,支持快速的查找、添加和删除操作。

  6. TreeMap类:实现了SortedMap接口,基于红黑树实现,提供了有序的键值对操作。

除了以上的核心接口和类,Java还提供了一些辅助类,如迭代器(Iterator)、枚举器(Enumeration)、比较器(Comparator)等,用于对集合进行更加详细的操作和控制。

在这里插入图片描述

🔎3.Collection集合常用API

  • Collection集合概述

    • 是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素
    • JDK 不提供此接口的任何直接实现.它提供更具体的子接口(如Set和List)实现
  • 创建Collection集合的对象

    • 多态的方式
    • 具体的实现类ArrayList
  • Collection集合常用方法

    方法名说明
    boolean add(E e)添加元素
    boolean remove(Object o)从集合中移除指定的元素
    boolean removeIf(Object o)根据条件进行移除
    void clear()清空集合中的元素
    boolean contains(Object o)判断集合中是否存在指定的元素
    boolean isEmpty()判断集合是否为空
    int size()集合的长度,也就是集合中元素的个数

以下是Collection的API相关案例:

/**目标:Collection集合的常用API.Collection是集合的祖宗类,它的功能是全部集合都可以继承使用的,所以要学习它。Collection API如下:- public boolean add(E e):  把给定的对象添加到当前集合中 。- public void clear() :清空集合中所有的元素。- public boolean remove(E e): 把给定的对象在当前集合中删除。- public boolean contains(Object obj): 判断当前集合中是否包含给定的对象。- public boolean isEmpty(): 判断当前集合是否为空。- public int size(): 返回集合中元素的个数。- public Object[] toArray(): 把集合中的元素,存储到数组中。小结:记住以上API。*/
public class CollectionDemo {public static void main(String[] args) {// 0,创建一个集合对象来学习Collection<String> list = new ArrayList<>();// 1.添加元素, 添加成功返回true。list.add("Java");list.add("Java");list.add("愚公");System.out.println(list.add("愚公"));list.add("MySQL");System.out.println(list);// 2.清空集合的元素。//list.clear();//System.out.println(list);// 3.判断集合是否为空 是空返回true,反之。System.out.println(list.isEmpty());// 4.获取集合的大小。System.out.println(list.size());// 5.判断集合中是否包含某个元素。System.out.println(list.contains("Java")); // trueSystem.out.println(list.contains("java")); // false// 6.删除某个元素:如果有多个重复元素默认删除前面的第一个!System.out.println(list.remove("Java"));System.out.println(list.remove("Java1"));System.out.println(list);// 7.把集合转换成数组  [HTML, HTML, MySQL, Java, 黑马]Object[] arr = list.toArray();System.out.println(Arrays.toString(arr));System.out.println("---------拓展---------");String[] arr1 = list.toArray( s -> new String[s]);System.out.println(Arrays.toString(arr1));}
}

🔎4.Collection集合的遍历

在Java中,可以使用以下三种方法来遍历Collection集合:

1.迭代器(Iterator):使用迭代器可以遍历Collection集合中的所有元素。

public static void main(String[] args) {Collection<String> lists = new ArrayList<>();lists.add("赵敏");lists.add("小昭");lists.add("素素");lists.add("灭绝");System.out.println(lists);// [赵敏, 小昭, 素素, 灭绝]// 1、得到当前集合对象的迭代器对象Iterator<String> it = lists.iterator();
//        String e1 = it.next();
//        String e2 = it.next();
//        String e3 = it.next();
//        String e4 = it.next();
//
//        System.out.println(e1);
//        System.out.println(e2);
//        System.out.println(e3);
//        System.out.println(e4);//        String e5 = it.next(); // 这时候出现bug,元素已经取完了
//        System.out.println(e5);// 2、使用循环遍历元素。while (it.hasNext()) {String ele = it.next();System.out.println(ele);}}

2.foreach/增强for循环:使用foreach/增强for循环可以遍历Collection集合中的所有元素。

public static void main(String[] args) {Collection<String> lists = new ArrayList<>();lists.add("赵敏");lists.add("小昭");lists.add("殷素素");lists.add("周芷若");System.out.println(lists);// [赵敏, 小昭, 殷素素, 周芷若]for (String ele : lists) {System.out.println(ele);if("殷素素".equals(ele)){ele = "素素";}}System.out.println(lists);System.out.println("------------------");double[] scores = {100, 99.5 , 59.5};for (double score : scores) {System.out.println(score);}}

3.lambda表达式:使用lambda表达式可以遍历Collection集合中的所有元素。

public static void main(String[] args) {Collection<String> lists = new ArrayList<>();lists.add("赵敏");lists.add("小昭");lists.add("殷素素");lists.add("周芷若");System.out.println(lists);// [赵敏, 小昭, 殷素素, 周芷若]//                    s//        lists.forEach(new Consumer<String>() {
//            @Override
//            public void accept(String s) {
//                System.out.println(s);
//            }
//        });lists.forEach(s -> {System.out.println(s);});lists.forEach( s -> System.out.println(s));}

需要注意的是,每种遍历方式的具体适用场景不同,应根据具体情况选择合适的方式。同时,在遍历过程中不要修改集合中的元素,否则可能会导致ConcurrentModificationException异常。

🔎5.Collection集合存储自定义类型的对象

Java中Collection集合可以存储自定义类型的对象,但需要保证该自定义类型实现了equals()和hashCode()方法。

假设有一个自定义类型Person:

public class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public int getAge() {return age;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Person person = (Person) o;return age == person.age &&Objects.equals(name, person.name);}@Overridepublic int hashCode() {return Objects.hash(name, age);}
}

可以通过以下方式创建一个存储Person对象的List集合:

List<Person> personList = new ArrayList<>();
personList.add(new Person("Tom", 20));
personList.add(new Person("Mary", 25));

同样的,也可以使用其他类型的Collection集合来存储自定义类型的对象,如:

Set<Person> personSet = new HashSet<>();
personSet.add(new Person("Tom", 20));
personSet.add(new Person("Mary", 25));Map<String, Person> personMap = new HashMap<>();
personMap.put("Tom", new Person("Tom", 20));
personMap.put("Mary", new Person("Mary", 25));

🚀二、Collection集合补充知识

🔎1.Collection体系的特点、使用场景总结

1、如果希望元素可以重复,又有索引,索引查询要快

用ArrayList集合,基于数组的。(用的最多)

2、如果希望元素可以重复,又有索引,增删首尾操作快

用LinkedList集合,基于链表的。

3、如果希望增删改查都快,但是元素不重复、无序、无索引

用HashSet集合,基于哈希表的。

4、如果希望增删改查都快,但是元素不重复、有序、无索引

用LinkedHashSet集合,基于哈希表和双链表。

5、如果要对对象进行排序

用TreeSet集合,基于红黑树。后续也可以用List集合实现排序。

🔎2.Collections

🦋2.1 概念

Java中的Collections是一个类集框架,提供了一系列的算法和数据结构,包括List、Set、Map等。它提供了许多可以对集合进行操作的静态方法,包括排序、搜索、转换等。同时,Collections也提供了一些线程安全的集合实现,如ConcurrentHashMap、ConcurrentSkipListMap等。它是Java中最常用的集合类之一,可以让开发者更方便地对集合进行增删改查、排序、复制等操作。

🦋2.2 Collections常用的API

下面是一些常用的API及使用示例:

  1. addAll(Collection<? super T> c, T… elements):将指定元素添加到集合中。
List<String> list = new ArrayList<>();
Collections.addAll(list, "a", "b", "c");
  1. sort(List list, Comparator<? super T> c):对List进行排序。
List<Integer> list = new ArrayList<>(Arrays.asList(3, 1, 2));
Collections.sort(list);
  1. reverse(List<?> list):将List中的元素翻转。
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
Collections.reverse(list);
  1. shuffle(List<?> list):将List中的元素随机排序。
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
Collections.shuffle(list);
  1. binarySearch(List<? extends Comparable<? super T>> list, T key):二分查找指定元素在List中的位置。
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
int index = Collections.binarySearch(list, 3);
  1. max(Collection<? extends T> coll):返回集合中最大的元素。
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
int max = Collections.max(list);
  1. min(Collection<? extends T> coll):返回集合中最小的元素。
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
int min = Collections.min(list);
  1. frequency(Collection<?> c, Object o):返回指定元素在集合中出现的次数。
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 3, 3));
int frequency = Collections.frequency(list, 3);
  1. replaceAll(List list, T oldVal, T newVal):将List中的所有旧值替换为新值。
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c", "a"));
Collections.replaceAll(list, "a", "d");
  1. singleton(T o):返回包含指定元素的只读集合。
List<String> list = Collections.singletonList("a");

🦋2.3 自定义排序

public static void main(String[] args) {// 1、方式一:对学生对象进行排序:学生类自己实现Comparable接口,指定规则List<Student> list = new ArrayList<>();Student s1 = new Student("紫霞仙子",23,'女');Student s2 = new Student("蜘蛛精",35,'女');Student s3 = new Student("白骨精",20,'女');Student s4 = new Student("铁扇公主",18,'女');Collections.addAll(list, s1, s2, s3, s4);System.out.println(list);// Collections.sort(list); // 方式一:排序// 方式二:自带比较器对象Collections.sort(list, new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {return o2.getAge() - o1.getAge(); // 降序}});System.out.println(list);
}

🔎3.集合的嵌套

一个集合对象中可以嵌套另一个集合对象,我们来看一个示例,实现一个学生信息的管理系统,每个学生信息包含姓名、年龄、性别、课程和成绩等属性,每个学生可以有多个课程以及每个课程对应一个成绩。

首先,我们定义一个学生类:

public class Student {private String name;private int age;private String gender;private Map<String, Double> courses; // 课程和成绩映射public Student(String name, int age, String gender) {this.name = name;this.age = age;this.gender = gender;this.courses = new HashMap<>();}public void addCourse(String course, double score) {this.courses.put(course, score);}public String getName() {return name;}public int getAge() {return age;}public String getGender() {return gender;}public Map<String, Double> getCourses() {return courses;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", gender='" + gender + '\'' +", courses=" + courses +'}';}
}

其中,课程和成绩使用Map集合表示。

然后,我们再定义一个班级类,一个班级可以有多个学生:

public class Class {private String name;private List<Student> students;public Class(String name) {this.name = name;this.students = new ArrayList<>();}public void addStudent(Student student) {this.students.add(student);}public String getName() {return name;}public List<Student> getStudents() {return students;}@Overridepublic String toString() {return "Class{" +"name='" + name + '\'' +", students=" + students +'}';}
}

最后,我们来测试一下:

public class Test {public static void main(String[] args) {Student s1 = new Student("Tom", 20, "male");s1.addCourse("Math", 80.0);s1.addCourse("English", 90.0);Student s2 = new Student("Lily", 19, "female");s2.addCourse("Math", 85.0);s2.addCourse("English", 95.0);Class c1 = new Class("Class 1");c1.addStudent(s1);c1.addStudent(s2);System.out.println(c1);}
}

输出结果:

Class{name='Class 1', students=[Student{name='Tom', age=20, gender='male', courses={Math=80.0, English=90.0}}, Student{name='Lily', age=19, gender='female', courses={Math=85.0, English=95.0}}]}

我们可以看到,班级对象中嵌套了多个学生对象,每个学生对象中有多个课程以及对应的成绩。这就是一个集合对象中嵌套另一个集合对象的案例。

🔎4.综合案例

public class Card {private String size; // 点数private String color; // 花色// 面向对象编程:yydsprivate int index;public Card(){}public Card(String size, String color, int index) {this.size = size;this.color = color;this.index = index;}public String getSize() {return size;}public void setSize(String size) {this.size = size;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}public int getIndex() {return index;}public void setIndex(int index) {this.index = index;}@Overridepublic String toString() {return size + color;}
}
/**目标:斗地主游戏的案例开发。业务需求分析:斗地主的做牌, 洗牌, 发牌, 排序(拓展知识), 看牌。业务: 总共有54张牌。点数: "3","4","5","6","7","8","9","10","J","Q","K","A","2"花色: "♠", "♥", "♣", "♦"大小王: "👲" , "🃏"点数分别要组合4种花色,大小王各一张。斗地主:发出51张牌,剩下3张作为底牌。功能:1.做牌:面向对象设计,一张牌是一个对象。2.洗牌。3.定义3个玩家4.发牌。5.排序(拓展,了解,作业)6.看牌*/
public class GameDemo {/**a、定义一个静态的集合用于存储54张牌对象*/public static List<Card> allCards = new ArrayList<>();/**b、做牌*/static {// 1、定义点数:类型确定,个数确定,采用数组记录。String[] sizes = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};// 2、定义花色:类型确定,个数确定,采用数组记录。String[] colors = {"♠", "♥", "♣", "♦"};// 3、组合点数和花色做牌对象int index = 0;for (String size : sizes) {index++; // 记录牌大小for (String color : colors) {// 4、创建一张牌对象封装点数和花色Card c = new Card(size ,color,index);allCards.add(c);}}// 4、存入小大王allCards.add(new Card("", "🃏", ++index));allCards.add(new Card("", "👲", ++index));System.out.println("新牌:" + allCards);}public static void main(String[] args) {// 5、洗牌:打乱List集合的元素顺序:List<Card> allCards...Collections.shuffle(allCards);System.out.println("洗牌后:" + allCards);// 6、发牌:定义三个玩家List<Card> linhuchong = new ArrayList<>();List<Card> jiumozhi = new ArrayList<>();List<Card> renyingying = new ArrayList<>();// 7、开始发出51张牌,剩余3张作为底牌// List<Card> allCards = [4♦, 9♠, A♥, 8♥, K♠, 4♠, A♣, 3♣, 3♦, 9♥,//                        0   1   2   3   4    5   6for (int i = 0; i < allCards.size() - 3; i++) {// 8、得到这张牌对象Card c = allCards.get(i);// 9、判断这张牌发给谁的问题。if(i % 3 == 0){// 请啊冲接牌linhuchong.add(c);}else if(i % 3 == 1){// 请啊鸠接牌jiumozhi.add(c);}else if(i % 3 == 2){// 请盈盈接牌renyingying.add(c);}}// 8、拿到最后三张底牌。List<Card> lastThreeCards = allCards.subList(allCards.size() - 3, allCards.size()); // 51 52 53linhuchong.addAll(lastThreeCards); // 令狐冲抢地主了// 9、对牌进行排序(拓展内容,先自己思考)sortCard(linhuchong);sortCard(jiumozhi);sortCard(renyingying);// 10、输出牌完事System.out.println("底牌:" + lastThreeCards);System.out.println("啊冲:" + linhuchong);System.out.println("啊鸠:" + jiumozhi);System.out.println("盈盈:" + renyingying);}public static void sortCard(List<Card> cards){// cards = [J♦, A♣, 2♦, Q♣, 👲, 8♥, 3♠, 3♥, ...
//        Collections.sort(cards, new Comparator<Card>() {
//            @Override
//            public int compare(Card o1, Card o2) {
//                // 指定比较规则: o1 = J♦   o2 = 👲
//                // return o1.getIndex() - o2.getIndex(); // 升序
//                return o2.getIndex() - o1.getIndex(); // 降序
//            }
//        });Collections.sort(cards, ( o1,  o2) -> o2.getIndex() - o1.getIndex());}}

🚀感谢:给读者的一封信

亲爱的读者,

我在这篇文章中投入了大量的心血和时间,希望为您提供有价值的内容。这篇文章包含了深入的研究和个人经验,我相信这些信息对您非常有帮助。

如果您觉得这篇文章对您有所帮助,我诚恳地请求您考虑赞赏1元钱的支持。这个金额不会对您的财务状况造成负担,但它会对我继续创作高质量的内容产生积极的影响。

我之所以写这篇文章,是因为我热爱分享有用的知识和见解。您的支持将帮助我继续这个使命,也鼓励我花更多的时间和精力创作更多有价值的内容。

如果您愿意支持我的创作,请扫描下面二维码,您的支持将不胜感激。同时,如果您有任何反馈或建议,也欢迎与我分享。

在这里插入图片描述

再次感谢您的阅读和支持!

最诚挚的问候, “愚公搬代码”

这篇关于【愚公系列】2023年10月 Java教学课程 046-集合对象Collection的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/289727

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl