黑马程序员_集合框架(二)

时间:2023-02-19 17:28:06

——- android培训java培训、期待与您交流! ———-
set集合
一:set集合的特点
1、元素是无序的。(存入和取出的顺序不一定一致)
2、元素不可以重复。
3、set集合的功能和collection是一样的。
4、数值唯一。
二:set集合中常见的子类
1、HashSet
底层数据结构式哈希表,是通过元素的hashcode和equals来保证元素的唯一性。
如果元素的hashcode值相同,才会判断equals是否为true;
如果元素的hashcode的值不同,不会调用equals。
对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashcode和equals方法。
线程是非同步的。

package set;

public class HashSetDemo {
public int hashCode()
{
return 60;
}
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[] args)
{
{
HashSetDemo d1 = new HashSetDemo();
HashSetDemo d2 = new HashSetDemo();
sop(d1);
sop(d2);

}


}

结果为:
黑马程序员_集合框架(二)

package set;

import java.util.HashSet;
import java.util.Iterator;

public class set01 {
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[] args)
{
HashSet hs = new HashSet();
sop(hs.add("java01"));
sop(hs.add("java01"));
hs.add("java03");
hs.add("java04");
hs.add("java05");
Iterator it = hs.iterator();
while(it.hasNext())
{
sop(it.next());
}

}

}

结果为:
黑马程序员_集合框架(二)

package set;

import java.util.HashSet;
import java.util.Iterator;

//往hashset集合中存入自定义对象
//姓名和年龄相同为同一个人,重复元素
public class set02 {
public static void sop(Object obj) {
System.out.println(obj);
}

public static void main(String[] args) {
HashSet hs = new HashSet();

hs.add(new Person("al", 11));
hs.add(new Person("a2", 12));
hs.add(new Person("a3", 13));
hs.add(new Person("a4", 14));

Iterator it = hs.iterator();
while (it.hasNext()) {
Person p = (Person) it.next();
sop(p.getName() + "::" + p.getAge());
}
}

}

class Person {
private String name;
private int age;

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

public String getName() {
return name;
}

public int getAge() {
return age;
}

}

2、TreeSet
TreeSet使用 :

使用:
TreeSet ts=new TreeSet();
ts.add();

Iterator it=ts.iterator();
while(it.hasNext){
it.next();
}

TreeSet存储自定义对象:往TreeSet集合中存储自定义对象,根据学生年龄进行排序。

排序方式一:让元素具备比较性
要让自定义对象是实现 Comparable接口,强制让对象具有比较性。,排序时当主要条件相同时,一定要判断下次要条件。
然后重写compareTo()方法。
例:

public int compareTo(Object obj)
{
if(!obj instanceof Student)
throw new RuntimeException("不是学生");
Student s=(Student)obj;

if(this.age>s.age)
return 1;
if(this.age==s.age)
return this.name.compareTo(s.name);
return -1;
}

排序方式二:定义一个类实现comparator接口,覆盖compare方法。让集合具备比较性

TreeSet ts=new TreeSet(new MyCompare());

class MyCompare implements Comparator

public int compare(Object o1,Object O2)
{

Student s1=(Student)o1;
Student s2=(Student)O2;

int num=s1.getName().compareTo(S2.getname());
if(num==0)
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));

}

                ****泛型****

一:泛型概念讲解
泛型:1.5后出现的新特性,解决了安全问题,是一个类型安全机制。
好处:
1.将运行时期转移到编译时期,方便程序员解决问题。提高了安全性。
2.避免了强制转换的麻烦
ArrayList 泛型语法
Iterator
格式:通过<>来定义要操作的引用数据类型。
什么时候使用泛型?
在集合中很常见,只要见到<>就要定义泛型。
<>是用来接收数据类型的泛型技术:其实应用在编译时期,是给编译器使用的技术,到了运行时期,泛型就不存在了。?
为什么??因为泛型的擦除:也就是说,编辑器检查了泛型的类型正确后,在生成的类文件中是没有泛型的。?
在运行时,如何知道获取的元素类型而不用强转呢??
泛型的补偿:因为存储的时候,类型已经确定了是同一个类型的元素,所以在运行时,只要获取到该元素的类型,
在内部进行一次转换即可,所以使用者不用再做转换动作了。
二:泛型类
泛型类
什么时候定义泛型类?
当类中操作的引用数据类型不确定的时候,
早起定义Object来完成扩展。
现在定义泛型来完成扩展。

class Utils<QQ>
{
private QQ q;
public void setObject(QQ q);
{
this.q=q;

}
public QQ gerobject()
{
return q;

}

}

三:泛型方法:
泛型方法:
泛型类定义的反应,在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。
为了让不同方法可以操作不同类型,而且类型还不确定,那么可以将泛型定义在方法上。

class Demo
{
public <T> void show(T t)
{

}


}

静态方法泛型:静态方法不可以访问类上定义的泛型,如果静态方法操作的数据类型不确定,可以将泛型定义在方法上。

public static void menthod(W w){}

泛型接口:

interface Inter<T>
{

void show(T t);
}

class InterImpl<R> implements Inter<R>
{

public void show(R r)
{
System.out.println("show:"+r);
}
}

案例:给限定Integer类型的集合 添加 String类型

ArrayList<Integer> collection2 = new ArrayList<Integer>(); 
System.out.println(collection1.getClass()==collection2.getClass());
collection2.add(“真暴力”);//这句会报错
collection2.getClass().getMethod("add", Object.class).invoke(collection2, "真暴力");
System.out.println(collection2.get(0)); //结果却为真暴力
//已经限制集合中元素的类型为Integer,可用反射却能将String存入,为什么? 这是因为泛型是给编译器用的,运行时就没有这些泛型信息了,这叫做“去泛型化”,所以可以通过反射,获取集合字节码加入非指定的类型。
}
}