【Java】集合与数组关系,认识集合,使用集合,集合使用判断情况

简介: 【Java】集合与数组关系,认识集合,使用集合,集合使用判断情况

目标①:了解集合和数组的区别


在Java中,集合位于java.util包下。


从定义看区别:


集合定义:集合是一个不定量存放对象的引用的容器。


数组定义:数组是一个定量存放“相同类型”变量的容器。


那么从定义的角度上看,数组和集合的区别:


  • 数组和集合都是Java中的容器
  • 数组的长度是固定的,集合的长度是可变的(数组是静态的,一个数组实例具有固定的大小,一旦创建了就无法改变容量了。而集合是可以动态扩展容量,可以根据需要动态改变大小,集合提供更多的成员方法,能满足更多的需求)
  • 数组只能存储相同数据类型的数据,这里的数据类型可以是基本数据类型,也可以是引用类型
  • 集合可以存储不同数据类型的对象的引用(但一般情况下,我们会使用泛型来约定只使用1种数据类型),但不能存储基本数据类型


从存储结构看联系


集合存储:(集合以接口和类的形式存在,不同的实现有着不同的存储结构)看下图


963e1ec5548b1b5a29e845ed000a62bd_406bc9e5e8b80acc6910d25c9b0cbb1a.png


注:粉色代表接口,绿色代表实现类;

数组、哈希表:顺序存储

哈希表、红黑树:链式存储


数组存储:链式存储


那么,

  • 数组是java语言中内置的数据类型,是线性排列的,执行效率或者类型检查都是最快的。
  • 集合以接口和类的形式存在,具有封装,继承和多态等类的特性,通过简单的方法和属性调用即可实现各种复杂的操作,大大提高软件的开发效率。


目标②:认识集合(自上而下)


Map和Collection 接口


195e41dab95c87f0b1e0cf08a0afa8c4_2af8ed9e29a7d0bd0950b62f6e927b41.png



左右两个集合:Collection、Map 都是接口(不能构建实例对象) 各自都有自己的实现类,以迭代器Iterator将其联系起来

经常使用的方法:

d55f4ef6c8f4351b91a362d0849d75cf_97b96aab5b5b6937e2be8f89d7002db1.png

de5726e2617343dab05b9495e854b48a_076f32af0b91676fccf95e4d9b9fcc72.png


构建方法:

Collection/Map 对象 = new 实现类;


注意:Map 没有继承 Collection 接口, Map 提供 key 到 value 的映射,你可以通过“key”查找“value”。一个 Map 中不能包含相同的 key ,每个 key 只能映射一个 value

ps:Map集合必须保证保证key唯一,作为key,必须重写hashCode方法和equals方法,以保证key唯一。


List和Set 接口以及它的实现类


5b893797edbd0e42e3c26eee6d10072a_f598b2ceaeee9d0b3feca9efe04e5432.png


注:绿色为实现类(内包含Collection的基本方法)。据结构为数组的特点:查询快、增删慢。结构为数组链表特点:查询慢、增删快。

List 接口:

它利用索引(index),定义了一些特殊方法:

get(int index,E e) 获取指定位置的元素;remove(int index)移除指定位置的元素;

add(int index,E e) 将元素添加到指定位置;set(int index,E e) 用元素替换指定位置的元素;

Set接口:

特点:元素不可重复;

元素无序,存储及取出时顺序不一致;

没有索引,因此不能使用普通For循环遍历;

Set与Collection 接口中的方法基本一致,没有进行功能上的扩充;


Map接口以及实现方法


053e33035a054c94f4febfc7e84e90ec_80d8ea2ce82cfd8840a767626627c2cd.png


特点:元素包含两个值(key,value)即键值对, key不允许重复,value可以重复, key与value是一一对应的。元素无序;

Map接口是双列集合的最顶层接口,定义了一些通用的方法。

put(key , value) 添加元素; remove(key) 删除key对应元素;

containsKey(key) 判断是否存在key对应元素;get(key) 获取key对应元素;

KeySet() 获取所有的key,存到Set集合中;entrySet() 获取所有的元素,存到Set集合中;

ps:Map集合必须保证保证key唯一,作为key,必须重写hashCode方法和equals方法,以保证key唯一。


使用集合进行操作(此内容来自csdn:java集合基础习题代码部分改动)


一.生成10个1到20之间的不重复的随机数


分析过程:


  1. 需要生成随机数,那么需要Random类
  2. 需要存储10个不能重复的数,需要HashSet集合(当前TreeSet还没学习到)
  3. 判断,当HashSet的Size小于10就往里存储随机数,等于就停止添加存储元素
  4. 通过Random的nextInt()方法获取随机数并加入到HashSet里
  5. 遍历HashSet,打印出10个随机数


package hashset;
import java.util.HashSet;
import java.util.Random;
public class Test1_HashSet {
  public static void main(String[] args) {
    //1.创建Random对象
    Random r = new Random();
    //2.创建HashSet对象
    HashSet<Integer> hs = new HashSet<>();  //注意是包装类不是int
    //3.判断并添加元素
    while(hs.size()< 10) {
      //4.通过Random中随机方法nextInt()获取1到20范围内随机数
      hs.add(r.nextInt(20) + 1);    //如果不加1,随机范围是0到19
    }
    //5.遍历HashSet
    for (Integer integer : hs) {
      System.out.println(integer);
    }
  }


二、从键盘获取一行输入字符串,要求去除重复字符。


分析过程:


  1. 需要使用Scanner类
  2. 输入的是一行字符串,需要转换成字符数组
  3. 创建HashSet集合对象(利用HashSet无法储存相同元素的特性达到去除重复字符的目的)
  4. 字符数组遍历元素,并添加进入HashSet集合
  5. 变量集合元素


package hashset;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
import javax.swing.plaf.synth.SynthSpinnerUI;
public class Test2_HashSet {
  public static void main(String[] args) {
    //1.创建键盘输入对象
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入一行字符串:");
    String line = sc.nextLine();
    //2.字符串转换成字符数组
    char[] c = line.toCharArray();
    //3.字符数组转换成集合对象,创建HashSet
    HashSet<Character> hs = new HashSet<>();
    //4.遍历数组,元素依次添加进集合
    for (int i = 0; i < c.length; i++) {
      hs.add(c[i]);
    }
    //5.遍历HashSet集合
    for (Character character : hs) {
      System.out.println(character);
    }
  }
}


三、假设顺序列表ArrayList中存储的元素是整型数字1~5,遍历每个元素,将每个元素顺序输出。(list集合遍历方法总结)


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
//假设顺序列表ArrayList中存储的元素是整型数字1~5,遍历每个元素,将每个元素顺序输出。 [必做题]
public class MyArray {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<Integer>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        Iterator<Integer> it = list.iterator();
//      迭代器遍历
        while(it.hasNext()){
            System.out.println(it.next());
        }
//      for循环遍历
        for(int i = 0;i<list.size();i++){
            System.out.println(list.get(i));
        }
//      增强for循环
        for(Integer i :list){
            System.out.println(i);
        }
    }


四、在一个列表中存储以下元素:apple,grape,banana,pear


• 3.1 返回集合中的最大的和最小的元素

• 3.2 将集合进行排序,并将排序后的结果打印在控制台上

package txtt;
import java.util.*;
//3、在一个列表中存储以下元素:apple,grape,banana,pear 
//• 3.1 返回集合中的最大的和最小的元素 
//• 3.2 将集合进行排序,并将排序后的结果打印在控制台上 
public class test4 {
  public static void main(String[] args) {
      HashSet<String> set = new HashSet<>();    
      set.add("apple");
      set.add("grape");
      set.add("banana");
      set.add("pear");
      String max = Collections.max(set);
      System.out.println(max);
      String min = Collections.min(set);
      System.out.println(min);
      for(Object o:set) {
        System.out.print(o+" ");
      }
    }
  }


五、编写程序,获取命令行参数中的字符串列表,输出其中重复的字符、不重复的字符以及消除重复以后的字符列表。


ublic static void main(String[] args) {
    String str = "abcdeafblmbnopawc";
    System.out.println("原字符串:"+str);
    Set<Character> set1 = new HashSet<Character>();//消除重复后的字符
    Set<Character> set2 = new HashSet<Character>();//重复的字符
    Set<Character> set3 = new HashSet<Character>();//不重复的字符
    //把字符串转为字符数组
    char[] cs = str.toCharArray();
    for (char c : cs) {
        boolean b = set1.add(c);
        if(!b){
            set2.add(c);
        }
    }
    //把消除重复后的字符赋给set3
    set3.addAll(set1);
    //把消除重复后的字符 - 重复的字符 = 不重复的字符
    set3.removeAll(set2);
    System.out.println("====消除重复后的字符========");
    for (char c : set1) {
        System.out.print(c+" ");
    }
    System.out.println("\n====重复的字符========");
    for (char c : set2) {
        System.out.print(c+" ");
    }
    System.out.println("\n====不重复的字符========");
    for (char c : set3) {
        System.out.print(c+" ");
    }
}


六、使用Scanner从控制台读取一个字符串,统计字符串中每个字符出现的次数,要求使用学习过的知识完成以上要求


实现思路根据Set、List、Map集合的特性完成。

public static void main(String[] args) {
    String str = "abcdeblmbac";
    System.out.println("原字符串:"+str);
    Map<Character,Integer> map = new HashMap<Character,Integer>();
    char[] cs = str.toCharArray();
    for (char c : cs) {
        if(map.containsKey(c)){
            Integer value = map.get(c);
            value++;
            map.put(c, value);
        }else{
            map.put(c, 1);
        }   
    }
    //遍历map
    Set<Character> set = map.keySet();
    for (Character c : set) {
        System.out.println(c+"出现了"+map.get(c)+"次");
    }
}


七、 写一个Student类, 包含属性id[1-30), grade[1-6], score[0-100], 所有属性都是随机生成


// 创建一个Set集合, 保存20个对象, 如果两个对象的id是一样的,则不允许添加.

// 使用迭代器遍历集合,打印输出对象的信息, 并找出分数最高的同学和分数最低的同学, 最后打印输出最高分和最低分同学信息.

package txtt;
import java.util.*;
public class Test13 {
  public static void main(String[] args) {
    Set<Student> set = new TreeSet<Student>();
    for (; set.size() != 20;) {
      int id = (int) (Math.random() * 29 + 1);
      int grade = (int) (Math.random() * 6 + 1);
      double score = (int) (Math.random() * 1001) / 10.0;
      set.add(new Student(id, grade, score));
    }
    for (Student student : set) {
      System.out.println(student);
    }
    System.out.println("---------------------------");
    Object[] array =  set.toArray();
    System.out.println("max:"+array[0]);
    System.out.println("min:"+array[array.length-1]);
}
}
class Student implements Comparable<Student> {
  private int id;
  private int grade;
  private double score;
  public Student() {
  }
  public Student(int id, int grade, double score) {
    super();
    this.id = id;
    this.grade = grade;
    this.score = score;
  }
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public int getGrade() {
    return grade;
  }
  public void setGrade(int grade) {
    this.grade = grade;
  }
  public double getScore() {
    return score;
  }
  public void setScore(double score) {
    this.score = score;
  }
  @Override
  public String toString() {
    return "Student [id=" + id + ", grade=" + grade + ", score=" + score + "]";
  }
  public int compareTo(Student o) {
    return (int) (this.score - o.score);
  }
}


附:选择


image.png



部分图来自网络,习题来自https://blog.csdn.net/Andrelia20171760/article/details/85268422



相关文章
|
15天前
|
存储 缓存 安全
Java 集合江湖:底层数据结构的大揭秘!
小米是一位热爱技术分享的程序员,本文详细解析了Java面试中常见的List、Set、Map的区别。不仅介绍了它们的基本特性和实现类,还深入探讨了各自的使用场景和面试技巧,帮助读者更好地理解和应对相关问题。
36 5
|
28天前
|
存储 缓存 安全
Java 集合框架优化:从基础到高级应用
《Java集合框架优化:从基础到高级应用》深入解析Java集合框架的核心原理与优化技巧,涵盖列表、集合、映射等常用数据结构,结合实际案例,指导开发者高效使用和优化Java集合。
40 4
|
1月前
|
Java
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式。本文介绍了 Streams 的基本概念和使用方法,包括创建 Streams、中间操作和终端操作,并通过多个案例详细解析了过滤、映射、归并、排序、分组和并行处理等操作,帮助读者更好地理解和掌握这一重要特性。
35 2
|
1月前
|
存储 Java
判断一个元素是否在 Java 中的 Set 集合中
【10月更文挑战第30天】使用`contains()`方法可以方便快捷地判断一个元素是否在Java中的`Set`集合中,但对于自定义对象,需要注意重写`equals()`方法以确保正确的判断结果,同时根据具体的性能需求选择合适的`Set`实现类。
|
1月前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
1月前
|
存储 Java 开发者
在 Java 中,如何遍历一个 Set 集合?
【10月更文挑战第30天】开发者可以根据具体的需求和代码风格选择合适的遍历方式。增强for循环简洁直观,适用于大多数简单的遍历场景;迭代器则更加灵活,可在遍历过程中进行更多复杂的操作;而Lambda表达式和`forEach`方法则提供了一种更简洁的函数式编程风格的遍历方式。
|
1月前
|
Java 开发者
|
2月前
|
存储 缓存 算法
Java 数组
【10月更文挑战第19天】Java 数组是一种非常实用的数据结构,它为我们提供了一种简单而有效的方式来存储和管理数据。通过合理地使用数组,我们能够提高程序的运行效率和代码的可读性。更加深入地了解和掌握 Java 数组的特性和应用,为我们的编程之旅增添更多的精彩。
37 4
|
2月前
|
存储 缓存 算法
提高 Java 数组性能的方法
【10月更文挑战第19天】深入探讨了提高 Java 数组性能的多种方法。通过合理运用这些策略,我们可以在处理数组时获得更好的性能表现,提升程序的运行效率。
43 2
|
1月前
|
存储 Java 开发者
Java中的集合框架深入解析
【10月更文挑战第32天】本文旨在为读者揭开Java集合框架的神秘面纱,通过深入浅出的方式介绍其内部结构与运作机制。我们将从集合框架的设计哲学出发,探讨其如何影响我们的编程实践,并配以代码示例,展示如何在真实场景中应用这些知识。无论你是Java新手还是资深开发者,这篇文章都将为你提供新的视角和实用技巧。
34 0