Comparison

General Maximization Function Through Inheritance

OurComparable接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public interface OurComparable {
int compareTo(Object obj);
}
public class Dog implements OurComparable {
public int compareTo(Object obj) {
/** Warning, cast can cause runtime error! */
Dog uddaDog = (Dog) obj;
return this.size - uddaDog.size;
}
}
public class Maximizer {
public static OurComparable max(OurComparable[] a) {
...
}
}


1
2
Dog[] dogs = new Dog[]{d1, d2, d3};
Dog largest = (Dog) Maximizer.max(dogs);

Benefits of this approach

  • No need for array maximization code in every custom type (i.e. no Dog.maxDog(Dog[]) function required).
  • Code that operates on multiple types (mostly) gracefully, e.g.
    1
    2
    OurComparable[] objs = getItems(“somefile.txt”); 
    return Maximizer.max(objs);

two issues

  • Awkward casting to/from Objects.
  • We made it up.
    • No existing classes implement OurComparable (e.g. String, etc).
    • No existing classes use OurComparable (e.g. no built-in max function that uses OurComparable)

Comparable接口

1
2
3
4
5
6
7
8
9
public interface Comparable<T> {
public int compareTo(T obj);
}

public class Dog implements Comparable<Dog> {
public int compareTo(Dog uddaDog) {
return this.size - uddaDog.size;
}
}

Ourcomparable 代码

1
2
3
public interface OurComparable {
int compareTo(Object obj);
}

Comparable Advantages

  • Lots of built in classes implement Comparable (e.g. String).
  • Lots of libraries use the Comparable interface (e.g. Arrays.sort)
  • Avoids need for casts.

Comparators

Natural Order

  • 数字大小排列
  • 按名称排列

Compartor接口

1
2
3
public interface Comparator<T> {
int compare(T o1, T o2);
}

接口实现与使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Dog implements Comparable<Dog> {
private String name;
private int size;

public static class NameComparator implements Comparator<Dog> {
public int compare(Dog d1, Dog d2) {
return d1.name.compareTo(d2.name);
}
}
}

\\使用
Comparator<Dog> cd = new Dog.NameComparator();
if (cd.compare(d1, d3) > 0) {
d1.bark();
} else {
d3.bark();
}


以上接口的总结

  • Sometimes a function needs the help of another function that might not have been written yet.
    • Example: max needs compareTo
    • The helping function is sometimes called a “callback”.
  • Some languages handle this using explicit function passing.
  • In Java, we do this by wrapping up the needed function in an interface (e.g. Arrays.sort needs compare which lives inside the comparator interface)
  • Arrays.sort “calls back” whenever it needs a comparison.
    • Similar to giving your number to someone if they need information.
    • See Project 1B to explore how to write code that uses comparators.

关于静态类的想法

猜想: 静态类能被用来调用其中的静态方法(对parameter进行计算)

Java libraries

接口的另外两个好处:

  • 提供一个供许多类共有的方法
  • 提供一个通用方法 例:compartor

Abstract Data Types(抽象数据类型)

我的理解:我是一个有需求的ADT,需要实现我的方法,而这些方法有多种方式可以实现

Collection

collection interface以及继承它的interface是java.util library 中最重要的几个接口

继承了collection接口的三个接口:

  • Lists of things.
  • Sets of things.
  • Mappings between items, e.g. jhug’s grade is 88.4.
    Maps also known as associative arrays, associative lists (in Lisp), symbol tables, dictionaries (in Python).

java.util package

在这个包中有接口和我们可以用的具体类

3 tasks, given the text of a book

Count the number of unique words.

Example: Using a Set to Count Unique Words

1
2
3
4
5
6
7
public static int countUniqueWords(List<String> words) {
Set<String> ss = new HashSet<>();
for (String s : words) {
ss.add(s);
}
return ss.size();
}
1
2
3
4
5
public static int countUniqueWords(List<String> words) {
Set<String> ss = new HashSet<>();
ss.addAll(words);
return ss;
}

Example: Using a Map to Create Counts of Specific Words

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static Map<String, Integer> 
collectWordCount(List<String> words, List<String> targets) {
Map<String, Integer> wordCounts = new HashMap<>();
for (String s : targets) {
wordCounts.put(s, 0);
}
for (String s : words) {
if (wordCounts.containsKey(s)) {
int oldCount = wordCounts.get(s);
wordCounts.put(s, oldCount + 1);
}
}
return wordCounts;
}

接口的实现方式有多种选择

Allows power user to explicitly handle engineering tradeoffs.

Interfaces

Inheritance Summary (So Far)

  • Interface inheritance: What (the class can do).
  • Implementation inheritance: How (the class does it).

Interfaces may combine a mix of abstract and default methods.

  • Abstract methods are what. And must be overridden by subclass.
  • Default methods are how.

其他要注意的

  • Unless you use the keyword default, a method will be abstract.
  • Unless you specify an access modifier, a method will be public.
  • Can provide variables, but they are public static final.
    • final means the value can never change. Use for constants: G=6.67e-11
  • A class can implement multiple interfaces.

Interface Summary

  • 不能被实例化
  • Can provide either abstract or concrete methods.
    • Use no keyword for abstract methods.
    • Use default keyword for concrete methods.
  • Can provide only public static final variables. 变量无法更改

Abstract Classes

Abstract classes

  • 不能被实例化
  • 与接口相反,抽象方法需要使用abstract来标注
  • 可以有任何类型的变量
  • Can provide protected and package private methods [after mt1].(我对mt1的理解是在第一个方法之后)

通常用法

为接口的实现提供基础

1
2
3
4
5
6
7
8
9
10
11
public abstract class AbstractList61B<T> implements List61B<T> {
int size = 0;
public AbstractList61B() { size = 0; }
@Override
public int size() {
return size;
}
}

public class AList<T> extends AbstractList61B<T> { ... }

好处和坏处

Good

Avoids the need to write a size() method or declare a size variable in AList and SLList.

Bad

混淆结构 (e.g. maybe you don’t want a size variable).

Summary: Abstract Classes vs. Interfaces

Interfaces

  • Primarily for interface inheritance. Limited implementation inheritance.
  • Classes can implement multiple interfaces.

Abstract classes

  • Can do anything an interface can do, and more.
  • Subclasses only extend one abstract class.

An example for abstract class

  • AbstractList provides default implementations for methods.
  • Why not just put them in List itself? No default methods in Java interfaces until 2014, and the AbstractList was public so can’t just throw it away.
1
2
3
4
5
6
7
8
9
10
11
public abstract class AbstractList<E>
implements List<E> {

...

public boolean add(E e) {
add(size(), e);
return true;
}
}

Packages

To address the fact that classes might share names:

  • A package is a namespace that organizes classes and interfaces.
  • Naming convention: Package name starts with website address (backwards).

注意: 我们不用遵循第二条因为我们不会distribution代码

使用

包外

加上包名

1
2
3
4
5
6
7
8
\\Dog.java
package ug.joshh.animal;

public class Dog {
private String name;
private String breed;
private double size;

1
2
3
4
5
6
\\e.g. 1
ug.joshh.animal.Dog d =
new ug.joshh.animal.Dog(...);
\\e.g. 2
org.junit.Assert.assertEquals(5, 5);

包内

If used from another class in same package (e.g. ug.joshh.animal.DogLauncher), can just use simple name.

import class

1
2
3
import ug.joshh.animal.Dog;
Dog d = new Dog(...);

import 多个class

1
2
3
import ug.joshh.animal.*;
Dog d = new Dog(...);

import static

1
2
import static org.junit.Assert.assertEquals;
assertEquals(5, 5);

Dangerous! Will cause compilation error if another * imported class contains Dog.

命令行使用

跳过,有空看