栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

泛型与Java集合

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

泛型与Java集合

泛型与Java集合 1.Collection集合 集合的概念

集合是Java中提供的一种容器,可以用来存储多个数据。

数组:存储一组相同类型的数据结构

​ 局限:定长

集合:动态存放多个对象。

​ 动态:集合的大小随着存储的数据量而改变。

​ 多个:0~多个数据

​ 对象:存储类的实例。基本数据类型—>包装类对象。

集合框架

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7MW7do0N-1633501776094)(C:Users24329Desktop集合框架.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dGCS1XOj-1633501776096)(C:Users24329Desktop屏幕截图 2021-10-01 173105.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-exYThUji-1633501776097)(C:Users24329Desktop2.png)]

Collection常用功能
方法描述
boolean add(Object obj)添加一个对象数据
boolean addAll(Collection c)将一个集合中的所有对象添加到此集合中
void clear()清空此集合中的所有对象
boolean contains(Object obj)检查此集合中是否包含obj对象
boolean equals(Object obj)比较此集合中是否与指定对象相等
boolean isEmpty()判断此集合中是否为空
boolean remove(Object obj)在此集合中移除obj对象
int size()返回此集合中的元素个数
Object[] toArray()将此集合转换成数组

示例:

class Person{}

public class CollectionDemo {
    public static void main(String[] args) {
        //1.创建对象
        Collection con = new ArrayList();
        //添加元素
        con.add(123);//向上转型,int...>Integer...>Object
        con.add(true);
        con.add("hello");
        con.add(new Person());

        Collection subCol = new ArrayList();
        subCol.add(1);
        subCol.add(2);
        System.out.println("subCol:"+ subCol);

        con.add(subCol);//添加一个集合
        System.out.println("con:"+con);

        //清空
//        con.clear();
        System.out.println("清空之后得到con:"+con);

        //是否包含某个元素
        boolean contains = con.contains("hello");
        System.out.println("是否包含contains:"+contains);

        //equals
        Collection collection = new ArrayList();
        collection.add("1");
        collection.add("2");
        System.out.println("collection:"+ collection);
        boolean equals = subCol.equals(collection);//比较的是内容
        System.out.println("两个集合是否equals:"+ equals);

//        con.clear();
//        System.out.println("是否为空:"+con.isEmpty());

        //删除某个元素
        con.remove("1");
        System.out.println("删除元素之后:"+ con);
        System.out.println("集合里面有多少个元素:"+ con.size());

        //集合转数组
        Object[] objects = con.toArray();
        System.out.println("集合转数组:"+ Arrays.toString(objects));
    }
}
Iterator迭代器

在程序开发中,经常需要遍历集合中的所有元素。

迭代:即Collection集合元素的通用获取手段,在获取元素之前需要先判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有旧在取出来,一直把集合中的所有元素全部取出,这种取出的方式专业术语上称为迭代。

Iterator接口也是Java集合中的一员,但它与Collection、Map接口有所不同,Collection接口与Map接口主要用于存储元素。而Iterator主要用于迭代访问(即遍历)Collection中的元素。因此Iterator对象也被称为迭代器。

迭代器的常用方法

public Iterator iterator(); //获取集合对应的迭代器,用来遍历集合中的元素。
Iterator接口的常用方法
public E next(); //返回迭代的下一个元素
public boolean hasNext(); //如果仍有元素可以迭代,则返回true
step1:先获取集合上的迭代器
	Iterator it = c1.iterator();
step2:先判断迭代器后是否有数据
	it.hasNext()-->boolean
step3:通过迭代器获取集合的元素
	it.next()-->E

示例:

public class CollectionDemo2 {
    public static void main(String[] args) {
        //1.创建对象
        Collection col = new ArrayList();//可变长度
        //添加元素
        col.add(123); //向上转型,int-->Integer-->Object
        col.add(true);
        col.add("hello");
        //集合的遍历 for
//        for (int i = 0; i < col.size(); i++) {
//            //Collection这个父接口没有与下标相关的方法 所以不用fori循环
//        }
        //foreach
//        for (Object o : col) {
//            System.out.println(o);
//        }
        //迭代器 简化
        Iterator iterator = col.iterator();
        while(iterator.hasNext()){
            Object obj = iterator.next();
            System.out.println("obj:"+obj);
            //不要在迭代的过程中删除元素
            //col.remove("hello"); //java.util.ConcurrentModificationException
            //需要这样用迭代器删除
            iterator.remove();
        }
        System.out.println("col:"+col);
//        //迭代器
//        Iterator iterator = col.iterator();
//        boolean b = iterator.hasNext();
//        if (b) {
//            Object obj = iterator.next();
//            System.out.println("obj:"+obj);
//        }
//
//        b = iterator.hasNext();
//        if (b) {
//            Object obj = iterator.next();
//            System.out.println("obj:"+obj);
//        }
//
//        b = iterator.hasNext();
//        if (b) {
//            Object obj = iterator.next();
//            System.out.println("obj:"+obj);
//        }
//
//        //当判断到第四个元素是否存在的时候,会返回false
        b = iterator.hasNext();
        if (b) {
            Object obj = iterator.next();
            System.out.println("obj:"+obj);
        }
//        Object next = iterator.next(); //java.util.NoSuchElementException
//        System.out.println("next:"+next);

    }
}
2.泛型 概念

集合可以任意存放对象,只要把对象存储集合后,那么这时他们会被提升成Object类型,当我们再取出每一个对象,并且进行相应的操作,这时候就必须采用类型转换。

没有泛型的话,取出来的话,需要向下转型,效率低下,容易产生错误。

泛型:保护数据类型的安全。

语法:

Collection<数据类型> 对象 = new ArrayList();

示例:

Collection c = new ArrayList();
c.add("hello");
c.add("world");
//c.add(123);
System.out.println(c);
泛型的定义 定义含有泛型的类

定义格式:

修饰符 class 类名<代表泛型的变量>{}

什么时候确定泛型?在创建对象的时候确定泛型

示例:

//定义带有泛型的类
public class Point {
    private T x;
    private T y;
   	//在方法上定义含有泛型的方法
    public static  void getValue(K k){
        System.out.println("k:"+k);
    }
    //在方法上定义含有泛型的方法
    public static  void test(M m){ //
        System.out.println("检测到了静态方法上的泛型:"+ m);
    }

    public T getX() {
        return x;
    }

    public void setX(T x) {
        this.x = x;
    }

    public T getY() {
        return y;
    }

    public void setY(T y) {
        this.y = y;
    }
}


public class PointTest {
    public static void main(String[] args) {
        //创建对象的时候确定泛型的类型
        Point point = new Point<>();
        point.setX(34);
        point.setY(123);
        System.out.println("---------------");

        Point point2 = new Point<>();
        point2.setX("长34");
        point2.setY("宽12");

        //定义在方法的泛型,在调用时才确定类型
        Point.test("wowo");
        point.test(23);
        Point.getValue(67);
        Point.getValue("zhangsan");
    }
}
定义含有泛型的方法

定义格式:

修饰符 <代表泛型的变量> 返回值类型 方法名(参数){}

什么时候确定泛型?调用方法时,确定泛型的类型

示例:

    //在方法上定义含有泛型的方法
    public static  void getValue(K k){
        System.out.println("k:"+k);
    }
    
    //在方法上定义含有泛型的方法
    public static  void test(M m){
        System.out.println("检测到了静态方法上的泛型:"+ m);
    }
        //定义在方法的泛型,在调用时才确定类型
        Point.test("wowo");
        point.test(23);
        Point.getValue(67);
        Point.getValue("zhangsan");

含有泛型的接口

定义格式:

修饰符 interface 接口名<代表泛型的变量> {}

示例:

public interface Door {
    public T getType();
}


class  DoorImpl implements Door  {

    @Override
    public String getType() {
        return null;
    }
}

class  DoorImpl2 implements Door  {

    @Override
    public Integer getType() {
        return null;
    }
}
泛型通配符

当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以,可以通过通配符表示。但是一旦使用了泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。

?:通配符,不确定类型,代表集合中可以存储任意类型的数据。

List :该容器有数据类型Object。

? extends E  确定了上限,集合的泛型,E以及E的子类
? super E   确定了下限,集合泛型,E以及E的父类

示例:

class Person{}
class Student extends Person{}
public class Demo3 {

    //代表可以接受任意类型
    public static void test1(List list) {

    }

    //代表可以接受任意类型
    public static void test2(List list) {

    }

    //代表只能放Person以及Person的子类
    public static void test3(List list) {

    }

    //代表可以接受任意类型
    public static void test4(List list) {

    }

    public static void main(String[] args) {
        ArrayList list1 = new ArrayList<>();
        ArrayList list2 = new ArrayList<>();
        ArrayList list3 = new ArrayList<>();
        test1(list1);
        test1(list2);
        test1(list3);
        System.out.println("--------------");

        ArrayList list4 = new ArrayList<>();
        test2(list4);
        System.out.println("------------------");

        List personList =  new ArrayList<>();
        List studentList =  new ArrayList<>();
        test3(personList);
        test3(studentList);
        System.out.println("-----------------");

        test4(personList);
//        test4(studentList);
    }
}
 
3.集合 
List接口 

特点:有序,有下标。元素可以重复。

List作为Collection集合的子接口,不但继承了Collection接口中的全部方法,而且增加了一些根据元素索引来操作集合的特有方法。如下:

public void add(int index,E element);将指定的元素,添加到该集合中的指定位置上
public E get(int indedx)返回集合中指定位置的元素
public E remove(int index)移除列表中指定位置的元素,返回的是被移除的元素
public E set(int index,E element)用指定元素替换集合中指定位置的元素,返回值的 更新向前的元素
List实现类 ArrayList

java.util.ArrayList 集合数据存储的结构是数组结构。元素增删慢,查找快。

优点:查询数据,遍历数据效率很高。它使用索引快速定位对象

缺点:ArrayList在添加和删除元素的时候比linkedList比较慢。因为用了数组,需要移动后面的元素以调整索引的顺序。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c2h2KV2X-1633501776099)(C:Users24329DesktopArrayList.png)]

示例:

public class ListDemo {
    public static void main(String[] args) {
        //创建对象
        ArrayList list = new ArrayList<>();
        //添加元素
        list.add(0,100);
        list.add(1,200);
        list.add(2,300);
        list.add(3,400);
        System.out.println("list:"+list);
        //获取元素
        Integer element = list.get(2);
        System.out.println("element:"+element);
        //修改
        list.set(2,999);
        System.out.println("修改后的集合:"+list);
        //删除
        list.remove(3);
        System.out.println("删除后的集合:"+list);
    }
}
linkedList

java.util.linkedList 集合数据存储的结构是链表结构,方便元素添加,删除的集合,访问遍历相对于ArrayList较慢。

数据结构:链表

特点:查询慢,链表中地址不是连续的,每次查询元素,必须从头开始。

增删快,链表结构,增加删除一个元素,对链表整体的结构没有影响。所以增删快。

集合的添加与删除经常涉及到的首尾操作,而linkedList提供了大量的首尾操作方法。

如下:

public void addFirst(E e)将指定元素插入此列表的开头
public void addLast(E e)将制定元素添加到此列表的结尾
public E getFirst()返回列表的第一个元素
public E getLast()返回列表的最后一个元素
public E removeFirst()移除并返回此列表的第一个元素
public E removeLast()移除并返回此列表的最后一个元素
public E pop()从此列表所表示的堆栈处弹出一个元素
public void push(E e)将元素推入此列表所表示的堆栈
public boolean isEmpty()如果列表不包含元素,则返回true

示例:

public class linkedListDemo {
    public static void main(String[] args) {
        linkedList list = new linkedList<>();
        list.addFirst("123");
        list.addFirst("234");
        list.addFirst("hello");
        list.addFirst("true");
        System.out.println("list:"+list);
        System.out.println("---------------------");

        System.out.println("弹出一个元素:"+ list.pop());
        System.out.println("弹出一个元素之后打印:"+ list);
    }
}
Set接口

特点:无序,无下标,元素不可重复。

方法:全部继承自Collection中的方法。

使用foreach循环遍历:for(数据类型 局部变量 : 集合名){ //循环内部的局部变量,代表当次循环从集合中去处的对象}

Set实现类 HashSet

特点:无序,去重

JDK提供的类中,String,Integer可以直接添加到HashSet,自动去重。

自定义类:自己重写hashCode()和equals(),必须同时重写。

示例:

class Cat{
    private String name;
    private int 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;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + ''' +
                ", age=" + age +
                '}';
    }

    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Cat() {
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Cat cat = (Cat) o;
        return age == cat.age &&
                name.equals(cat.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}
public class SetDemo {
    public static void main(String[] args) {
        Set set = new HashSet<>();
        //添加
        set.add("hello1");
        set.add("hello2");
        set.add("hello3");
        set.add("hello4");
        System.out.println(set);
        System.out.println("-------------------");
        //遍历
        for (String s : set) {
            System.out.println("s:"+s);
        }
        System.out.println("---------------");
        //迭代器
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            String next = iterator.next();
            System.out.println("next:"+next);
        }
        System.out.println("----------------");

        Set set2 = new HashSet<>();
        //添加
        set2.add(2);
        set2.add(3);
        set2.add(4);
        set2.add(5);
        System.out.println("set2:"+set2);
        System.out.println("-------------------");

        //自定义类型 如果希望自定义类型的成员相同的时候,不要重复添加到set集合,那么应该重写hashCode()和equals()方法
        Set catSet = new HashSet<>();
        catSet.add(new Cat("Cat1",1));
        catSet.add(new Cat("Cat2",2));
        catSet.add(new Cat("Cat3",3));
        System.out.println("catSet:"+catSet);
    }
}
TreeSet

特点:有序,去重

JDK提供的类String、Integer。已经实现了这个Comparable接口,自动有序去重;

自定义的类:实现Comparable接口的comparableTo方法,在这个方法里重写相应的排序的规则。

示例:

public class Dog implements Comparable{
    private String name;
    private int age;
    //比较的方法 (从大到小)
    @Override
    public int compareTo(Dog dog) {
        //this指向新增加进来的元素
        if (this.getAge() > dog.getAge()){
            return -1;
        }else if (this.getAge() < dog.getAge()){
            return 1;
        }
        //如果年龄相等,在比较名字。
        return this.getName().compareTo(dog.getName());
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + ''' +
                ", age=" + age +
                '}';
    }
    
    public Dog() {}
    
    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Dog dog = (Dog) o;
        return age == dog.age &&
                Objects.equals(name, dog.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, 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 class TreeSetDemo {
    public static void main(String[] args) {
        TreeSet set = new TreeSet<>();
        set.add("aaa");
        set.add("bbb");
        set.add("ddd");
        set.add("ccc");
        System.out.println("set:"+set);
        System.out.println("------------------");
        TreeSet set2 = new TreeSet<>();
        set2.add(111);
        set2.add(222);
        set2.add(1);
        set2.add(2);
        set2.add(3);
        System.out.println("set2:"+set2);
        System.out.println("-----------------");
        Set dogSet = new TreeSet<>();
        dogSet.add(new Dog("小狗1",1));
        dogSet.add(new Dog("小狗2",2)); //添加第二个元素的时候
        dogSet.add(new Dog("小狗3",3));
        dogSet.add(new Dog("小狗4",3)); //去重
        System.out.println("dogSet:"+dogSet);
    }
}

Comparator接口

比较器,实现定制比较。

compare(o1,o2)方法的返回值0,表示重复。

示例:

public class TestComparator {
    public static  void main(String[] args) {
        //创建集合的时候,并指定比较器规则
       TreeSet dogTreeSet =  new TreeSet<>(new Comparator() {
           @Override
           public int compare(Dog dog1, Dog dog2) {
               if (dog1.getAge()>dog2.getAge()) {
                   return 1;
               }else if (dog1.getAge() < dog2.getAge()) {
                   return -1;
               }
               return dog1.getName().compareTo(dog2.getName());
              // return 0;
           }
       });
        dogTreeSet.add(new Dog("小狗1",1));
        dogTreeSet.add(new Dog("小狗2",2)); //添加第二个元素的时候
        dogTreeSet.add(new Dog("小狗3",3));
        dogTreeSet.add(new Dog("小狗4",3)); //去重
        System.out.println("dogTreeSet:"+dogTreeSet);
    }
}
Map接口

map接口,也是一种容器,存储的数据是成双成对儿出现的。键(key)、值(value)。

​ map存储的是键值对:key-value

注意点:

​ 1、存储无序的键值对儿

​ 2、key必须是唯一的,而且和value是一一对应的。

常用的方法:

方法名描述
V put(K key, V Value)将对象存入到集合中,关联键值。key重复则覆盖原值
Object get(Object key)根据键获取对应的值
Set keySet()返回所有的key
Collection values()返回包含所有值的collection集合
Set> entrySet()键值匹配的Set集合
Map实现类 HashMap

JDK1.2版本,线程不安全,运行效率快。

允许用null作为key或是value。

存储结构:哈希表。

示例:

public class MapDemo {
    public static void main(String[] args) {
        Map map = new HashMap<>();
        //put(key,value); 添加元素:key要唯一
        map.put("台湾1","周杰伦1");
        map.put("台湾2","周杰伦2");
        map.put("台湾3","周杰伦3");
        System.out.println(map);
        System.out.println("------------------");
        //如果有重复的key值,那么会覆盖原来的value值
        map.put("台湾1","周杰伦4");
        System.out.println(map);
        System.out.println("------------------");
        //根据key获取对应的value值
        System.out.println("map.get("台湾2"):"+map.get("台湾2"));
        System.out.println("------------------");
        //是否包含
        boolean result = map.containsKey("台湾1");
        System.out.println("是否包含这个key值:"+ result);
        System.out.println("------------------");
        //删除元素 remove(key);
        map.remove("台湾3");
        System.out.println("删除之后的map:"+map);
        System.out.println("------------------");
        //遍历 map.keySet();
        Set keySet = map.keySet();
        for (String key : keySet) {
            String value = map.get(key);
            System.out.println("value:"+value);
        }
        System.out.println("------------------");
        //遍历2 map.entrySet();
        Set> entrySet = map.entrySet();
        for (Map.Entry set : entrySet) {
            System.out.println(set.getKey()+":"+set.getValue());
        }
        
        
        HashMap hashMap = new HashMap<>();
        hashMap.put("aaa",1);
        hashMap.put("ddd",2);
        hashMap.put("ccc",1);
        hashMap.put("bb",4);
        System.out.println("hashMap:"+hashMap);
    }
}
TreeMap

实现了SortedMap接口(Map的子接口),可以对key自动排序。Key需实现Comparable接口。

public class TreeMapDemo {
    public static void main(String[] args) {
        //key会自动排序,要实现comparable接口
        TreeMap treeMap = new TreeMap<>();
        treeMap.put("bbb",2);
        treeMap.put("aaa",1);
        treeMap.put("ddd",4);
        treeMap.put("ccc",3);
        System.out.println("treeMap:"+treeMap);
    }
}
4.Collections工具类

常用方法:

方法描述
public static void reverse(List list)反转集合中元素的顺序
public static void shuffle(List list)随机重置集合元素的顺序
public static void sort(List list)升序排序(元素类型必须实现Comparable接口)
public static int binarySearch(list,T key)二分查找

示例:

public class CollectionsDemo {
    public static void main(String[] args) {
        ArrayList list = new ArrayList<>();
        list.add("aaa");
        list.add("333");
        list.add("222");
        list.add("111");
        System.out.println("排序前的:"+list);
        //Collection工具类的常用方法
        Collections.addAll(list,"hello","world");
        System.out.println(list);
        //排序
        Collections.sort(list);
        System.out.println("排序后的:"+list);
        //搜索
        int index = Collections.binarySearch(list,"111");
        System.out.println("index:"+index);
        //反转
        Collections.reverse(list);
        System.out.println("反转之后的list:"+list);
    }
}
               |

| public static void sort(List list) | 升序排序(元素类型必须实现Comparable接口) |
| public static int binarySearch(list,T key) | 二分查找 |

示例:

public class CollectionsDemo {
    public static void main(String[] args) {
        ArrayList list = new ArrayList<>();
        list.add("aaa");
        list.add("333");
        list.add("222");
        list.add("111");
        System.out.println("排序前的:"+list);
        //Collection工具类的常用方法
        Collections.addAll(list,"hello","world");
        System.out.println(list);
        //排序
        Collections.sort(list);
        System.out.println("排序后的:"+list);
        //搜索
        int index = Collections.binarySearch(list,"111");
        System.out.println("index:"+index);
        //反转
        Collections.reverse(list);
        System.out.println("反转之后的list:"+list);
    }
}
转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号