Java入门---------集合(尚马day15)Week4(7)

集合:
  将多个数据(元素)存储在一起。也是一个容器。
  理论上存储任意多个"不同数据类型"的数据。 
  只能存储 "引用数据类型的数据"
  底层已经封装好了空间不足或者移动位置等这些操作。
  //实际开发中  存储还是相同类型的数据(避免出现类型转换的异常)
 
  
数组: 
  一个容器。存储相同数据类型指定length个数据。
  空间固定   数据类型必须相同。
  数组可以存储什么类型的数据?
      int[] String[] Bike[] "所有的类型都可以。"
  优势:
    查询/修改性能最快。index
  弊端:
    新增/删除性能比较低。
    空间固定----> 一值新增 手动扩容
    数据是连贯的---->后面的数据向左移动位置

数组  VS  集合
相同点:容器。存储很多元素/数据。
不同点:
   数组: 空间固定   数据类型必须相同
   集合: 空间可变   数据类型可以相同  

1. 集合分类

Collection VS Map

元素 元素是否可重复
Collection<T> 存储的是单值元素(一次存储一个) 具体看子级List/set
Map<K,V> 存储的是一组元素(key-value) key必须唯一 value可重复的

Java入门---------集合(尚马day15)Week4(7)

 

2. Collection<T>

元素是否有序(索引位置) 元素是否可重复
List<T> 有序 可重复
Set<T> 无序 不可重复

2.1 常用方法

方法 功能
boolean`add(E e) 将指定的数据添加集合中
void``clear() 清空集合里面所有的元素
boolean``contains(Object o) 判断集合里面是否包含指定的数据
boolean``isEmpty() 判断集合是否是空
Iterator<E>``iterator() 获得集合对象的迭代器对象(遍历集合元素)
boolean``remove(Object o) 删除集合里面元素
int``size() 获得集合元素个数
Object[]``toArray() 集合转数组
<T> T[]``toArray(T[] a)
default boolean``removeIf(Predicate<? super E> filter) 删除满足条件的多个元素
Stream<E>``parallelStream() 获得集合对象的并行化Stream对象
default Stream<E>``stream() 获得集合串行化Stream对象
default void``forEach(Consumer<? super T> action) (遍历集合元素)

Iterator

boolean hasNext()  判断指针/光标后面是否有更多的数据需要迭代】
​
E next() 获得指针之后的元素数据
​
default void remove()  
从底层集合中删除此迭代器返回的最后一个元素(可选操作)。  
​

2.2 使用方法

 private static void demo1() {
        //创建集合对象 增删改查集合元素
        Collection collection = new ArrayList();
        //System.out.println(collection.isEmpty());
        System.out.println(collection);//[]
        //1.新增元素---> 存储不同类型的数据
        collection.add(100);
        collection.add("hello");
        collection.add("hello");
        collection.add("hello");
        collection.add(true);
        collection.add(null);
        collection.add(new UserInfo());
        collection.add(100.123);
​
        System.out.println(collection);
        System.out.println("集合的元素个数:" + collection.size());
​
        //2.删除集合元素
       /* collection.remove("hello");
        collection.remove("hello");
        collection.remove("hello");*/
        //循环 遍历集合里面的每个元素  删除满足条件的数据
        /*collection.removeIf(new Predicate() {
            @Override
            public boolean test(Object data) {
                return Objects.equals(data, "hello");
            }
        });*/
​
        //面向函数式编程----> 面向方法编程---->重写的那个方法
        //lamda:  ()->{}
        //类名/引用::方法名
        //collection.removeIf(a -> Objects.equals(a, "hello"));
        //collection.removeIf("hello"::equals);
​
        //判断集合里面是否包含指定的数据
        //System.out.println(collection.contains(100));
        //清空集合元素
        //collection.clear();
​
        //集合转数组
        //Object[] array = collection.toArray();
        //System.out.println(Arrays.toString(array));
        System.out.println(collection);
        System.out.println(collection.size());
    }

2.3 遍历集合元素

private static void demo2() {
​
    Collection collection = new ArrayList();
    collection.add(1);
    collection.add(10);
    collection.add(2);
    collection.add("abc");
    collection.add(null);
​
    //循环遍历输出集合里面的每个元素数据
    //增强for
    /*for(Object data:collection){
        System.out.println(data);
    }*/
 /*  //1.获得集合对象的迭代器对象
    Iterator it = collection.iterator();//集合里面的所有的数据都在it
    //2.判断指针之后是否有更多的数据需要迭代
    while (it.hasNext()) {
        //3.获得指针之后的数据
        Object data = it.next();
        System.out.println(data);
    }*/
​
    //1.8+  forEach
    /*collection.forEach(new Consumer() {
        @Override
        public void accept(Object obj) {
            System.out.println(obj);
        }
    });*/
​
    //使用lamda替换上面的匿名内部类
    //::
    // collection.forEach(o->System.out.println(o));
    collection.forEach(System.out::println);
​
    //遍历Collection:
    //1.增强for循环
    //2. iterator()
    //3. forEach();

2.4 集合_泛型

public static void main(String[] args) {
​
    //使用泛型修饰集合
    //泛型+集合: 限定集合元素数据类型。 只存储一种类型的数据。
    Collection<String> nameCollection = new ArrayList<>();
    //泛型只在编译期间有效 在运行期间其实泛型还是Object---->反射  泛型擦除
    nameCollection.add("张三");
    nameCollection.add("李四");
    nameCollection.add("王五");
    nameCollection.add("赵六");
​
    //遍历集合元素
    /*for (String name : nameCollection) {
        System.out.println(name);
    }*/
​
    //nameCollection.forEach(System.out::println);
   /* Iterator<String> it = nameCollection.iterator();
    while (it.hasNext()) {
        String str = it.next();
        System.out.println(str);
    }*/
​
    //nameCollection.remove("张三");
    //nameCollection.removeIf("张三"::equals);
    System.out.println(nameCollection);
​
    //集合转数组
    //无参的toArray()不推荐  返回值类型Object[]  需要进行手动类型转换
    /*Object[] array1 = nameCollection.toArray();
    for (Object o : array1) {
         String s= (String) o;
    }*/
    //<T> T[] toArray(T[] a);
    //集合转数组: 推荐数组的空间  0
    //length>size 有很多null  很容易NPE  空间内存浪费
    //size<length>0 并发的时候 多次将集合转数组  GC进行回收无用的数组引用
    //length==0
    String[] strings1 = nameCollection.toArray(new String[0]);
    System.out.println("strings1:" + Arrays.toString(strings1));
    
}

3. 泛型<>

<T,k> T K V 一般都是使用 A-Z。 限定泛型里面参数化的数据类型。

只能是引用数据类型。

作用: 实现类型的自动转换。

泛型修饰类   ----> 泛型类 
泛型修饰方法  ----> 泛型方法
泛型修饰接口 ---->  泛型接口

3.1 问题(使用变量维护不定类型的数据)

@Data
public class MyClass {
​
    private Integer id;
    private String name;
​
    //使用data维护了一个不定类型数据
    private Object data;
}

 private static void demo1() {
        //创建MyClass类对象 对属性进行取值以及赋值
        MyClass myClass = new MyClass();
        myClass.setId(1001);
        myClass.setName("zhangsan");
        myClass.setData(100);
​
​
        //每次获取数据的时候  都要手动进行类型的强制转换
        //有可能会出现类型转换的异常
        Integer id = myClass.getId();
        String name = myClass.getName();
        Integer data = (Integer) myClass.getData();
        data = data + 100;
​
        MyClass myClass1 = new MyClass();
        myClass1.setData("hello");
        String d = (String) myClass1.getData();
    }

可以满足使用data变量维护不同类型的数据。但是每次获得数据的时候 都要进行类型的强制转换 进而实现其他的功能。

在这种情况下:

  • 就会有可能出现类型转换的异常

  • 每次都进行手动的转换 代码不是很优雅

3.2 泛型类解决

目标: 不使用类型的强制转换 实现类型的自动转换 。

使用泛型进行解决。

//MyClass<T> 代表是一个泛型类。T:参数化类型
//不清楚T的真实的数据类型。Object
@Data
public class MyClass<T> {
​
    private Integer id;
    private String name;
​
    //使用data维护了一个不定类型数据
    private Object data;
​
    //参数化数据类型---->指定好的规则  A-Z    T  E  K V
    private T data1;
​
    //实例方法: 对象/引用.方法
    //参数化到底是什么类型?  创建对象的时候 指定的参数化类型具体是什么类型
    public T a(T t) {
        return null;
    }
}

public static void main(String[] args) {
​
    //需求: "实现类型的自动转换"
    //一般类  接口是泛型类或者泛型接口   一般都会指定参数化类型
    MyClass<String> myClass = new MyClass<>();
    myClass.setData1("hello");
    String data1 = myClass.getData1();
​
    MyClass<Integer> myClass1 = new MyClass<>();
    myClass1.setData1(100);
    Integer data11 = myClass1.getData1();
​
​
}

3.3 泛型方法

在任意一个类里面 都可以使用泛型修饰方法。

使用参数化类型修饰方法 这个方法就是泛型方法。

//K:是一个参数化类型  不指定  默认Object
public class FanXingClass<K> {
    private K a;
​
    //只是参数化类型 充当形参和返回值
    //K类型是固定的  只能是一种 创建对象的时候 指定的数据类型
    public K getA() {
        return a;
    }
​
    public void setA(K a) {
        this.a = a;
    }
​
    //泛型方法
    //T: 不定类型
    //K: 创建对象的时候类型  m1是一个实例方法
    public <T> void m1(T abc, K bb) {
    }
​
    //静态方法
    //是否可以使用参数化数据类型? 创建对象的时候指定参数化类型
    //在泛型类里面 提供了很多静态的方法  里面使用参数化类型 这些静态方法都是"泛型方法"
    public static <K>  void m2(K aaa) {
​
    }
​
    //一个泛型类里面 有很多的静态的方法 这个类一般都是工具类 用来封装一些的数据。
​
​
}

3.4 泛型接口

//后期有很多模块:  User  Product
// 新增 删除  修改  查询
//T  就是 User  Product....
class User {
}
​
class Product {
}
public interface BaseDao<T> {
    void add(T t);
​
    void delete();
​
    void update();
​
    T findOne();
​
    Collection<T> findAll();
}
​
class ProductDaoImpl implements BaseDao<Product>{
​
    @Override
    public void add(Product product) {
        
    }
​
    @Override
    public void delete() {
​
    }
​
    @Override
    public void update() {
​
    }
​
    @Override
    public Product findOne() {
        return null;
    }
​
    @Override
    public Collection<Product> findAll() {
        return null;
    }
}
class UserDaoImpl implements BaseDao<User>{
​
    @Override
    public void add(User user) {
        
    }
​
    @Override
    public void delete() {
​
    }
​
    @Override
    public void update() {
​
    }
​
    @Override
    public User findOne() {
        return null;
    }
​
    @Override
    public Collection<User> findAll() {
        return null;
    }
}

3.5 上限和下限

//使用 T extends 具体类型 规定参数化类型的上限
//只能:Number以及Number类型所有的子类
public class DemoTest<T extends Number> {
​
​
    //?是一个通配符 统配任意一个类型
    //下限: ?只能是String以及String的父级类型。
    public static void a(Collection<? super String> collection) {
​
    }
}
​
class Test3 {
    public static void main(String[] args) {
​
        Collection<Comparable> collection = new ArrayList<>();
        DemoTest.a(collection);
​
    }
}

上一篇:并发修改异常原理及原因


下一篇:react实例todolist