七、集合框架,Collection、list、set、map老师说集合学好了走到哪里都不怕

集合框架

1. 数组

对象数组

题目:将全班30位同学的信息,一次录入(增加)到一个对象数组之中,并且输出。

分析:

类:Student(学生类):name,age

​ StudentBiz(学生数组类):Student[] students = new Student[30];

对象数组有自己的不足

  • 数组的长度固定,不可改变
  • 数组无法求出真实有效的数据个数
  • 用数组实现对象的增删改查操作比较发麻烦

2.collection集合

Collection->List/Set

List---->ArrayList/LinkedList

Set---->HashSet/TreeSet

Collection 是一个接口,允许有重复的元素,而另一些不允许。一些cottection是有序的(输入顺序是否和输出顺序一致),而另一些是无序的

  1. 用集合实现对象的额增删改查很方便,直接调用add()方法即可
  2. Collection长度会自动适应不必要人工干预
  3. Collection可以获取到真实的数据个数

collection集合方法

2.1add方法

增加字符串

 // Collection coll = new Collections();//接口不能被实例化
        //add(Object a ):向集合中增加一个元素
        Collection coll = new ArrayList();
        coll.add("a");
        coll.add("b");
        coll.add("c");
        System.out.println(coll);//重写了toString方法.要不然直接打印内存地址
//[a, b, c]

增加数组

   Collection coll = new ArrayList(); 
//增加对象
        Student stu1 = new Student();
        stu1.setName("张三");
        stu1.setAge(23);
        Student stu2 = new Student();
        stu2.setName("李四");
        stu2.setAge(24);
        Student stu3 = new Student();
        stu3.setName("王五");
        stu3.setAge(15);
        coll.add(stu1);
        coll.add(stu2);
        coll.add(stu3);
//重写Student中的toString方法
        System.out.println(coll);
//[张三-23, 李四-24, 王五-15]

2.2clear方法

移除此Collection中的所有元素

 coll.clear();//clear:清楚集合中所有的元素
        System.out.println(coll);

2.3size方法

 //求集合中真实数据的个数:size()
        System.out.println(coll.size());

2.3addAll方法

Collection coll = new ArrayList();
        coll.add("a");
        coll.add("b");
        coll.add("c");
Collection col2 = new ArrayList();
        col2.add("c");
        col2.add("d");
        col2.add("e");
    //addAll:可以将一个集合中的全部元素增加到另一个集合之中
        coll.addAll(col2) ;
        System.out.println(coll);
//a b c c d e

2.4containsAll/contains方法

如果此collection包含指定collection中的所有元素,则返回true

//判断集合是否包含了指定的对象(元素)
boolean flag = coll.contains("a");
System.out.println(flag);
//-------
boolean flag1 = coll.contains(stu1);
System.out.println(flag1);

//containsAll:判断集合是否包含了另一个集合

boolean flag2= coll.containsAll(col2);
System.out.println(flag2);
//true
//true
//true

2.5isEpty方法

如果此collection不包含元素,则返回true

Collection coll = new ArrryList();
boolean flag = coll.isEmpty();
System.out.println(flag);
//true

2.6iterator方法(重点掌握)

  //iterator():迭代器
        System.out.println("col2:"+col2);
        Iterator iter  = col2.iterator();
      // iter.hasNext();//判断集合是否有下一个元素
        while(iter.hasNext()){
   
            //接收类型为Object强制转换成String 
            String reault = (String)iter.next();//取出下一个元素
            System.out.println(reault);

2.7 remove/removeAll方法

//remove:可以删除集合之中指定的对象
col2.remove("b");
System.out.println(col2);
//removeAll:从一个集合之中删除另一个集合中包含的元素
coll.removeAll(col2);

2.8 retinAll方法

  //retainAll:与removeAll是相反操作,从一个集合之中只保留另一个集合的所有元素
Collection col1 = new ArrryList();
        coll.add("a");
        coll.add("b");
        coll.add("c");
Collection col2 = new ArrryList();
        col2.add("a");
        col2.add("c");
System.out.println("col1"+col1);
System.out.println("col2"+col2);
        coll.retainAll(col2);
System.out.println("col1"+col1);
ystem.out.println("col2"+col2);
//abc
//ac

//ac
//ac

2.9toArray方法

  //toArray():将集合转换为数组(Obiect[]);
        Object[] col1Array = coll.toArray();
        System.out.println(col1Array[0]);
        System.out.println(col1Array[1]);

3.List集合方法

-----ArrayList的特有方法

3.1 add()插入到指定位置

  List list1 = new ArrayList();
        list1.add("a");
        list1.add("b");
        list1.add("c");
        System.out.println(list1);
        list1.add("d");
        System.out.println(list1);
//List接口中,有一个重载的add()方法,可以将增加的元素指定到某一个具体的位置
        list1.add(1,"e");
        System.out.println(list1);

3.2 addAll方法插入

List list1 = new ArrayList();
        list1.add("a");
        list1.add("b");
        list1.add("c");
        List list2 = new ArrayList();
        list2.add("1");
        list2.add("2");
//可以将增加的集合元素指定到某一个具体的位置
        list1.addAll(2,list2);
        System.out.println(list1);

3.3 get方法

List list1 = new ArrayList();
        list1.add("a");
        list1.add("b");
//通过get方法获取到集合中的某一个元素(类似于数组的下表)
  Object o = list1.get(1);
        System.out.println(o);
//b

3.4 indexof/lastindexof方法

  List list1 = new ArrayList();
        list1.add("a");
        list1.add("b");
        list1.add("c");
//可以获取到某一个指定对象(元素)在集合之中的位置
        int e = list1.indexOf("b");
        System.out.println(2);
//1
//从后往前找
 int e1 = list1.lastIndexOf("c");
        System.out.println(e1);
//3

3.5 remove方法

 			 list1.remove("a");
        System.out.println(list1);
        list1.remove("e");
        System.out.println(list1);
        //可以删除指定索引位置对象(元素)通过索引删除(重载方法)(因为list集合是有序的)
        list1.remove(1);
        System.out.println(list1);

3.6 set方法

 //将指定位置的元素(对象)修改成新的
        list1.set(3,"中");
        System.out.println(list1);

3.7 sublist方法

 //类似subString(),截取List集合,左闭右开
        List list = list1.subList(2, 4);
        System.out.println(list);

------LinkedList的特有方法

3.8 addList/addFirst方法

 LinkedList list = new LinkedList();
        list.add("hello");
        list.add("world");
        list.addLast("wh");
        list.addFirst("hw");
        System.out.println(list);

-----ArrayList和LinkedList区别

arrayList(动态数组)

优点:每个元素紧密相连,可以通过下表快速取存

缺点:增删改麻烦,覆盖

linkedList(链式)

缺点:查询麻烦

优点:增删改方便

-----Collection、List、Set区别

Collection:存储的数据是 不唯一、无序的对象

List:存储的数据是 不唯一、有序的对象

Set:存储的数据是 唯一、无序的对象

集合 存储数据是否唯一 是否有序
Collection 不唯一 无序
List 不唯一 有序
Set 唯一 无序

唯一:不能重复

有序:不是排序;是输入顺序 是否与 输出顺序一致的。

是否唯一(因为Collection是抽象类所以实现不了,此处用Collection和List对比)

 public static void main(String[] args) {
   
        Collection list = new ArrayList();
        list.add("aa");
        list.add("aa");
        list.add("bb");
        System.out.println(list);
        Collection set = new HashSet();
        set.add("aa");
        set.add("aa");
        set.add("cc");
        System.out.println(set);
    }
//[aa, aa, bb]
//[aa, cc]
//可以看出在HashSet中不能存在重复的值只能是唯一的所以add了两个aa只显示了一个而ArrayList是不唯一的

是否有序

    public static void main(String[] args) {
   
        Collection list = new ArrayList();
        list.add("中国");
        list.add("俄罗斯");
        list.add("美国");
        System.out.println(list);
        Collection set = new HashSet();
        set.add("中国");
        set.add("俄罗斯");
        set.add("美国");
        System.out.println(set);
    }
//[中国, 俄罗斯, 美国]
//[美国, 俄罗斯, 中国]
//可以看出ArrayList是按顺序输出的是有序的,而HashSet是无序的

4.Map集合方法

key:唯一

value:不唯一

返回值
Collection中的类(List、Set) 删除的返回值是boolean
Map中的类 是根据Key删除,返回值是value

4.1 Map常用方法

				HashMap map = new HashMap();
        map.put("s01","张三");//key:学号, value:姓名
        map.put("s02","李四");//key:学号, value:姓名
        map.put("s03","王五");//key:学号, value:姓名
        System.out.println(map);

        Object v = map.get("s01");//根据key找value
        System.out.println(v);

        int size = map.size();
        System.out.println(size);//元素的个数

        boolean s01 = map.containsKey("s01");
        System.out.println(s01);//判断是否包含了指定的key

        //keySet方法将Map转为单值集合
        //转为只包含Key的单值集合
        Set set = map.keySet();//为什么是set不是list?因为map中key是唯一的
        System.out.println(set);

        //转化为只包含value的单值集合
        //values方法转换单值valuse
        Collection values = map.values();
        System.out.println(values);

        map.remove("s01");//删除,通过学号/删除成功返回值,就是删除的value对象,删除没成功不提示
        System.out.println(map);

4.2 如何遍历集合

  • 循环for(普通for(不适用无序的集合),增强for(建议使用增强for))
  • 迭代器
public interface Iterator<E>{
   ...}

4.2.1 List

  1. 循环for
   List list = new ArrayList();
        list.add("aa");
        list.add("bb");
        list.add("cc");
        for (int i = 0; i <list.size() ; i++) {
   
            System.out.println(list.get(i));
        }
  1. 增强for
  List list = new ArrayList();
        list.add("aa");
        list.add("bb");
        list.add("cc");
        for (Object lists:list) {
   
            System.out.println(lists);
        }
  1. 迭代器
 List list = new ArrayList();
        list.add("aa");
        list.add("bb");
        list.add("cc");
      Iterator iterator = list.iterator();
        while(iterator.hasNext()){
   
          Object o = iterator.next();
            System.out.println(o);
        }

4.2.2 Set

  1. 循环for

不能使用for因为Set是无序的没有下标

  1. 增强for
 Set set = new HashSet();
        set.add("AA");
        set.add("BB");
        set.add("CC");
        for (Object sets :set) {
   
            System.out.println(sets);
        }
  1. 迭代器
  Set set = new HashSet();
        set.add("AA");
        set.add("BB");
        set.add("CC");

        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
   
          Object o = iterator.next();
            System.out.println(o);
        }

4.2.3 Map(将双值,转化单值集合)

  1. 循环for

不能使用for因为Set是无序的没有下标

  1. 增强for
   Map map = new HashMap();
        map.put("s01","zs");
        map.put("s02","ls");
        map.put("s03","ww");
        Set set1 = map.keySet();
        for(Object O:set1){
   
            System.out.println("key:"+O);
          //value可以不用迭代器,可以用get方法,通过key找到value
					//Object v = map.get(O);
          // System.out.println("value:"+v);
        }
 //====================================================
        Collection values = map.values();
       for(Object value:values){
   
         System.out.println(value);
       }
  1. 迭代器
   Map map = new HashMap();
        map.put("s01","zs");
        map.put("s02","ls");
        map.put("s03","ww");
        Set set1 = map.keySet();
        Iterator iterator = set1.iterator();
  			 while(iterator.hasNext()){
   
            System.out.println(iterator.next());
        }
        Collection values = map.values();
        Iterator iterator1 = values.iterator();
        while(iterator1.hasNext()){
   
            System.out.println(iterator1.next());
        }
  1. entry遍历
 Map map = new HashMap();
        map.put("s01","zs");
        map.put("s02","ls");
        map.put("s03","ww");
       Set entries = map.entrySet();

       for(Object e :entries){
   
           Map.Entry et = (Map.Entry)e;
           Object k = et.getKey();
           Object v = et.getValue();
           System.out.println("k-"+k);
           System.out.println("v-"+v);
       }

5.泛型

Collection、Map都能用

自从jdk1.5开始的

作用:

  1. 保证数据安全
 List<String> list = new ArrayList<String>();
        list.add("aa");
        list.add(2);//这句话报错,表明只能输入String类型
        for (Object lists:list) {
   
            System.out.println(lists);
        }
  1. 防止类型转换时出错

list.add(默认是Object)、二u过加了Double泛型,则自动编程list.add(double…),返回值类型,会直接返回double类型的数据

简言,以Double泛型为例,入伙不加泛型,则默认操作的是Object类型,如果加了Double泛型,则默认操作的是Double类型。

使用

    //单值
        // List<String> list = new ArrayList<String>();
        List<String> list = new ArrayList<>();   // 和上面的等价/1.7之后提供的类型推断
        list.add("a");
        String s = list.get(0);
        System.out.println(s);

     //双值
        //k(学号) ,v(名次)
        Map<String,Integer> map = new HashMap<>();
        map.put("s01",3);
        map.put("s02",1);
        map.put("s03",2);
        Set<Map.Entry<String, Integer>> entries = map.entrySet();
        for(Map.Entry<String, Integer> o:entries){
   
            System.out.println(o.getKey());
            System.out.println(o.getValue());
        }

   //迭代器也能用泛型方式
        //取key
        Set<String> keys = map.keySet();
        Iterator<String> iterator = keys.iterator();
        while(iterator.hasNext()){
   
            String key = iterator.next();
            Integer value = map.get(key);
            System.out.println(key+"--"+value);
        }

示例:根据人的名字,查询这个人的全部信息

    Map<String,Person> map = new HashMap<>();
        Person per01 = new Person("zs",23,"西安");
        Person per02 = new Person("ls",23,"北京");
        Person per03 = new Person("ww",25,"上海");
        Person per04 = new Person("zl",24,"天津");
        Person per05 = new Person("sq",27,"深圳");

        //key 名字 ,value:人
        map.put("zs",per01);
        map.put("ls",per02);
        map.put("ww",per03);
        map.put("zl",per04);
        map.put("sq",per05);

        System.out.println("请输入人的名字");
        Scanner input = new Scanner(System.in) ;
        String name = input.next();
//map方法简单
         Person person = map.get(name);
        System.out.println(person);
//如果对象不是Null,在打印时会调用toString.如果是null则不会调用toString

//老方法底层

// Set<String> names = map.keySet();
// //在Names中找name
// for(String n:names){
   
// if(n.equals(name)){
   
// Person person = map.get(n);
// System.out.println(person);
// }
// }

集合工具类

集合工具类Collections(集合)

        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("e");
        list.add("w");
        list.add("v");
        list.add("s");
        //字典顺序排序
        Collections.sort(list);
        System.out.println(list);
        //获取集合最大值、最小值
        String max = Collections.max(list);
        System.out.println(max);
        String min = Collections.min(list);
        System.out.println(min);
        //二分查询(在list中找v的索引)(使用前,必须保证集合元素是自然有序的,sort)
        int v = Collections.binarySearch(list, "v");
        System.out.println(v);
        //混洗,打乱已有顺序
        Collections.shuffle(list);
        //反转、倒序
        Collections.reverse(list);
        //换顺序
        Collections.swap(list,2,3);
        //替换
        Collections.replaceAll(list, "a", "A");
        //将所有元素全部填充
        Collections.fill(list,"H");

数组工具类Arrays(数组)

        int[] arr = new int[]{
   2,4,5,8,6,1};
        //排序
        Arrays.sort(arr);
        for (int i = 0; i <arr.length ; i++) {
   
            System.out.print(arr[i]+"\t");
        }

        System.out.println();

        //二分法找数字(返回下表)(先有序)
        int i1 = Arrays.binarySearch(arr, 5);
        System.out.println(i1);
        
        System.out.println();

        //数字全部填充为5
        Arrays.fill(arr,5);
        for (int i = 0; i <arr.length ; i++) {
   
            System.out.print(arr[i]+"\t");
        }

比较器

list.add(3) ; //2 4 3 1 9

list.add(“b”) ; //b c a d w

Collections.sort(list) //能够识别一些自然顺序

但是,如果集合中的元素是 用户自定义对象,如何排序?

Person p1 = new Person(3,“zs”,23,6) ;

Person p2 = new Person(2,“ls”,24,2) ;

Person p3 = new Person(1,“ww”,25,8) ;

list.add(p1);

list.add(p2);

list.add(p3);

Collections.sort(list) //程序 无法知道 ,是根据什么排序? ->自定义比较器, 自定义“比较时,根据学号排”

自定义比较器:Comparable 、Comparator

Comparable: 内部比较器(侵入性,需要修改原有代码)

package col;

/* * Created by 颜群 */
public class Person implements Comparable{
   
    private int id ;
    private String name ;
    private int age ;
    private String city;
    public Person() {
   
    }



    public Person(int id, String name, int age, String city) {
   
        this.id = id;
        this.name = name;
        this.age = age;
        this.city = city;
    }
    public Person( String name, int age, String city) {
   
        this.name = name;
        this.age = age;
        this.city = city;
    }

    public int getId() {
   
        return id;
    }

    public void setId(int id) {
   
        this.id = id;
    }

    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 String getCity() {
   
        return city;
    }

    public void setCity(String city) {
   
        this.city = city;
    }

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

    //重写比较器接口中的方法
    @Override
    public int compareTo(Object o) {
   
      //Obiect转换成Person
    Person input =   (Person)o;
      //根据学号 降序 3,2,1
    int result =  this.id > input.id? -1:( this.id   == input.id?0:1);
       //如果学号相同根据姓名升序
      if(result == 0 ){
   
              //调用String已经重写过的compareTo本身就是升序/如果想要降序在前面加负号
          result =  -this.name.compareTo( input.name) ;
       }
       		 return result;
    }
}

思路:将比较的对象(Person)实现Comparable接口,重写连的compareTo()方法。在compareTo()中编写比较的逻辑。重点是返回值,-1 ,0,1 ;

Comparator:外部比较器 (无侵入性,不影响原有代码)

1.先定义一个外部比较器

package col;

import java.util.Comparator;

public class MyComparatorWithId implements Comparator {
   
    @Override
    public int compare(Object o1, Object o2) {
   
      //先转换
        Student s1 =  (Student)o1 ;
        Student s2 =  (Student)o2 ;
        return   s2.getId() -  s1.getId()  ;
      
    }
}

2.使用外部比较器

package col;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

//内部比较器
public class Demo08 {
   
    public static void main(String[] args) {
   

        Student s1 = new Student(10,"zs",23,"xa") ;
        Student s2 = new Student(2,"zs",26,"xa") ;
        Student s3 = new Student(3,"zs",24,"xa") ;
        List<Student> students = new ArrayList<>() ;
        students.add(s1);
        students.add(s2);
        students.add(s3);

  Collections.sort(students,new MyComparatorWithId() );
      //给students使用了MyComparatorWithId比较器
        System.out.println(students);

    }
}

List list = new ArrayList<>() ;

包装类(自动装箱、自动拆箱)

evething is an Object,万物皆对象。 属性、方法

自动装箱:基本类型 ->包装类型 ,int ->Integer(有更多的属性和方法)

自动拆箱:包装类型->基本类型,Integer ->int

java中 将8个基本类型,包装成了8个对象类型(引用类型)。这8个对象类型 就成为包装类

package col;


public class BZL {
   
    public static void main(String[] args) {
   
        int i = 10 ;

        Integer j = new Integer(20) ;
        i = j ;//Integer->int 自动拆箱 底层用的是intValue()
        j = i ;
//int ->Integer 自动装箱 底层用的是valueOf() ,该方法中有个缓冲区 [-128,127],
//如果要装箱的数字 在缓冲区范围以内,则直接从缓冲区中取;否则,new Integer()一个新对象


        Integer i1 = 100 ;
        Integer i2 = 100 ;
//因为100在缓冲区以内所以从缓冲区拿100是同一个对象。所以为true

        Integer i3 = 1000 ;
        Integer i4 = 1000 ;
//因为1000大于缓冲区所以new了两个Integer而对象类型对比的是引用是否为同一个
        System.out.println(i1 == i2);//true
        System.out.println(i3 == i4);//false
      
      

    }
}

面试题

面试题

  1. set中的remove()为什么只能根据内容删除?不能根据下表删除?

​ 因为set是无序的没有下标

  1. 当Map中的key转换成单值时为什么系统转换成了set?

​ 因为map中的key是唯一的,set也是唯一的(二者匹配)

全部评论

相关推荐

02-25 21:07
中北大学 Python
初创团队 实习生 1500房补加每天450块钱
点赞 评论 收藏
分享
数开小菜鸡:你是我今早见过的最美的牛客女孩......
点赞 评论 收藏
分享
昨天 18:25
已编辑
南京大学 算法工程师
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客企业服务