public class Strategy {
public static void main(String[] args) {
int[] arr = {5, 3, 1, 7, 2};
new DataSorter().sort(arr);//调用工具类进行排序
for(int i = 0; i < arr.length; i++){
System.out.println(arr[i]);
}
}
}
class DataSorter{//用于排序的工具类
public void sort(int[] arr){//调用sort方法进行排序, 此处使用冒泡排序
for(int i = arr.length - 1; i > 0; i--){
for(int j = 0; j < i; j++){
if(arr[j] > arr[j + 1])
swap(arr, j, j + 1);
}
}
}
private void swap(int[] arr, int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
?
float
类型, 把int类型数组的排序算法复制一遍不就可以了吗?class Cat{
private int age;//猫的年龄
private int weight;//猫的体重
//get / set 方法...
}
public void sort(Cat[] arr){//以猫数组作为参数
for(int i = arr.length - 1; i > 0; i--){
for(int j = 0; j < i; j++){
if(arr[j].getAge() > arr[j + 1].getAge())//根据猫的年龄作比较
swap(arr, j, j + 1);
}
}
}
sort()
方法可以对任何调用它的对象进行排序.sort()
方法的参数改为Object
类型不久可以了嘛. 这个方向是对的, 但是问题是, 当拿到两个Object
类型对象, 应该根据什么规则进行比较呢?比较法则
, 这样在排序的时候就能直接调用对象的排序法则进行排序了.Comparable
接口, 凡是要进行比较的类都要实现Comparable
接口, 并且定义自己的比较法则, 也就是CompareTo()
方法.Comparable
接口的对象进行比较, 不用担心比较的细节了.public class Strategy {
public class Strategy {
public static void main(String[] args) {
// Integer[] arr = {5, 3, 1, 7, 2};//注意这里把int改为Integer, Integer是Object的子类
Cat[] arr = {new Cat(3, 3), new Cat(1, 1), new Cat(5, 5)};
DataSorter ds = new DataSorter();
ds.sort(arr);
for(int i = 0; i < arr.length; i++){
System.out.println(arr[i]);
}
}
}
}
class DataSorter{//用于排序的工具类
public void sort(Object[] arr){//参数类型为Object
for(int i = arr.length - 1; i > 0; i--){
for(int j = 0; j < i; j++){
Comparable c1 = (Comparable) arr[j];//先转为Comparable类型
Comparable c2 = (Comparable) arr[j + 1];
if(c1.CompareTo(c2) == 1)//调用CompareTo()进行比较, 不关心具体的实现
swap(arr, j, j + 1);
}
}
}
private void swap(Object[] arr, int i, int j){
Object temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
class Cat implements Comparable{
private int age;
private int weight;
@Override
public int CompareTo(Object o) {
if(o instanceof Cat){//先判断传入的是否是Cat类对象, 不是则抛异常
Cat c = (Cat) o;
if(this.age > c.age) return 1;
else if (this.age < c.age) return -1;
else return 0;
}
throw null == o ? new NullPointerException() : new ClassCastException();
}
// get / set ...
//toString() ...
}
interface Comparable{
public int CompareTo(Object o);
}
?
Comparable
接口来由, 大家会感觉整个设计又美好了一些, 但是其中还有漏洞. 我们在Cat
类的CompareTo()
方法中, 对猫的比较策略是写死的, 现在我们按猫的年龄比较大小, 如果哪天我们想按照猫的体重比较大小, 又要去修改源码了. 有没有扩展性更好的设计?Comparable
接口, 但是它具体是怎么比较的, 则通过具体的Comparator
比较器进行比较.Comparator
, 用户的比较器需要实现Comparator
接口, 下面上代码:public class Strategy {
public static void main(String[] args) {
Cat[] arr = {new Cat(3, 3), new Cat(1, 1), new Cat(5, 5)};
DataSorter ds = new DataSorter();
ds.sort(arr);
for(int i = 0; i < arr.length; i++){
System.out.println(arr[i]);
}
}
}
class DataSorter{//用于排序的工具类
public void sort(Object[] arr){//参数类型为Object
for(int i = arr.length - 1; i > 0; i--){
for(int j = 0; j < i; j++){
Comparable c1 = (Comparable) arr[j];//先转为Comparable类型
Comparable c2 = (Comparable) arr[j + 1];
if(c1.CompareTo(c2) == 1)//背后已经转换为使用Comparator的定义的规则进行比较
swap(arr, j, j + 1);
}
}
}
private void swap(Object[] arr, int i, int j){
Object temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
class Cat implements Comparable{
private int age;
private int weight;
private Comparator comparator = new CatAgeComparator();//默认持有年龄比较器
@Override
public int CompareTo(Object o) {
return comparator.Compare(this, o);//调用比较器比较而不是直接在此写比较法则
}
// get / set / toString ...
}
interface Comparable{
public int CompareTo(Object o);
}
interface Comparator{
public int Compare(Object o1, Object o2);
}
//用户自己定义的, 按照猫的年龄比较大小的比较器
class CatAgeComparator implements Comparator{
@Override
public int Compare(Object o1, Object o2) {
Cat c1 = (Cat) o1;
Cat c2 = (Cat) o2;
if(c1.getAge() > c2.getAge()) return 1;
else if(c1.getAge() < c2.getAge()) return -1;
else return 0;
}
}
//按照猫的体重比较大小的比较器
class CatWeightComparator implements Comparator{
@Override
public int Compare(Object o1, Object o2) {
Cat c1 = (Cat) o1;
Cat c2 = (Cat) o2;
if(c1.getWeight() > c2.getWeight()) return 1;
else if(c1.getWeight() < c2.getWeight()) return -1;
else return 0;
}
}
?
Comparable
接口和Comparator
接口, 其实这两个接口都是Java自带的, 通过上面的代码示例, 想必大家也应该知道了为什么会有这两个接口.Comparable
定义的就是一种比较的策略, 这里的策略你可以理解为一个功能, 然而策略有了, 我们还需要有具体的策略实现, 于是便有了Comparator
接口.?
public interface Fire {
public void fire();//发射炮弹的策略
}
public interface FireAction {
public void fireAction(Tank tank);
}
Fire()
接口, 而且坦克拥有发射炮弹的动作, 至于动作的具体实现, 这里默认给出只发射一颗炮弹的动作.public class Tank implements TankHitListener, Fire {
//省略各种属性方法...
private FireAction fireAction = new NormalFireAction();//默认动作是只发射一颗炮弹
@Override
public void fire() {
fireAction.fireAction(this);
}
//...
fire()
接口, 获得发射炮弹的能力.?
为什么会有Comparable与Comparator接口? 引入策略模式
原文:https://www.cnblogs.com/tanshaoshenghao/p/10753022.html