Java编程思想:泛型方法
import java.util.*;
public class Test {
public static void main(String[] args) {
// GenericMethods.test();
// GenericVarargs.test();
BasicGeneratorDemo.test();
}
}
/*
如论合适,如果使用泛型方法可以取代将整个类泛型化,那么就应该只使用泛型方法
因为它可以使事情更清楚明白。另外,对于一个static的方法而言,无法访问泛型类
的类型参数,所以,如果static方法需要使用泛型的能力,就必须使其成为泛型方法
*/
class GenericMethods {
public <T> void f(T x) {
System.out.println(x.getClass().getName());
}
public static void test() {
GenericMethods gm = new GenericMethods();
// gm.f("");
// gm.f(1);
// gm.f(1.0);
// gm.f('c');
// gm.f(gm);
gm.f(New.map());
}
}
/*
需求:
利用方法的推导功能,简化我们创建集合类时的编码,但是这个工作
现在已经不需要了,因为IDE和编译器都可以满足自动推导的功能。
*/
class New {
public static <K,V> Map<K,V> map() {
return new HashMap<>();
}
}
/*
类型推导只对赋值操作有效果,其他时候并不起作用。如果你将一个泛型方法
调用的结果(例如New.map())作为参数,传递给另一个方法时,这时候编译
器并不会执行类型推导。这种情况下,编译器认为:调用泛型方法后,其返回值
被赋给了一个Object类型的变量
——现在好像可以哦
*/
class LimtsOfInference {
static void f(Map<String, List<? extends Map>> arg) {
}
static void test() {
f(New.map());
}
}
/*
泛型方法中,显式指明类型的语法。要显式指明类型,必须在点操作符
与方法名之间插入尖括号,然后把类型置于尖括号内。
——这些知识点,有点不适用了,现在
*/
class LimtsOfInference2 {
static void f(Map<String, List<? extends Map>> arg) {
}
static void test() {
f(New.<String,List<? extends Map>>map());
}
}
/*
15.4.2 可变参数与泛型方法
*/
class GenericVarargs {
public static <T> List<T> makeList(T... args) {
List<T> result = new ArrayList<>();
for (T item : args) {
result.add(item);
}
return result;
}
static void test() {
List<String> ls = makeList("A");
System.out.println(ls);
ls = makeList("A", "B", "C");
System.out.println(ls);
ls = makeList("adfasdfsafsdf".split(""));
System.out.println(ls);
}
}
/*
15.4.3 用于Generator的泛型方法
*/
interface Generator<T>{
T next();
}
class Generators {
//给我一个容器,给我一个生成器,我帮你把容器填满,只省下了几行for循环的代码
public static <T> Collection<T> fill(Collection<T> coll, Generator<T> gen, int len) {
; i < len; i++) {
coll.add(gen.next());
}
return coll;
}
}
/*
15.4.4 一个同游的Generator
下面的程序,可以为任何类构造一个Generator,只要该类具有默认的构造器,为了
减少类型的声明,它提供了一个泛型的方法,用于生成BasicGenerator。我感觉我
上一个小节的代码,也可以为任何类构造了一个Generator啊
我觉得真正的区别会在这儿,以往的Generator,是需要自己去实现next()部分的
代码的,而这个Generator却不用,你传给它一个Class对象,它就能为你生成许多
个对象,是真正意义上的简化了操作
*/
class BasicGenerator<T> implements Generator<T> {
private Class<T> type;
public BasicGenerator(Class<T> type) {
this.type = type;
}
@Override
public T next() {
try {
return type.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
public static <T> Generator<T> create(Class<T> type) {
return new BasicGenerator<>(type);
}
}
class CounterObject {
;
private final long id = counter++;
public long id() {
return id;
}
public String toString() {
return "Counted Object "+id;
}
}
class BasicGeneratorDemo {
static void test() {
Generator<CounterObject> g = BasicGenerator.create(CounterObject.class);
; i < ; i++) {
System.out.println(g.next());
}
}
}
/*
15.4.5 简化元组的使用
*/
class TwoTuple<A, B> {
public final A first;
public final B second;
public TwoTuple(A first, B second) {
this.first = first;
this.second = second;
}
public String toString() {
return "(" + first + "," + second + ")";
}
}
/*
这个方案只是在创建的时候,给简化了一下,统一了一下创建的接口
*/
class Tuple {
public static <A, B> TwoTuple<A, B> tuple(A a, B b) {
return new TwoTuple<>(a, b);
}
}
/*
问题:
方法f()返回一个参数化的TwoTuple对象,而f2()返回的是非参数化的
TwoPuple对象。在这个例子中,编译器并没有f2()的警告信息,因为我们
并没有将其返回值作为参数化对象使用。在某种意义上,它被“向上转型”为
一个非参数化的TwoTuple。然而,如果试图将f2()的返回值转型为参数化
的TwoTuple,编译器就会发出警告
——有点尴尬,参数化其实就是指的泛型化
*/
class TupleTest {
static TwoTuple<String, String> f() {
return Tuple.tuple("AAA","BBB");
}
static TwoTuple f2() {
return Tuple.tuple("BBB","CCC");
}
static void test(){}
}
/*
15.4.6 一个Set实用工具
需求:
用Set表示集合的各种关系,如交集、并集、、补集
*/
class Sets {
public static <T> Set<T> union(Set<T> a, Set<T> b) {
Set<T> result = new HashSet<>(a);
a.addAll(b);
return result;
}
public static <T> Set<T> intersection(Set<T> a, Set<T> b) {
Set<T> result = new HashSet<>(a);
result.retainAll(b);
return result;
}
public static <T> Set<T> difference(Set<T> superset, Set<T> subset){
Set<T> result = new HashSet<>(superset);
result.retainAll(subset);
return result;
}
public static <T> Set<T> complement(Set<T> a, Set<T> b) {
return difference(union(a,b),intersection(a,b));
}
}
enum Letters{
A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z
}
/*
EnumSet:
用来从enum直接创建Set,在这儿,我们向static方法EnumSet.range()传入某个范围的
第一个元素和最后一个元素,然后它将返回一个Set,其中包括该范围内的所有元素
*/
class LettersDemo {
static void test() {
/*
我看案例中,有一个import static.generics.watercolors.Watercolos.*
又看到他解释说:为了方便起见(可以直接使用enum中的元素名),下面的实例以
static的方式引入Watercolors。
——这种写法,我从来没有用过,标记一下
*/
Set<Letters> l1 = EnumSet.range(Letters.A, Letters.D);
//。。。
}
}
Java编程思想:泛型方法的更多相关文章
- Java编程思想(11~17)
[注:此博客旨在从<Java编程思想>这本书的目录结构上来检验自己的Java基础知识,只为笔记之用] 第十一章 持有对象 11.1 泛型和类型安全的容器>eg: List<St ...
- 《Java编程思想》读书笔记
前言 这个月一直没更新,就是一直在读这本<Java编程思想>,这本书可以在Java业界被传神的一本书,无论谁谈起这本书都说好,不管这个人是否真的读过这本书,都说啊,这本书很好.然后再看这边 ...
- Java编程思想(后)
Java编程思想(后) 持有对象 如果一个程序只包含固定数量的且其生命期都是已知的对象,那么这是一个非常简单的程序. Java中的库基本类型: List, Set, Queue和Map --- 称为集 ...
- Java中的泛型 --- Java 编程思想
前言 我一直都认为泛型是程序语言设计中一个非常基础,重要的概念,Java 中的泛型到底是怎么样的,为什么会有泛型,泛型怎么发展出来的.通透理解泛型是学好基础里面中非常重要的.于是,我对<Ja ...
- JAVA编程思想——分析阅读
需要源码.JDK1.6 .编码风格参考阿里java规约 7/12开始 有点意识到自己喜欢理论大而泛的模糊知识的学习,而不喜欢实践和细节的打磨,是因为粗心浮躁导致的么? cron表达式使用 设计能力.领 ...
- Java编程思想 笔记
date: 2019-09-06 15:10:00 updated: 2019-09-24 08:30:00 Java编程思想 笔记 1. 四类访问权限修饰词 \ 类内部 本包 子类 其他包 publ ...
- 《Java编程思想》读书笔记(二)
三年之前就买了<Java编程思想>这本书,但是到现在为止都还没有好好看过这本书,这次希望能够坚持通读完整本书并整理好自己的读书笔记,上一篇文章是记录的第一章到第十章的内容,这一次记录的是第 ...
- JAVA编程思想(第四版)学习笔记----4.8 switch(知识点已更新)
switch语句和if-else语句不同,switch语句可以有多个可能的执行路径.在第四版java编程思想介绍switch语句的语法格式时写到: switch (integral-selector) ...
- 《Java编程思想》学习笔记(二)——类加载及执行顺序
<Java编程思想>学习笔记(二)--类加载及执行顺序 (这是很久之前写的,保存在印象笔记上,今天写在博客上.) 今天看Java编程思想,看到这样一道代码 //: OrderOfIniti ...
- #Java编程思想笔记(一)——static
Java编程思想笔记(一)--static 看<Java编程思想>已经有一段时间了,一直以来都把笔记做在印象笔记上,今天开始写博客来记录. 第一篇笔记来写static关键字. static ...
随机推荐
- C#如何将十六进制数字符串转byte[]?
代码: /// <summary> /// 16进制原码字符串转字节数组 /// </summary> /// <param name="hexString&q ...
- CROSS JOIN
原文:CROSS JOIN 最近在讲到T-SQL查询的Join部分时,一下子没有想起来CROSS JOIN的用法,因为其实平常也确实基本不用到.特意找了一个例子,以供参考 CROSS JOIN又称为笛 ...
- Chinese Messy Code of String
It's very strange that I found the messy code.I 've never seen this before. this is the java code: / ...
- 【Qt】一劳永逸解决UAC问题(修改mkspecs\win32-msvc2012\qmake.conf)
如果你的程序跑在一个开启了UAC保护的系统中,而你的程序又没有"盾牌"的话,程序总是会受到各种阻挠的,比如读写文件,写注册表等. 有了"盾牌"的话就不会出现一些 ...
- 关于qtcreator+vs2008+CDB调试太卡的问题研究(载入符号表,以及VS调试器的注册表信息)
在刚接触Qt时,对于较大的项目,用qtcreator + vs + cdb 调试时,启动很慢并且单步运行时也经常会出现卡住半分钟以上的情况,一直没有解决.在需要debug的时候大多会在vs2008上安 ...
- 深入windows的关机消息截获-从XP到Win7的变化(在XP中程序可以阻止关机,但是在Win7中程序无法阻止关机,可Block的时间从1秒调到了5秒) good
之前写了一个软件用于实验室的打卡提醒,其中一个重要的功能是在关机之前提醒当天晚上是否已经打卡.之前我是在WM_ENDSESSION中弹出一个模态对话框来提醒,在XP中基本工作正常,在Win7中大多数时 ...
- 基于QT的在线打字练习软件助手(C/S模型)good
简介 通过基于QT中QTcpServer和QTcpSocket以及UI编程,实现了基于TCP协议的C/S模型在线打字练习软件助手,服务端处理各客户端打字数据,以及显示在线打字客户列表即实时更新打字 ...
- CMake编译Widget UI Qt程序
自从CMake被引入到KDE项目的编译系统中后,CMake的使用者日益增多,Qt也不例外,除了使用QMAKE编译Qt程序外,也可以使用CMake来编译Qt程序,并且CMake在使用上更灵活,特别是大型 ...
- centos yum 安装 jdk1.8
JDK: 版本:1.8 服务器默认安装1.7,所以不使用默认安装 yum -y list java* --查看yum的jdk安装包 yum install java-1.8.0-openjdk jav ...
- flask(二)
1.装饰器坑 使用装饰器后,视图函数名字相同问题view function错误问题 1.给装饰器加functiontools 2.反向生成url地址标志,指定endpoint(endpoint必须唯一 ...