泛型,数据结构,List,Set

1 泛型

1.1 泛型的介绍

  • 泛型是一种类型参数,专门用来保存类型用的

    • 最早接触泛型是在ArrayList,这个E就是所谓的泛型了。使用ArrayList时,只要给E指定某一个类型,里面所有用到泛型的地方都会被指定对应的类型

1.2 使用泛型的好处

  • 不用泛型带来的问题

    • 集合若不指定泛型,默认就是Object。存储的元素类型自动提升为Object类型。获取元素时得到的都是Object,若要调用特有方法需要转型,给我们编程带来麻烦.
  • 使用泛型带来的好处
    • 可以在编译时就对类型做判断,避免不必要的类型转换操作,精简代码,也避免了因为类型转换导致的代码异常
 //泛型没有指定类型,默认就是Object
ArrayList list = new ArrayList();
list.add("Hello");
list.add("World");
list.add(100);
list.add(false);
//集合中的数据就比较混乱,会给获取数据带来麻烦
for (Object obj : list) {String str = (String) obj;//当遍历到非String类型数据,就会报异常出错System.out.println(str + "长度为:" + str.length());
}

1.3 泛型的注意事项

  • 泛型在代码运行时,泛型会被擦除。后面学习反射的时候,可以实现在代码运行的过程中添加其他类型的数据到集合

    • 泛型只在编译时期限定数据的类型 , 在运行时期会被擦除

1.4 自定义泛型类

  • 当一个类定义其属性的时候,不确定具体是什么类型时,就可以使用泛型表示该属性的类型

  • 定义的格式
    • 在类型名后面加上一对尖括号,里面定义泛型。一般使用一个英文大写字母表示,如果有多个泛型使用逗号分隔
    • public class 类名<泛型名>{ … }
    举例 :
    public class Student<X,Y>{  X  xObj;
    }
    
  • 泛型的确定
    • 当创建此泛型类是 , 确定泛型类中泛型的具体数据类型
  • 练习
package com.itheima.genericity_demo.genericity_class;import java.time.Period;/*需求 : 定义一个人类,定义一个属性表示爱好,但是具体爱好是什么不清楚,可能是游泳,乒乓,篮球。*/
public class GenericityDemo {public static void main(String[] args) {Person<BasketBall> person = new Person<>();person.setHobby(new BasketBall());Person<Swim> person2 = new Person<>();person2.setHobby(new Swim());Person person3 = new Person<>();// 如果没有指定泛型 , 那么默认使用Object数据类型}
}class Person<H> {// 定义属性表达爱好private H hobby;public H getHobby() {return hobby;}public void setHobby(H hobby) {this.hobby = hobby;}
}class Swim {}class PingPang {}class BasketBall {}

1.3 自定义泛型接口

  • 当定义接口时,内部方法中其参数类型,返回值类型不确定时,就可以使用泛型替代了。

  • 定义泛型接口
    • 在接口后面加一对尖括号 , 尖括号中定义泛型 , 一般使用大写字母表示, 多个泛型用逗号分隔
    • public interface<泛型名> { … }
    • 举例 :
    public interface Collection<E>{public boolean add(E e);
    } 
  • 泛型的确定
    • 实现类去指定泛型接口的泛型
    • 实现了不去指定泛型接口的泛型 , 进行延续泛型 , 回到泛型类的使用
package com.itheima.genericity_demo.genericity_interface;
/*需求:模拟一个Collection接口,表示集合,集合操作的数据不确定。定义一个接口MyCollection具体表示。*/
// 泛型接口
public interface MyCollection<E> {// 添加功能public abstract void add(E e);// 删除功能public abstract void remove(E e);
}// 指定泛型的第一种方式 : 让实现类去指定接口的泛型
class MyCollectionImpl1 implements MyCollection<String>{@Overridepublic void add(String s) {}@Overridepublic void remove(String s) {}
}
// 指定泛型的第二种方式 : 实现类不确定泛型,延续泛型,回到泛型类的使用
class MyCollectionImpl2<E> implements MyCollection<E>{@Overridepublic void add(E a) {}@Overridepublic void remove(E a) {}
}

1.4 自定义泛型方法

  • 当定义方法时,方法中参数类型,返回值类型不确定时,就可以使用泛型替代了

  • 泛型方法的定义
    • 可以在方法的返回值类型前定义泛型
    • 格式 : public <泛型名> 返回值类型 方法名(参数列表){ … }
    • 举例 : public void show(T t) { … }
  • 泛型的确定
    • 当调用一个泛型方法 , 传入的参数是什么类型, 那么泛型就会被确定
  • 练习
    package com.itheima.genericity_demo.genericity_method;import java.util.ArrayList;
    import java.util.Arrays;public class Test {public static void main(String[] args) {// Collection集合中 : public <T> T[] toArray(T[] a) : 把集合中的内容存储到一个数组中 , 进行返回ArrayList<String> list = new ArrayList<>();list.add("abc");list.add("ads");list.add("qwe");String[] array = list.toArray(new String[list.size()]);System.out.println(Arrays.toString(array));}// 接收一个集合 , 往集合中添加三个待指定类型的元素public static <X> void addElement(ArrayList<X> list, X x1, X x2, X x3) {list.add(x1);list.add(x2);list.add(x3);}
    }
    

1.5 通配符

  • 当我们对泛型的类型确定不了,而是表达的可以是任意类型,可以使用泛型通配符给定

    符号就是一个问号:? 表示任意类型,用来给泛型指定的一种通配值。如下

public static void shuffle(List<?> list){//…
} 说明:该方法时来自工具类Collections中的一个方法,用来对存储任意类型数据的List集合进行乱序
  • 泛型通配符结合集合使用

    • 泛型通配符搭配集合使用一般在方法的参数中比较常见。在集合中泛型是不支持多态的,如果为了匹配任意类型,我们就会使用泛型通配符了。
    • 方法中的参数是一个集合,集合如果携带了通配符,要特别注意如下
      • 集合的类型会提升为Object类型
      • 方法中的参数是一个集合,集合如果携带了通配符,那么此集合不能进行添加和修改操作 , 可以删除和获取
    package com.itheima.genericity_demo;import java.util.ArrayList;
    import java.util.List;public class Demo {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("abc");list.add("asd");list.add("qwe");// 方法的参数是一个集合 , 集合的泛型是一个通配符 , 可以接受任意类型元素的集合show(list);}public static void show(List<?> list) {// 如果集合的泛型是一个通配符 , 那么集合中元素以Object类型存在Object o = list.get(0);// 如果集合的泛型是一个通配符 , 那么此集合不能进行添加和修改操作 , 可以删除和获取// list.add(??);// 删除可以list.remove(0);// 获取元素可以for (Object o1 : list) {System.out.println(o1);}}
    }
    
    package com.itheima.genericity_demo;import java.util.ArrayList;/*已知存在继承体系:Integer继承Number,Number继承Object。定义一个方法,方法的参数是一个ArrayList。要求可以接收ArrayList<Integer>,ArrayList<Number>,ArrayList<Object>,ArrayList<String>这些类型的数据。结论 : 具体类型的集合,不支持多态 , 要想接收任意类型集合 , 需要使通配符集合*/
    public class Test1 {public static void main(String[] args) {ArrayList<Integer> list1 = new ArrayList<>();ArrayList<Number> list2 = new ArrayList<>();ArrayList<String> list3 = new ArrayList<>();ArrayList<Object> list4 = new ArrayList<>();useList5(list1);useList5(list2);useList5(list3);useList5(list4);}// 此方法只能接收存储Integer类型数据的集合public static void useList1(ArrayList<Integer> list) {}// 此方法只能接收存储Number类型数据的集合public static void useList2(ArrayList<Number> list) {}// 此方法只能接收存储String类型数据的集合public static void useList3(ArrayList<String> list) {}// 此方法只能接收存储Object类型数据的集合public static void useList4(ArrayList<Object> list) {}public static void useList5(ArrayList<?> list) {}}
    

1.6 受限泛型

  • 受限泛型是指,在使用通配符的过程中 , 对泛型做了约束,给泛型指定类型时,只能是某个类型父类型或者子类型

  • 分类 :

    • 泛型的下限 :

      • <? super 类型> //只能是某一类型,及其父类型,其他类型不支持
    • 泛型的上限 :
      • <? extends 类型> //只能是某一个类型,及其子类型,其他类型不支持
    package com.itheima.genericity_demo.wildcard_demo;import java.util.ArrayList;/*wildcardCharacter基于上一个知识点,定义方法show1方法,参数只接收元素类型是Number或者其父类型的集合show2方法,参数只接收元素类型是Number或者其子类型的集合*/
    public class Test2 {public static void main(String[] args) {ArrayList<Integer> list1 = new ArrayList<>();ArrayList<Number> list2 = new ArrayList<>();ArrayList<Object> list3 = new ArrayList<>();show1(list3);show1(list2);show2(list2);show2(list1);}// 此方法可以接受集合中存储的是Number或者Number的父类型 , 下限泛型public static void show1(ArrayList<? super Number> list) {}// 此方法可以接受集合中存储的是Number或者Number的子类型 , 上限泛型public static void show2(ArrayList<? extends Number> list) {}
    }
    

2 数据结构

  • 栈结构 : 先进后出

  • 队列结构 : 先进先出

  • 数组结构 : 查询快 , 增删慢

  • 链表结构 : 查询慢 , 增删快

  • 二叉树

    • 二叉树 : 每个节点最多有两个子节点

    • 二茬查找树 : 每个节点的左子节点比当前节点小 , 右子节点比当前节点大

    • 二茬平衡树 : 在查找树的基础上, 每个节点左右子树的高度不超过1

    • 红黑树 :

      • 每一个节点或是红色的,或者是黑色的

      • 根节点必须是黑色

      • 如果一个节点没有子节点或者父节点,则该节点相应的指针属性值为Nil,这些Nil视为叶节点,每个叶节点(Nil)是黑色的

      • 不能出现两个红色节点相连的情况

      • 对每一个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点

      • 添加元素 :

  • 哈希表结构 :

    • 哈希值:是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
    • Object类中有一个方法可以获取对象的哈希值
      public int hashCode():返回对象的哈希码值
    • 对象的哈希值特点
      • 同一个对象多次调用hashCode()方法返回的哈希值是相同的
      • 默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同

3 List集合

  • List集合是Collection集合子类型,继承了所有Collection中功能,同时List增加了带索引的功能

  • 特点 :
    • 元素的存取是有序的【有序】
    • 元素具备索引 【有索引】
    • 元素可以重复存储【可重复】
  • 常见的子类
    • ArrayList:底层结构就是数组【查询快,增删慢】
    • Vector:底层结构也是数组(线程安全,同步安全的,低效,用的就少)
    • LinkedList:底层是链表结构(双向链表)【查询慢,增删快】
  • List中常用的方法

List继承了Collection中所有方法,元素具备索引特性,因此新增了一些含有索引的特有方法

  • public void add(int index, E element): 将指定的元素,添加到该集合中的指定位置上。
  • public E get(int index):返回集合中指定位置的元素
  • public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。
  • public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回值的更新前的元素
package com.itheima.list_demo;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;/*List继承了Collection中所有方法,元素具备索引特性,因此新增了一些含有索引的特有方法,如下:- public void add(int index, E element): 将指定的元素,添加到该集合中的指定位置上。- public E get(int index):返回集合中指定位置的元素。- public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。- public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回值的更新前的元素*/
public class ListDemo1 {public static void main(String[] args) {// 可以采用多态的形式创建对象List<String> list = new ArrayList<>();//  [周瑜   黄盖   周泰    甘宁   陆逊   吕蒙]list.add("周瑜");list.add("黄盖");list.add("周泰");list.add("甘宁");list.add("陆逊");list.add("吕蒙");// - public void add(int index, E element): 将指定的元素,添加到该集合中的指定位置上。// list.add(3 , "鲁肃");// - public E get(int index):返回集合中指定位置的元素。
//        System.out.println(list.get(0));
//        System.out.println(list.get(1));
//        System.out.println(list.get(2));
//        System.out.println(list.get(3));
//        System.out.println(list.get(4));
//        System.out.println(list.get(5));
//        for (int i = 0; i < list.size(); i++) {//            System.out.println(list.get(i));
//        }// - public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。// System.out.println(list.remove(1));//  - public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回值的更新前的元素// System.out.println(list.set(3 , "孙权"));//        ArrayList<Integer> list2 = new ArrayList<>();
//        list2.add(1);//删除 ?
//        list2.add(2);//删除 ?
//        list2.add(3);
//        list2.remove((Integer) 1);
//        System.out.println(list2);// 1 3Iterator<String> it = list.iterator();while(it.hasNext()){String s = it.next();System.out.print(s + "   ");}}
}
  • LinkedList类
    • LinkedList底层结构是双向链表。每个节点有三个部分的数据,一个是保存元素数据,一个是保存前一个节点的地址,一个是保存后一个节点的地址。可以双向查询,效率会比单向链表高。
    • LinkedList特有方法
      • public void addFirst(E e):将指定元素插入此列表的开头。
      • public void addLast(E e):将指定元素添加到此列表的结尾。
      • public E getFirst():返回此列表的第一个元素。
      • public E getLast():返回此列表的最后一个元素。
      • public E removeFirst():移除并返回此列表的第一个元素。
      • public E removeLast():移除并返回此列表的最后一个元素。
package com.itheima.list_demo;import java.util.LinkedList;/*LinkedList特有功能public void addFirst(E e):将指定元素插入此列表的开头。public void addLast(E e):将指定元素添加到此列表的结尾。public E getFirst():返回此列表的第一个元素。public E getLast():返回此列表的最后一个元素。public E removeFirst():移除并返回此列表的第一个元素。public E removeLast():移除并返回此列表的最后一个元素。*/
public class LinkedListDemo {public static void main(String[] args) {LinkedList<String> list = new LinkedList<>(); // [黄忠, 关羽, 张飞, 赵云, 马超]list.add("黄忠");list.add("关羽");list.add("张飞");list.add("赵云");list.add("马超");// public void addFirst(E e):将指定元素插入此列表的开头。// list.addFirst("刘备");// public void addLast(E e):将指定元素添加到此列表的结尾// list.addLast("刘禅");// public E getFirst():返回此列表的第一个元素// System.out.println(list.getFirst());// public E getLast():返回此列表的最后一个元素。// System.out.println(list.getLast());// public E removeFirst():移除并返回此列表的第一个元素。// System.out.println(list.removeFirst());// public E removeLast():移除并返回此列表的最后一个元素。System.out.println(list.removeLast());System.out.println(list);// 内容}
}
ArrayList集合扩容分析

F:\黑马\01-JavaSE进阶面授\day05【泛型,数据结构,List接口,Set接口】\资料

package com.itheima.list_demo;import java.util.ArrayList;
import java.util.Arrays;public class ArrayListDemo {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("于禁");list.add("华佗");list.add("潘凤");/*ArrayList集合是属于 -- 数组结构研究集合如何进行扩容 ?空参构造方法 : Object[] elementData = {};*/int[] arr = {};int[] newArr = Arrays.copyOf(arr, 10);System.out.println(Arrays.toString(newArr));}
}

4 Set集合

  • Set集合也是Collection集合的子类型,没有特有方法。Set比Collection定义更严谨
  • 特点 :
    • 元素不能保证插入和取出顺序(无序)
    • 元素是没有索引的(无索引)
    • 元素唯一(元素唯一)
  • Set常用子类
    • HashSet:底层由HashMap,底层结构哈希表结构。
      去重,无索引,无序。
      哈希表结构的集合,操作效率会非常高。

    • LinkedHashSet:底层结构链表加哈希表结构。
      具有哈希表表结构的特点,也具有链表的特点。
      链表结构:是为了保证插入顺序
      哈希表结构:是为了去重
      存储元素的时候,先过哈希表,如果哈希表能够接受数据,进一步存到链表结构表结构实实现

    • TreeSet:底层是有TreeMap,底层数据结构 红黑树。
      去重,让存入的元素具有排序(升序排序)

  • HashSet概述 :

    • java.util.HashSet是Set接口的实现类,没有特有方法。 底层是哈希表结构,具有去重特点。
package com.itheima.set_demo;import java.util.HashSet;/*练习 : 使用HashSet集合存储字符串并遍历HashSet特点 :1 无序2 没有索引3 保证元素唯一*/
public class HashSetDemo1 {public static void main(String[] args) {HashSet<String> set = new HashSet<>();set.add("abc");set.add("abc");for (String s : set) {System.out.println(s);}}
}
package com.itheima.set_demo;public class Student {private String name;private int age;public Student() {}public Student(String name, int age) {this.name = name;this.age = 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;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;if (age != student.age) return false;return name != null ? name.equals(student.name) : student.name == null;}//    @Override
//    public int hashCode() {//        return 1;
//    }//  减少equals方法的执行次数 , 从而提高效率
//    @Override
//    public int hashCode() {//            /*
//                s1 = 7 + 3 = 10
//                s2 = 3 + 7 = 10
//            */
//        return name.hashCode() + age;
//    }@Overridepublic int hashCode() {/*s1 = 217 + 3 = 220s2 = 93 + 7  = 10031 常量 : 1,质数    2,不大不小  3, 2的五次方-1*/int result = name != null ? name.hashCode() : 0;result = 31 * result + age;return result;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}package com.itheima.set_demo;import java.util.HashSet;/*练习 : 使用HashSet集合存储自定义对象并遍历HashSet特点 :1 无序2 没有索引3 保证元素唯一HashSet集合要想保证元素的唯一 , 那么存储元素所在的类 , 必须重写hashCode和equals方法*/
public class HashSetDemo2 {public static void main(String[] args) {// 创建集合对象HashSet<Student> set = new HashSet<>();// { s1 }// 创建元素对象Student s1 = new Student("柳岩", 3);Student s2 = new Student("景甜", 7);// Student s3 = new Student("李四", 24);// 把元素添加到集合中set.add(s1);set.add(s2);// set.add(s3);// 遍历集合for (Student s : set) {System.out.println(s);}}
}
//    public V put(K key, V value) {// key代表的是HashSet集合添加的元素
//
//        int hash = hash(key); // 获取添加元素的哈希值
//
//        // 遍历当前集合中已经存在的元素
//        for (Entry<K,V> e = table[i]; e != null; e = e.next) {//            Object k;
//            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {//                V oldValue = e.value;
//                e.value = value;
//                e.recordAccess(this);
//                return oldValue;
//            }
//        }
//
//        modCount++;
//        // 添加元素的方法
//        addEntry(hash, key, value, i);
//        return null;
//    }
  • 哈希值

    • 哈希值:是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
    • Object类中有一个方法可以获取对象的哈希值
      • public int hashCode​():返回对象的哈希码值
    • 对象的哈希值特点
      • 同一个对象多次调用hashCode()方法返回的哈希值是相同的
      • 默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同
  • 哈希表

    • JDK8之前,底层采用数组+链表实现,可以说是一个元素为链表的数组
    • JDK8以后,在长度比较长的时候,底层实现了优化
package com.itheima.set_demo;/*哈希值 :1 通过对象的地址获取 , 不同对象的哈希值不同2 重写了hashCode方法 , 不同的对象, 但是获取的哈希值是有可能相等的Object类中有一个方法可以获取对象的哈希值public int hashCode​():返回对象的哈希码值对象的哈希值特点同一个对象多次调用hashCode()方法返回的哈希值是相同的默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同哈希表结构JDK8之前 :哈希表 : 数组 + 链表JDK8版本及之后 :哈希表 : 数组 + 链表/红黑树*/
public class HashCodeDemo {public static void main(String[] args) {Student s1 = new Student();System.out.println(s1.hashCode());
//        System.out.println(s.hashCode());
//        System.out.println(s.hashCode());Student s2 = new Student();System.out.println(s2.hashCode());System.out.println("你好".hashCode());// 652829// 哈希冲突System.out.println("通话".hashCode());// 1179395System.out.println("重地".hashCode());// 1179395}
}
  • LinkedHashSet

package com.itheima.set_demo;import java.util.LinkedHashSet;public class LinkedHashSetDemo {public static void main(String[] args) {LinkedHashSet<Integer> linkedHashSet = new LinkedHashSet<>();linkedHashSet.add(10);linkedHashSet.add(10);linkedHashSet.add(20);linkedHashSet.add(30);System.out.println(linkedHashSet);}
}

4 集合总结

package com.itheima.test;
/*集合 :单列集合 : Collection接口List接口 : 1 有序 , 2 有索引 ,  3 元素可以重复ArrayList类  : 数组结构(查询快 , 增删慢)LinkedList类 : 链表结构(查询满 , 增删快)Set 接口 : 1 无序 , 2 无索引 ,  3 元素唯一HashSet类  : 哈希表结构(JDK8之前 : 数组 + 链表 )(JDK8包含及之后 : 数组 + 链表/红黑树)LinkedHashSet类 : 元素唯一并有序 .  哈希表 + 链表TreeSet类  : 红黑树(可以对元素进行排序 , 还可以保证元素唯一) , 今天不学双列集合 : Map接口TreeMap类 : 红黑树(可以对元素进行排序 , 还可以保证元素唯一)HashMap类 : 哈希表结构(JDK8之前 : 数组 + 链表 )(JDK8包含及之后 : 数组 + 链表/红黑树)集合的遍历 : 单列集合的遍历1 普通for循环(根据所以获取元素值)只能遍历List集合体系2 迭代器所有的单列集合3 增强for所有的单列集合,和数组*/
public class Test {public static void main(String[] args) {}
}
package com.itheima.test;import java.util.ArrayList;
import java.util.Iterator;public class ArrayListDemo {public static void main(String[] args) {// 创建集合对象ArrayList<String> list = new ArrayList<>();// 直接添加元素list.add("马云禄");list.add("关凤");list.add("关银屏");list.add("貂蝉");list.add("孙尚香");// 迭代器Iterator<String> it = list.iterator();while (it.hasNext()) {String s = it.next();System.out.println(s);}System.out.println("===========");// 增强forfor (String s : list) {System.out.println(s);}System.out.println("===========");// 普通for循环for (int i = 0; i < list.size(); i++) {String s = list.get(i);System.out.println(s);}}
}
package com.itheima.test;import java.util.Iterator;
import java.util.LinkedList;
/*因为底层为双向链表public void addFirst(E e):将指定元素插入此列表的开头。public void addLast(E e):将指定元素添加到此列表的结尾。public E getFirst():返回此列表的第一个元素。public E getLast():返回此列表的最后一个元素。public E removeFirst():移除并返回此列表的第一个元素。public E removeLast():移除并返回此列表的最后一个元素。*/
public class LinkedListDemo {public static void main(String[] args) {// 创建集合对象LinkedList<String> list = new LinkedList<>();// 直接添加元素list.add("马云禄");list.add("关凤");list.add("关银屏");list.add("貂蝉");list.add("孙尚香");// 遍历集合// 迭代器Iterator<String> it = list.iterator();while(it.hasNext()){String s = it.next();System.out.println(s);}System.out.println("============");// 增强forfor (String s : list) {System.out.println(s);}System.out.println("============");// 普通forfor (int i = 0; i < list.size(); i++) {String s = list.get(i);System.out.println(s);}}
}
package com.itheima.test;import java.util.HashSet;
import java.util.Iterator;/*HashSet要想保证元素的唯一 , 那么元素所在的类必须重写hashCode和equals方法  !!!!!!*/
public class HashSetDemo {public static void main(String[] args) {HashSet<String> hs = new HashSet<>();hs.add("abs");hs.add("abc");hs.add("abs");hs.add("abc");// 遍历方式// 迭代器Iterator<String> it = hs.iterator();while(it.hasNext()){String s = it.next();System.out.println(s);}System.out.println("===============");// 增强forfor (String h : hs) {System.out.println(h);}}
}
package com.itheima.test;public class Student {private String name;private int age;public Student() {}public Student(String name, int age) {this.name = name;this.age = 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;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;if (age != student.age) return false;return name != null ? name.equals(student.name) : student.name == null;}@Overridepublic int hashCode() {int result = name != null ? name.hashCode() : 0;result = 31 * result + age;return result;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}
package com.itheima.test;import java.util.HashSet;
import java.util.Iterator;/*HashSet要想保证元素的唯一 , 那么元素所在的类必须重写hashCode和equals方法  !!!!!!*/
public class HashSetDemo2 {public static void main(String[] args) {// 创建集合对象HashSet<Student> hs = new HashSet<>();// 创建元素对象Student s1 = new Student("张三" , 23);Student s2 = new Student("张三" , 23);Student s3 = new Student("李四" , 24);// 添加到集合中hs.add(s1);hs.add(s2);hs.add(s3);// 迭代器Iterator<Student> it = hs.iterator();while(it.hasNext()){Student s = it.next();System.out.println(s);}System.out.println("===========");// 增强forfor(Student s  : hs){System.out.println(s);}}
}
package com.itheima.test;import java.util.Iterator;
import java.util.LinkedHashSet;public class LinkedHashSetDemo {public static void main(String[] args) {LinkedHashSet<Student>  linkedHashSet = new LinkedHashSet<>();// 创建元素对象Student s1 = new Student("张三" , 23);Student s2 = new Student("张三" , 23);Student s3 = new Student("李四" , 24);linkedHashSet.add(s1);linkedHashSet.add(s2);linkedHashSet.add(s3);// 迭代器Iterator<Student> it = linkedHashSet.iterator();while(it.hasNext()){Student s = it.next();System.out.println(s);}System.out.println("======================");// 增强forfor (Student s : linkedHashSet) {System.out.println(s);}}
}

【泛型,数据结构,List接口,Set接口】相关推荐

  1. java泛型方法 通配符_Java泛型教程–示例类,接口,方法,通配符等

    java泛型方法 通配符 泛型是Java编程的核心功能之一,它是Java 5中引入的.如果您使用的是Java Collections ,并且版本5或更高版本,则可以肯定使用了它. 将泛型与集合类一起使 ...

  2. Java泛型教程–示例类,接口,方法,通配符等

    泛型是Java编程的核心功能之一,它是Java 5中引入的.如果您使用的是Java Collections ,并且版本5或更高版本,则可以肯定使用了它. 在集合类中使用泛型非常容易,但是它提供了比仅创 ...

  3. JAVA学习 API_day03(字符串编码, 泛型, 数据结构, Collection)

    字符串编码, 泛型, 数据结构, Collection 1.字符串编码 2.泛型 3.数据结构 4.Collection 1.字符串编码 1.String -> 字符序列 (中文\英文) JVM ...

  4. 常用的函数式接口_Consumer接口的默认方法andThen

    默认方法:andThen 如果一个方法的参数和返回值全都是Consumer 类型,那么就可以实现效果:消费数据的时候,首先做一个操作,然后再做一个操作,实现组合.而这个方法就是Consumer 接口中 ...

  5. 常用的函数式接口_Consumer接口

    Consumer接口 java.util.function.Consumer<T> 接口则正好与Supplier接口相反,它不是生产一个数据,而是消费一个数据,其数据类型由泛型决定. 抽象 ...

  6. 常用的函数式接口_Supplier接口

    常用函数式接口 JDK提供了大量常用的函数式接口以丰富Lambda的典型使用场景,它们主要在java.util.function 包中被提供. 下面是最简单的几个接口及使用示例. Supplier接口 ...

  7. java集合——集合接口+迭代器接口

    [0]README 0.1) 本文描述转自 core java volume 1, 源代码 diy 的, 旨在理解 java集合框架--集合接口+迭代器接口 的相关知识: 0.2) for full ...

  8. java 接口函数_Java函数式接口Supplier接口实例详解

    这篇文章主要介绍了Java函数式接口Supplier接口实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 JDK提供了大量常用的函数式接口以丰 ...

  9. java supplier接口_Java函数式接口Supplier接口实例详解

    这篇文章主要介绍了Java函数式接口Supplier接口实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 JDK提供了大量常用的函数式接口以丰 ...

  10. Java函数式接口--抽象方法接口

    1 函数式接口 函数式接口在Java中是指: 有且仅有一个抽象方法的接口 函数式接口, 即适用于函数式编程场景的接口; 而Java中函数式编程体现就是Lambda, 所以函数式接口就是可以适用于Lam ...

最新文章

  1. 字符编码笔记:ASCII,Unicode和UTF-8
  2. java学习体会论文_Java I/O学习心得一
  3. Mysql中的递归层次查询(父子查询)
  4. c语言 if 按大小顺序排序,刚学c语言,老师让用if编一个五个数字从大到小的排序,有那个大神能帮我,谢谢啦...
  5. 基于visual Studio2013解决C语言竞赛题之0505选数
  6. linux 日志面试题,Linux运维 | 面试题
  7. vs cpp代码 添加汇编_C++ 汇编代码查看
  8. ThinkPhp 更改 BIT 类型的问题
  9. 作为程序员,你还在用B站学习?别做梦了
  10. 6. php 基本语法
  11. ad 4层板设计实例文件_独家数据 | 1619Fall美研传媒类专业1590+申请实例(含大众传播、新闻学、公共关系、新媒体、整合营销等)...
  12. NeatUpload 同时选择并上传多个文件
  13. c语言编译怎么查看错误,C语言编译器的错误信息
  14. 面试官问“你还有什么需要了解的吗”——应该这样回答
  15. 软件工程师为什么单身的六宗罪
  16. webpack项目运用(一)打包压缩css文件
  17. 安卓玩机搞机技巧综合资源-----闲置手机当摄像头 当监控 上网课必备 多软件评测【十四】
  18. 隐藏微信右上角的分享按钮
  19. 2021年危险化学品生产单位安全生产管理人员新版试题及危险化学品生产单位安全生产管理人员考试总结
  20. 基于UBAT工具的试验性应用

热门文章

  1. 骑士问题-BFS求解
  2. java-家庭作业3
  3. 转载黑苹果10.13N卡驱动方法
  4. 矩阵基础概念之行列式与秩
  5. 【网络安全】小白每天学一点之“监控应用程序行为” [process monitor]
  6. jsp中空格字符怎么写_jsp多个空格符号怎么打
  7. IOS7.1.2越狱手工美化(字体,状态栏等资源) CSDN
  8. Mysql第一天笔记02——安装Navicat
  9. 不是有效的win32应用程序
  10. 解决Namecheap域名转入确认邮件重发及邮件收不到