Java集合框架(二)
Set
Set:无序,不可以重复元素。
|--------HashSet:数据结构是哈希表。
线程是非同步的。保证元素唯一性的原理是:判断元素的hashCode值是否相同,如果相同,还会继续判断元素的equals方法,是否为true
|--------TreeSet:可以对Set集合中元素进行排序。
底层数据结构是二叉树(也叫红黑树),保证元素唯一性的依据是:compareTo()方法return 0。
TreeSet排序的第一种方式:让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo()方法。这种方式也称为元素的自然顺序,或者也叫默认顺序。
TreeSet排序的第二种方式:当元素自身不具备比较性时,或者具备的比较性不是所需要的,这是就需要让集合自身具备比较性。在集合一初始化时,就具备比较方式。
例,需求:往TreeSet集合中存储自定义对象学生。想按照学生的年龄进行排序。
int compareTo(T o):比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
代码如下:
import java.util.Iterator;
import java.util.TreeSet; public class TreeSetDemo { public static void sop(Object obj) {
System.out.println(obj);
} public static void main(String[] args) {
TreeSet ts = new TreeSet(); ts.add(new Student("lisi02", 22));
ts.add(new Student("lisi007", 20));
ts.add(new Student("lisi09", 19));
ts.add(new Student("lisi08", 19));
//ts.add(new Student("lisi02", 22)); Iterator it = ts.iterator(); while(it.hasNext()) {
Student stu = (Student)it.next();
sop(stu.getName()+"...."+stu.getAge());
} } }
class Student implements Comparable {//该接口强制让学生具备比较性
private String name;
private int age; Student(String name, int age) {
this.name = name;
this.age = age;
} public int compareTo(Object obj) { //return 0; if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student s = (Student)obj; System.out.println(this.name+"....compareTo...."+s.name);
if(this.age > s.age)
return 1;
if(this.age == s.age)
return this.name.compareTo(s.name);
return -1; } public String getName() {
return name;
} public int getAge() {
return age;
}
}
记住,排序时,当主要条件相同时,一定判断一下次要条件。
当元素自身不具备比较性时,或者具备的比较性不是所需要的,这时就需要让容器自身具备比较性。定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。定义一个类实现Comparator接口,覆盖compare()方法。
当两种排序都存在时,以比较器为主。
int compare(T o1, T o2):比较用来排序的两个参数。根据第一个参数小于、等于或大于第二个参数分别返回负整数、零或正整数。
示例代码如下:
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet; public class TreeSetDemo1 {
public static void sop(Object obj) {
System.out.println(obj);
} public static void main(String[] args) {
TreeSet ts = new TreeSet(new MyCompare()); ts.add(new Student1("lisi02", 22));
ts.add(new Student1("lisi007", 20));
ts.add(new Student1("lisi09", 19));
ts.add(new Student1("lisi06", 18));
ts.add(new Student1("lisi007", 29));
ts.add(new Student1("lisi06", 18));
//ts.add(new Student("lisi02", 22)); Iterator it = ts.iterator(); while(it.hasNext()) {
Student1 stu = (Student1)it.next();
sop(stu.getName()+"...."+stu.getAge());
}
} }
class MyCompare implements Comparator { @Override
public int compare(Object o1, Object o2) {
Student1 s1 = (Student1)o1;
Student1 s2 = (Student1)o2; int num = s1.getName().compareTo(s2.getName());
if(num == 0) {
/*
if(s1.getAge() > s2.getAge()) {
return 1;
}
if(s1.getAge() == s2.getAge()) {
return 0;
}
return -1;
*/
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
}
return num; } }
class Student1 implements Comparable {//该接口强制让学生具备比较性
private String name;
private int age; Student1(String name, int age) {
this.name = name;
this.age = age;
} public int compareTo(Object obj) { //return 0; if(!(obj instanceof Student1))
throw new RuntimeException("不是学生对象");
Student1 s = (Student1)obj; System.out.println(this.name+"....compareTo...."+s.name);
if(this.age > s.age)
return 1;
if(this.age == s.age)
return this.name.compareTo(s.name);
return -1; } public String getName() {
return name;
} public int getAge() {
return age;
}
}
练习:按照字符串长度排序。
分析:字符串本身具备比较性,但是它的比较方式不是所需要的,这时就只能使用比较器。
示例代码如下:
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet; class StringLengthComparator implements Comparator { @Override
public int compare(Object o1, Object o2) {
String s1 = (String) o1;
String s2 = (String) o2;
/*
if(s1.length() > s2.length()) {
return 1;
}
if(s1.length() == s2.length()) {
return 0;
}
*/
int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
if(num == 0) {
return s1.compareTo(s2); //如果两个字符串的长度相同,再按他俩的字典顺序排序。
}
return num;
} }
public class TreeSetTest { public static void main(String[] args) {
TreeSet ts = new TreeSet(new StringLengthComparator()); ts.add("abcd");
ts.add("cc");
ts.add("cba");
ts.add("aaa");
ts.add("z");
ts.add("hahaha"); Iterator it = ts.iterator(); while(it.hasNext()) {
System.out.println(it.next());
}
} }
泛型
泛型:JDK1.5版本以后出现的新特性。用于解决安全问题,是一个类型安全机制。
泛型的好处:
- 将运行时期出现的问题ClassCastException,转移到了编译时期,方便于程序员解决问题,让运行时期问题减少,安全。
- 避免了强制转换的麻烦。
泛型格式:通过<>来定义要操作的引用数据类型。
问:在使用java提供的对象时,什么时候写泛型呢?
答:通常在集合框架中很常见,只要见到<>就要定义泛型。其实<>就是用来接收类型的。当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。
示例代码如下:
import java.util.ArrayList;
import java.util.Iterator; public class GenericDemo { public static void main(String[] args) { ArrayList<String> al = new ArrayList<String>(); al.add("abc01");
al.add("abc0991");
al.add("abc014"); //al.add(4);//al.add(new Integer(4)); Iterator<String> it = al.iterator();
while(it.hasNext()) {
String s = it.next();
System.out.println(s + ":" + s.length());
}
} }
练习:按照字符串长度排序。
代码:
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet; class LenComparator implements Comparator<String> { @Override
public int compare(String arg0, String arg1) {
int num = new Integer(arg0.length()).compareTo(new Integer(arg1.length())); if(num == 0)
return arg0.compareTo(arg1);//如果两个字符串的长度相同,再按他俩的字典顺序排序。 return num;
} }
public class GenericDemo1 { public static void main(String[] args) {
TreeSet<String> ts = new TreeSet<String>(new LenComparator()); ts.add("abcd");
ts.add("cc");
ts.add("cba");
ts.add("aaa");
ts.add("z");
ts.add("hahaha"); Iterator<String> it = ts.iterator(); while(it.hasNext()) {
String s = it.next();
System.out.println(s);
}
} }
什么时候定义泛型类?
当类中要操作的引用数据类型不确定的时候,早期定义Object来完成扩展。现在定义泛型来完成扩展。
如:
class Worker { } class Stud { }
//泛型前做法
class Tool {
private Object object; public void setObject(Object object) {
this.object = object;
} public Object getObject() {
return object;
}
}
//什么时候定义泛型类?
//当类中要操作的引用数据类型不确定的时候,早期定义Object来完成扩展。
//现在定义泛型来完成扩展。
class Utils<QQ> {
private QQ q; public void setObject(QQ q) {
this.q = q;
} public QQ getObject() {
return q;
} }
public class GenericDemo2 { public static void main(String[] args) {
Utils<Worker> u = new Utils<Worker>();
u.setObject(new Worker());
Worker w = u.getObject(); /*
Tool t = new Tool();
t.setObject(new Stud());
Worker w = (Worker)t.getObject();
*/
} }
泛型方法
泛型类定义的泛型,在整个类中有效。如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。为了让不同方法可以操作不同类型,而且类型还不确定,那么可以将泛型定义在方法上。
特殊之处:静态方法不可以访问类上定义的泛型。
如果静态方法操作的引用数据类型不确定,可以将泛型定义在方法上。
示例代码:
/*
class DemoG<T> {
public void show(T t) {
System.out.println("show:" + t);
} public void print(T t) {
System.out.println("print:" + t);
} }
*/
//泛型类定义的泛型,在整个类中有效。如果被方法使用,
//那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。
//为了让不同方法可以操作不同类型,而且类型还不确定,那么可以将泛型定义在方法上。 /*
特殊之处:静态方法不可以访问类上定义的泛型。
如果静态方法操作的引用数据类型不确定,可以将泛型定义在方法上。
*/ class DemoG<T> {
public void show(T t) {
System.out.println("show:" + t);
}
//泛型方法
public <Q> void print(Q q) {
System.out.println("print:" + q);
}
//静态泛型方法
public static <W> void method(W t) {
System.out.println("method:" + t);
}
}
public class GenericDemo3 { public static void main(String[] args) {
DemoG<String> d1 = new DemoG<String>();
d1.show("haha");
//d1.show(4);
d1.print(4);
d1.print("hello");
DemoG.method("hahahha"); /*
DemoG d = new DemoG();
d.show("haha");
d.show(new Integer(4)); d.print("heihei");
*/
/*
DemoG<Integer> d = new DemoG<Integer>();
d.show(new Integer(4));
d.print("haha"); DemoG<String> d1 = new DemoG<String>();
d1.print("haha");
d1.show(5);
*/
}
}
泛型接口
示例代码:
//泛型定义在接口上
interface Inter<T> {
void show(T t);
}
/*
泛型接口的第一种实现方式:
class InterImpl implements Inter<String> {
public void show(String t) {
System.out.println("show:" + t);
}
}
*/ /*
泛型接口的第二种实现方式:
*/
class InterImpl<T> implements Inter<T> { @Override
public void show(T t) {
System.out.println("show:" + t);
} }
public class GenericDemo4 { public static void main(String[] args) {
InterImpl<Integer> i = new InterImpl<Integer>();
i.show(4); //InterImpl i = new InterImpl();
//i.show("haha");
} }
泛型的限定
?:通配符,也可以理解为占位符。
泛型的限定:
- ? extends E:可以接收E类型或者E类型的子类型,上限。
- ? super E:可以接收E类型或者E的父类型,下限。
示例代码如下:
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator; class PersonG {
private String name; public PersonG(String name) {
this.name = name;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} } class StudentG extends PersonG {
public StudentG(String name) {
super(name);
}
} public class GenericDemo5 { public static void main(String[] args) {
/*
ArrayList<String> al = new ArrayList<String>(); al.add("abc1");
al.add("abc2");
al.add("abc3"); ArrayList<Integer> al1 = new ArrayList<Integer>(); al1.add(4);
al1.add(7);
al1.add(1); printColl(al);
printColl(al1);
*/
ArrayList<PersonG> al = new ArrayList<PersonG>(); al.add(new PersonG("abc1"));
al.add(new PersonG("abc2"));
al.add(new PersonG("abc3"));
//printColl(al); ArrayList<StudentG> al1 = new ArrayList<StudentG>(); al1.add(new StudentG("abc---1"));
al1.add(new StudentG("abc---2"));
al1.add(new StudentG("abc---3")); printColl(al1);// ArrayList<PersonG> al = new ArrayList<StudentG>();error----泛型中无法向上转型
} public static void printColl(ArrayList<? extends PersonG> al) {//ArrayList<String> al = new ArrayList<Integer>(); error
Iterator<? extends PersonG> it = al.iterator(); while(it.hasNext()) {
System.out.println(it.next().getName());
}
} /*
public static <T> void printColl_1(ArrayList<T> al) {//ArrayList<String> al = new ArrayList<Integer>(); error
Iterator<T> it = al.iterator(); while(it.hasNext()) {
T t = it.next();//可以接收T类型并操作
System.out.println(t);
}
} public static void printColl(ArrayList<?> al) {//ArrayList<String> al = new ArrayList<Integer>(); error
Iterator<?> it = al.iterator(); while(it.hasNext()) {
System.out.println(it.next());
//System.out.println(it.next().length());//不能使用类型特有方法:length()
}
}
*/
}
现在重点讲解泛型的下限。通过如下代码示例说之:
泛型的下限的应用举例:
TreeSet(Comparator<? super E> comparator)
//伪代码:
class PersonG {
private String name; public PersonG(String name) {
this.name = name;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} } class StudentG extends PersonG {
public StudentG(String name) {
super(name);
}
}
class StudentG implements Comparable<PersonG> {//<? super E> @Override
public int compareTo(PersonG arg0) { return 0;
} } class Comp implements Comparator<PersonG> {//可以接收StudentG,也可以接收StudentG的父类型PersonG @Override
public int compare(PersonG arg0, PersonG arg1) { PersonG arg0 = new StudentG("abc---1");
return arg0.getName().compareTo(arg1.getName());
} } TreeSet<StudentG> ts = new TreeSet<StudentG>(new Comp());
ts.add(new StudentG("abc---1"));
ts.add(new StudentG("abc---2"));
ts.add(new StudentG("abc---3"));
现示例说明:
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet; class PersonGe {
private String name; public PersonGe(String name) {
this.name = name;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} } class StudentGe extends PersonGe {
public StudentGe(String name) {
super(name);
}
} class WorkerGe extends PersonGe {
public WorkerGe(String name) {
super(name);
}
}
/*
class StuComp implements Comparator<StudentGe> { @Override
public int compare(StudentGe s1, StudentGe s2) { return s1.getName().compareTo(s2.getName());
} }
class WorkerComp implements Comparator<WorkerGe> { @Override
public int compare(WorkerGe s1, WorkerGe s2) { return s1.getName().compareTo(s2.getName());
} }
*/
class Comp implements Comparator<PersonGe> { @Override
public int compare(PersonGe p1, PersonGe p2) {
return p2.getName().compareTo(p1.getName());//局限性:只能用父类型的方法
} }
public class GenericDemo6 { public static void main(String[] args) { TreeSet<StudentGe> ts = new TreeSet<StudentGe>(new Comp());
ts.add(new StudentGe("abc03"));
ts.add(new StudentGe("abc02"));
ts.add(new StudentGe("abc06"));
ts.add(new StudentGe("abc01")); Iterator<StudentGe> it = ts.iterator(); while(it.hasNext()) {
System.out.println(it.next().getName());
} TreeSet<WorkerGe> ts1 = new TreeSet<WorkerGe>(new Comp());
ts1.add(new WorkerGe("wabc--03"));
ts1.add(new WorkerGe("wabc--02"));
ts1.add(new WorkerGe("wabc--06"));
ts1.add(new WorkerGe("wabc--01"));
Iterator<WorkerGe> it1 = ts1.iterator(); while(it1.hasNext()) {
System.out.println(it1.next().getName());
} } }
Java集合框架(二)的更多相关文章
- (Set, Map, Collections工具类)JAVA集合框架二
Java集合框架部分细节总结二 Set 实现类:HashSet,TreeSet HashSet 基于HashCode计算元素存放位置,当计算得出哈希码相同时,会调用equals判断是否相同,相同则拒绝 ...
- java 集合框架(二)Iterable接口
Iterable接口是java 集合框架的顶级接口,实现此接口使集合对象可以通过迭代器遍历自身元素,我们可以看下它的成员方法 修饰符和返回值 方法名 描述 Iterator<T> iter ...
- (二)java集合框架综述
一集合框架图 说明:对于以上的框架图有如下几点说明 1.所有集合类都位于java.util包下.Java的集合类主要由两个接口派生而出:Collection和Map,Collection和Map是Ja ...
- Java集合框架源码(二)——hashSet
注:本人的源码基于JDK1.8.0,JDK的版本可以在命令行模式下通过java -version命令查看. 在前面的博文(Java集合框架源码(一)——hashMap)中我们详细讲了HashMap的原 ...
- 【集合框架】Java集合框架综述
一.前言 现笔者打算做关于Java集合框架的教程,具体是打算分析Java源码,因为平时在写程序的过程中用Java集合特别频繁,但是对于里面一些具体的原理还没有进行很好的梳理,所以拟从源码的角度去熟悉梳 ...
- Java集合框架的总结
本篇文章先从整体介绍了Java集合框架包含的接口和类,然后总结了集合框架中的一些基本知识和关键点,并结合实例进行简单分析.当我们把一个对象放入集合中后,系统会把所有集合元素都当成Object类的实例进 ...
- 浅谈JAVA集合框架
浅谈JAVA集合框架 Java提供了数种持有对象的方式,包括语言内置的Array,还有就是utilities中提供的容器类(container classes),又称群集类(collection cl ...
- 【JAVA集合框架之工具类】
一.概述 JAVA集合框架中有两个很重要的工具类,一个是Collections,另一个是Arrays.分别封装了对集合的操作方法和对数组的操作方法,这些操作方法使得程序员的开发更加高效. public ...
- 【JAVA集合框架之Map】
一.概述.1.Map是一种接口,在JAVA集合框架中是以一种非常重要的集合.2.Map一次添加一对元素,所以又称为“双列集合”(Collection一次添加一个元素,所以又称为“单列集合”)3.Map ...
随机推荐
- swift学习初步(四)-- 函数
好了,让我们开始接着前几天写的系列博客开始今天的这篇博客.在swift里面如果你需要定义一个方法的话,你需要使用关键字:func,请看下面的这段代码: func sayHello(name:Strin ...
- Partition分组使用和行列转换
CREATE TABLE score ( name NVARCHAR(20), subject NVARCHAR(20), score INT ) --2.插入测试数据 INSERT INTO sco ...
- OC中NSDictionary(字典)、NSMutableDictionary(可变字典)、NSSet(集合)、NSMutableSet(可变集合)得常用方法
字典用于保存具有映射关系数据的集合 一个key—value对认为是一个条目(entry),字典是存储key—value对的容器 与数组不同,字典靠key存取元素 key不能重复,value必须是对象 ...
- GNU make 总结 (一)
make的执行依赖于一个makefile文件,该文件告诉make应该如何执行编译和链接操作.make通过比较对应文件的最后修改时间来决定哪些文件需要更新.make工具主要用来进行工程编译和程序链接操作 ...
- iOS开发HTTPS实现之信任SSL证书和自签名证书
iOS开发HTTPS实现之信任SSL证书和自签名证书 转自:http://www.jianshu.com/p/6b9c8bd5005a/comments/5539345 (收录一下供自己学习用的) 字 ...
- java使用ms-dos编译,运行程序
1.安装好JDK,并配置好环境变量. 2.编辑好源程序,如Test.java public class Test{ public static void main(String[] args){ Sy ...
- 向Array中添加堆排序
堆排序思路 堆排序是一种树形选择排序方法(注意下标是从1开始的,也就是R[1...n]). 1) 初始堆: 将原始数组调整成大根堆的方法——筛选算法:比较R[2i].R[2i+1]和R[i],将最大者 ...
- Python中的高阶函数与匿名函数
Python中的高阶函数与匿名函数 高阶函数 高阶函数就是把函数当做参数传递的一种函数.其与C#中的委托有点相似,个人认为. def add(x,y,f): return f( x)+ f( y) p ...
- Grails 1.2参考文档速读(10):Controller
转载:http://keyvalue.blog.51cto.com/1475446/303260 从本篇起,我们将开始进入Grails的Web层,首先让我们从Controller说起. G ...
- Slim + Twig 构建PHP Web应用程序
Twig : PHP 视图模板引擎,类似于Smart模板引擎. 下载地址:http://twig.sensiolabs.org/ Slim: 轻量级PHP MVC框架,可用于构建Web app,Res ...