java adapter(适配器)惯用方法
如果现在有一个Iterable类,你想要添加一种或多种在foreach语句中使用这个类的方法,例如方向迭代,应该怎么做呢? 如果之间继承这个类,并且覆盖iterator()方法,你只能替换现有的方法,而不能实现选择
一种解决方案是所谓的adapter方法的惯用法,"适配器"部分来自于设计模式,因为你必须提供特定接口以满足foreach语句,当你有一个接口并需要另一个接口时,编写adapter就可以解决问题,这里,希望在默认的前向迭代器的基础上,添加方向迭代器的能力,因此不能使用覆盖,而是添加了一个能够产生Iterable对象的方法,该对象可以用于foreach语句,正如你所见,可以提供多种使用foreach的方式
package object;
//: holding/AdapterMethodIdiom.java
// The "Adapter Method" idiom allows you to use foreach
// with additional kinds of Iterables.
import java.util.*; class ReversibleArrayList<T> extends ArrayList<T> {
public ReversibleArrayList(Collection<T> c) { super(c); }
public Iterable<T> reversed() {//返回一个具有反向迭代器的Iterable
return new Iterable<T>() {
public Iterator<T> iterator() {
return new Iterator<T>() {
int current = size() - 1;
public boolean hasNext() { return current > -1; }
public T next() { return get(current--); }
public void remove() { // Not implemented
throw new UnsupportedOperationException();
}
};
}
};
}
} public class AdapterMethodIdiom {
public static void main(String[] args) {
ReversibleArrayList<String> ral =
new ReversibleArrayList<String>(
Arrays.asList("To be or not to be".split(" ")));
// Grabs the ordinary iterator via iterator():
for(String s : ral)
System.out.print(s + " ");
System.out.println();
// Hand it the Iterable of your choice
for(String s : ral.reversed())
System.out.print(s + " ");
}
} /* Output:
To be or not to be
be to not or be To
*///:~
通过这种方法,可以在IterableClass.java的示例中添加两种适配器方法
package object;
//: holding/MultiIterableClass.java
// Adding several Adapter Methods.
import java.util.*; public class MultiIterableClass extends IterableClass {
public Iterable<String> reversed() {
return new Iterable<String>() {
public Iterator<String> iterator() {
return new Iterator<String>() {
int current = words.length - 1;
public boolean hasNext() { return current > -1; }
public String next() { return words[current--]; }
public void remove() { // Not implemented
throw new UnsupportedOperationException();
}
};
}
};
}
public Iterable<String> randomized() {
return new Iterable<String>() {
public Iterator<String> iterator() {
List<String> shuffled =
new ArrayList<String>(Arrays.asList(words));
Collections.shuffle(shuffled, new Random(47));////
return shuffled.iterator();
}
};
}
public static void main(String[] args) {
MultiIterableClass mic = new MultiIterableClass();
for(String s : mic.reversed())
System.out.print(s + " ");
System.out.println();
for(String s : mic.randomized())
System.out.print(s + " ");
System.out.println();
for(String s : mic)
System.out.print(s + " ");
}
} /* Output:
banana-shaped. be to Earth the know we how is that And
is banana-shaped. Earth that how the be And we know to
And that is how we know the Earth to be banana-shaped.
*///:~
Collections方法并没有打乱原来的数组,而是打乱了shuffled中的引用,之所以这样,只是因为,randmize()方法用一个ArrayList将Arrays.asList()结果包装了起来
如果这个有Arrays.asList()产生的List被直接打乱,那么就会修改底层是数组,就像下面这样;
package object;
//: holding/ModifyingArraysAsList.java
import java.util.*; public class ModifyingArraysAsList {
public static void main(String[] args) {
Random rand = new Random(47);
Integer[] ia = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
List<Integer> list1 =
new ArrayList<Integer>(Arrays.asList(ia));//ia的输出被传给了ArrayList构造器,这将创建一个ia的元素引用的ArrayList
System.out.println("Before shuffling: " + list1);
Collections.shuffle(list1, rand);
System.out.println("After shuffling: " + list1);
System.out.println("array: " + Arrays.toString(ia)); List<Integer> list2 = Arrays.asList(ia);//lsit2 直接使用Arrays.asList(ia),这样做会直接修改ia的数据
System.out.println("Before shuffling: " + list2);
Collections.shuffle(list2, rand);
System.out.println("After shuffling: " + list2);
System.out.println("array: " + Arrays.toString(ia));
}
} /* Output:
Before shuffling: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
After shuffling: [4, 6, 3, 1, 8, 7, 2, 5, 10, 9]
array: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Before shuffling: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
After shuffling: [9, 1, 6, 3, 7, 2, 5, 10, 4, 8]
array: [9, 1, 6, 3, 7, 2, 5, 10, 4, 8]
*///:~
意识到Arrays.asLIst()产生的对象会使用底层数组作为其物理实现是很重要的,只要你执行的操作会修改这个List,并且你不想原来的数组被修改那么你就应该在另一个容器中创建副本
java adapter(适配器)惯用方法的更多相关文章
- Android中ListView 控件与 Adapter 适配器如何使用?
一个android应用的成功与否,其界面设计至关重要.为了更好的进行android ui设计,我们常常需要借助一些控件和适配器.今天小编在android培训网站上搜罗了一些有关ListView 控件与 ...
- GoldenGate for Java Adapter介绍一(原理篇)
前言 Oracle Goldengate在很早前就推出了一个for java的版本,主要目的是方便把关系型数据实时写入到不支持的目标端,如JMS或Redis等key value数据库.在Hadoop刚 ...
- java演示适配器(adapter)模式
为什么要使用模式: 模式是一种做事的一种方法,也即实现某个目标的途径,或者技术. adapter模式的宗旨就是,保留现有类所提供的服务,向客户提供接口,以满足客户的需求. 类适配器:客户端定义了接口并 ...
- Java 实现适配器(Adapter)模式
平时我们会常常碰到这种情况,有了两个现成的类,它们之间没有什么联系.可是我们如今既想用当中一个类的方法.同一时候也想用另外一个类的方法.有一个解决方法是.改动它们各自的接口.可是这是我们最不愿意看到的 ...
- Android adapter适配器的学习
学习Android有一点时间,说说自己的学习感悟. 首先呢,先说说适配器的作用,顾名思义,它就是把数据定义好一定的规则,使得我们可以用到ListView GridView等上面 所以说这玩意,还是得好 ...
- Android adapter适配器的使用
说起Adapter的使用,首先想到的就是listview或各种各样的Adapter.下面我们对常用的一些Adapter进行简单的使用讲解. 这是Adapter的关系图: 下面的所有例子均使用同一个布局 ...
- Java模式(适配器型号)
今天阅读Java该适配器模式,这里有一个小的总结和下谈感受.对于将来使用. 首先.让我们有关适配器先说说. 适应是“来源”至“目标”适应.其中连接这两个的关系是适配器.它负责“源”过度到“目标”. 举 ...
- android学习-Adapter适配器进阶
参考资源 Android 快速开发系列 打造万能的ListView GridView 适配器 实现代码复用,争取打机**的时间. android4.4源码 target=android-19 一般自定 ...
- java之类适配器
类适配器 所谓类适配器,指的是适配器Adapter继承我们的被适配者Adaptee,并实现目标接口Target.由于Java中是单继承,所以这个适配器仅仅只能服务于所继承的被适配者Adaptee.代码 ...
随机推荐
- Python模块-pandas
目录 数据读取 数据探索 数据清洗 数据清洗 类型转换 缺失值 重复值 值替换 修改表结构 新增列 删除列 删除行 修改列名 数据分组(数值变量) 数据分列(分类变量) 设置索引 排序 数据筛选/切片 ...
- Delphi7如何实现让Tedit显示文字垂直居中(上下居中)
通过下面的组件,可以在输入文字的时候自动垂直居中 直接把下面代码保存到Unit1.pas即可------------------------------------------ unit Unit1; ...
- BZOJ2655 calc(动态规划+拉格朗日插值法)
考虑暴力dp:f[i][j]表示i个数值域1~j时的答案.考虑使其值域++,则有f[i][j]=f[i][j-1]+f[i-1][j-1]*i*j,边界f[i][i]=i!*i!. 注意到值域很大,考 ...
- MT【99】2005联赛二试题我的一行解法
为表示尊敬先展示参考答案:参考答案其实很好的体现了当年出题人陶平生的想法,就是利用已知形式联想到三角里的射影定理,从而写出余弦定理形式,利用三角解题,如下: 这里展示以下几年前做这题时我的解法: $\ ...
- 【Treap 例题】神秘岛(island)
神秘岛(island) 题目描述: 除了敲代码和撩妹,旅行是cxw123 的第三爱好.他来到了澳大利亚东北部的大宝礁,在这里,有一个隔绝人世的神秘岛,这个岛不同于附近其他的珊瑚岛,它的生长速度极快,甚 ...
- 【bzoj2434】 Noi2011—阿狸的打字机
http://www.lydsy.com/JudgeOnline/problem.php?id=2434 (题目链接) 题意 给出一个字符串,$P$表示输出,$B$表示退格.$m$组询问$(x,y)$ ...
- 滥用基于资源约束委派来攻击Active Directory
0x00 前言 早在2018年3月前,我就开始了一场毫无意义的争论,以证明TrustedToAuthForDelegation属性是无意义的,并且可以在没有该属性的情况下实现“协议转换”.我相信,只要 ...
- ASP.NET MVC学习之Log4Net配置(日志记录)
Log4Net配置笔记---- 首先,添加对log4net.dll的引用. 在Web.config文件下的Configuration节点下添加Log4Net的配置信息: <!--Log4Net配 ...
- POJ 3259 Wormholes(最短路径,求负环)
POJ 3259 Wormholes(最短路径,求负环) Description While exploring his many farms, Farmer John has discovered ...
- 界面编程之QT的Socket通信20180730
/*******************************************************************************************/ 一.linu ...