java map 泛型定义_泛型的定义以及set map接口

泛型(generic)

泛型的概念

泛型允许开发者在强类型程序设计语言(java)编写代码时定义一些可变部分,这些部分在使用前必须作出指明。

泛型的擦除

泛型在运行时已经被擦除了。

泛型的应用

泛型类

当一个类中属性的数据类型不确定时,具体是什么类型由使用者来确定时,使用泛型。泛型类的形式

泛型方法

当一个方法的参数类型不确定时,具体是什么类型由使用者来确定,可以考虑使用泛型方法。形式:

public  void xxx(T a) {

System.out.println(a);

}

泛型方法在调用时确定(指明)类型。

泛型方法在一定程度上优化了方法重载。

多个同类型的泛型

/ 多个同类型的泛型

/*public void print(A a) {

System.out.println(a);

}

public void print(A a,A b) {

System.out.println(a);

System.out.println(b);

}*/

public  void print(A...a) {

System.out.println(a);

}

A… a 表示方法可以接受多个参数。当调用方法传递多个参数时,多个参数被放到a数组中,a是什么类型的数组由开发者调用处传参决定。

泛型接口

如果接口中的方法的参数(形参、返回值)不确定时,可以考虑使用泛型接口。形式

public interface FanInterface {

public void showInfo(T t);

}

实现类能确定泛型接口的类型

实现类不能确定泛型接口的类型->继续泛。

泛型的上限和下限

public static void print(ArrayList extends Pet> list) {

for (Pet pet : list) {

pet.showInfo();

}

}

泛型的上限ArrayList(? extends Pet) list 声明了一个容器,容器中的元素类型一定要继承于Pet,我们称这种形式叫做泛型的上限。

泛型的下限ArrayList(? super Pet) list 声明了一个容器,容器中的元素类型一定要是Pet的父类,我们称这个形式为泛型的下限。

Set接口

Set接口表示一个唯一、无序的容器(和添加顺序无关)

Set接口提供的方法

public static void main(String[] args) {

/**

* 增:add/addAll

* 删:clear/remove/removeAll/retainAll

* 改:

* 查:contains/containsAll

* 遍历:iterator

* 其他:size/isEmpty

*/

Set set = new HashSet();

// [1]添加

// 无序

set.add(10);

set.add(3);

set.add(20);

set.add(0);

// 不能添加重复元素

boolean r = set.add(1);

System.out.println(set);

// 【2】删除

// set.remove(1);

// set.clear();

// System.out.println(set);

// 【3】查看是否包含

System.out.println(set.contains(1));

// 【4】其他

System.out.println(set.size());

System.out.println(set.isEmpty());

}

Set接口的遍历

public static void main(String[] args) {

Set set = new HashSet();

set.add("banana");

set.add("apple");

set.add("coco");

// 快速遍历

for (String item : set) {

System.out.println(item);

}

// 迭代器

Iterator it = set.iterator();

while(it.hasNext()) {

String item = it.next();

System.out.println(item);

}

}

Set接口的实现类常见的有HashSet、LinkedHashSet、TreeSet

HashSet

HashSet是Set接口的实现类,底层数据结构是哈希表。

HashSet是线程不安全的(不保证同步)

哈希表工作原理

5fffb7587c899bf0096d539823957800.png

添加自定义对象

根据哈希表的工作原理,请存储一个自定义对象到HashSet中。

package cn.sxt03.hashset;

public class Student {

private String id;

private String name;

private int age;

//…

@Override

public int hashCode() {

final int prime = 31;

int result = 1;

result = prime * result + age;

result = prime * result + ((id == null) ? 0 : id.hashCode());

result = prime * result + ((name == null) ? 0 : name.hashCode());

return result;

}

@Override

public boolean equals(Object obj) {

if (this == obj)

return true;

if (obj == null)

return false;

if (getClass() != obj.getClass())

return false;

Student other = (Student) obj;

if (age != other.age)

return false;

if (id == null) {

if (other.id != null)

return false;

} else if (!id.equals(other.id))

return false;

if (name == null) {

if (other.name != null)

return false;

} else if (!name.equals(other.name))

return false;

return true;

}

@Override

public String toString() {

return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";

}

}

总结

[1]如果向HashSet中存储元素时,元素一定要实现hashCode方法和equals方法。

[2] 优点:添加、删除、查询效率高;缺点:无序

LinkedHashSet

LinkedHashSet是Set接口的实现类,底层数据结构哈希表+链表

哈希表用于散列元素;链表用于维持添加顺序。

如果要添加自定义对象元素,也需要重写hashCode和equals方法。

TreeSet

TreeSet 是Set接口的实现类,底层数据结构是二叉树。

TreeSet 存储的数据按照一定的规则存储。存储规则让数据表现出自然顺序。

TreeSet工作原理

8c44463aac81eab82c595ed376e3daf8.png

添加一个新元素t的存储的步骤

[1] 如果集合无元素,t直接加入;如果集合有元素,t和根节点比较;

[2] 如果t小于根节点;把t放到根节点的左子树上;重复1-3步骤

[3] t大于根节点;把t放到根节点的右子树上;重复1-3步骤

输出时按照一定的规则:左子树->根节点->右子树

根据TreeSet的工作原理,向TreeSet添加自定义元素?

向TreeSet中添加元素时,一定要提供比较策略,否则会出现ClassCastException。

比较策略分两种:内部比较器和外部比较器

内部比较器

当一个自定义对象实现Comparable并实现compareTo方法时,通过指定具体的比较策略,此时称为内部比较器。

package cn.sxt05.treeset;

public class Student implements Comparable{

private String id;

private String name;

private int age;

//。。。

@Override

public String toString() {

return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";

}

@Override

public int compareTo(Student o) {

if(this.getAge()

return -1;

}else if(this.getAge() == o.getAge()) {

return 0;

}else {

return 1;

}

}

}

比较策略的几种情况

[1]比较策略一般当前对象写在前面,待比较对象也在后面,比较结果默认升序

return  this.getAge() - o.getAge() ;

如果想要降序,改变两个比较对象的位置即可。

[2] 多种比较因素

@Override

public int compareTo(Student o) {

/*if(this.getAge()

return -1;

}else if(this.getAge() == o.getAge()) {

return 0;

}else {

return 1;

}*/

// return  this.getAge() - o.getAge() ;

if(this.getAge()

return -1;

}else if(this.getAge() == o.getAge()) {

return this.getName().compareTo(o.getName());

}else {

return 1;

}

}

外部比较器

当实际开发过程中不知道添加元素的源代码、无权修改别人的代码,此时可以使用外部比较器。

Comparator 位于java.util包中,定义了compare(o1,o2) 用于提供外部比较策略。

TreeSet接受一个指定比较策略的构造方法,这些比较策略的实现类必须实现Comparator

接口。

需求:按照字符串的长度比较

public class Test01 {

public static void main(String[] args) {

LenComparator lenComparator = new LenComparator();

TreeSet set2 = new TreeSet(lenComparator);

set2.add("banana");

set2.add("coco");

set2.add("apple");

set2.add("apple");

System.out.println(set2);

}

}

class LenComparator implements Comparator{

@Override

public int compare(String o1, String o2) {

return o1.length() - o2.length();

}

}

使用匿名内部类优化

public class Test02 {

public static void main(String[] args) {

TreeSet set2 = new TreeSet(new Comparator() {

@Override

public int compare(String o1, String o2) {

return o1.length() - o2.length();

}

});

set2.add("banana");

set2.add("coco");

set2.add("apple");

set2.add("apple");

System.out.println(set2);

}

}

Map接口

Map接口称为键值对集合或者映射集合,其中的元素(entry)是以键值对(key-value)的形式存在。

Map 容器接口中提供了增、删、改、查的方式对集合进行操作。

Map接口中都是通过key来操作键值对,一般key是已知。通过key获取value。

map常用方法

public static void main(String[] args) {

/**

* 增:put/putAll

* 删:clear/remove

* 改:put

* 查:get/containsKey/containsValue

* 其他:isEmpty/size

*/

Map map = new HashMap();

// 【1】put

map.put("A", "apple");

map.put("B", "banana");

map.put("C", "coco");

// 【2】删除

// map.clear();

// smap.remove("A");

// 【3】修改

//map.put("A", "apple x");

// 【4】查看

String val = map.get("A");

System.out.println(map.containsKey("D"));

System.out.println(map);

}

map接口的遍历

通过keySet() 返回map中键的set集合。

public static void main(String[] args) {

Map map = new HashMap();

map.put("B", "banana");

map.put("A", "apple");

map.put("C", "coco");

// map无序

// 可以根据key的自然顺序 让map有序=>一般用string作为key

System.out.println(map);

// 遍历

Set keys = map.keySet();

for (String key : keys) {

System.out.println(key+"=>"+map.get(key));

}

Iterator it = keys.iterator();

while(it.hasNext()) {

String key = it.next();

System.out.println(key+"=>"+map.get(key));

}

}

Iterator it = keys.iterator();

while(it.hasNext()) {

String key = it.next();

System.out.println(key+"=>"+map.get(key));

}

}

map中以键值对作为元素,键值对在map中称为entry,entrySet返回键值对的set集合。

public static void main(String[] args) {

Map map = new HashMap();

map.put("B", "banana");

map.put("A", "apple");

map.put("C", "coco");

// map无序

// 可以根据key的自然顺序 让map有序=>一般用string作为key

System.out.println(map);

// entrySet

Set> entrySet = map.entrySet();

for (Entry entry : entrySet) {

System.out.println(entry.getKey()+"=>"+entry.getValue());

}

Iterator> it2 = entrySet.iterator();

while(it2.hasNext()) {

Entry entry = it2.next();

System.out.println(entry.getKey()+"=>"+entry.getValue());

}

}

Map接口的实现类HashMap、LinkedHashMap、TreeMap

HashMap

HashMap 是Map的实现类,key以HashSet存储。

总结:

[1] 向HashMap中存储元素时,key一定要实现hashCode和equals

[2] 一般建议使用String作为Map接口的key

LinkedHashMap

LinkedHashMap是Map接口的实现类,key以LinkedHashSet存储。

哈希表散列key,链表维持key的添加顺序。

TreeMap

TreeMap是Map的实现类,key以TreeSet存储。

public static void main(String[] args) {

/*TreeMap map = new TreeMap(new Comparator() {

@Override

public int compare(String o1, String o2) {

return o1.length() - o2.length();

}

});

ArrayList list2 = new ArrayList();

list2.add("ben");

list2.add("bill");

map.put("Aa", list2);

ArrayList list1 = new ArrayList();

list1.add("alex");

list1.add("alice");

list1.add("allen");

map.put("B", list1);

System.out.println(map);*/

TreeMap map = new TreeMap(new Comparator() {

@Override

public int compare(Student o1, Student o2) {

return o1.getAge() - o2.getAge();

}

});

ArrayList list1 = new ArrayList();

list1.add("alex");

list1.add("alice");

list1.add("allen");

Student s1 = new Student("001", "大狗", 20);

map.put(s1, list1);

ArrayList list2 = new ArrayList();

list2.add("ben");

list2.add("bill");

Student s2 = new Student("001", "2狗", 20);

// 修改

map.put(s2, list2);

System.out.println(map);

}

Collection集合

|

1 List 接口          2、Set接口

|(有序可重复)       |(无序 唯一)

1 ArrayList  2 Vector  3 LinkList          1 HashSet   2  LinkHashSet   3  TreeSet

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值