# Company Ghost Story 公司鬼故事 1

## Java

### Unique

```class DbObj{
@Override
public boolean equals(Object obj){
return this.compareTo((DbObj) obj) == 0;
}
}
```

，它們可以直接用 `==`

```class MyString{
@Override
public boolean equals(Object obj){...}; // possible O(n)
}
```

### `toString` in Comparison

```class CompositeClassimplements Comparable<CompositeClass>{
@Override
public int compareTo(CompositeClass other){
}
}
```

### `toString()` in Key

，因為這個函數很容易被其他人覆寫。

```enum SomeType {
@Override
public String toString(){
return super.toString() + "...";
}
}
SomeType.valueOf(type.toString()); // ?????
```

### It is not in C++

```boolean sameLocation(Point a, Point b){
return a == b; // ?????, Objects.equals(a, b)
}
```

### Numeric Comparison

```static final Comparator<Point> compareX =
(a, b) -> a.getX() - b.getX(); // X, Long.compare(a.getX(), b.getX());
```

### `this` in Constructor

```public Point {
Point(long x, long y) {
mX = x;
mY = y;
}
Point() {
mX = 0; // X, this(0, 0);
mY = 0;
}
}
```

### Initialization

```Pointcopy(){
Point pt = new Point();
pt.setX(getX());
pt.setY(getY());
return pt; // new Point(getX(), getY());
}
```

### Find the Minimum/Maximum Element

```PointgetMax(List<Point> testList){
Collections.sort(testList);
return testList.get(testList.size() - 1); // Collections.max(testList);
}
PointgetMin(List<Point> testList){
return testList.stream().sorted().getFirst().orElse(null);
// testList.stream().min().orElse(null);
}
```

### Computed Getter

```static final Comparator<CPoint> compateLocation =
(CPoint ca, CPoint cb) -> {
long p0x = ca.getCPt().getX();
long p1x = cb.getCPt().getX();
long p0y = ca.getCPt().getY();
long p1y = cb.getCPt().getY();
... // X, return ca.getCPt().compareTo(cb.getCPt());
}
```

，如果牽涉到好幾步複雜運算，整個效率就慢上了好幾倍。

### Computed If-Else

```if (getA() != null &&
getA().getB() != null &&
getA().getB().getC() != null) {
...
}
```

```A a = getA();
if (a != null) {
B b = a.getB();
...
}
getA().ifPresent(a -> {
a.getB().ifPresent(...)
});
```

### List Getter

```LinkedList<Long> X;
void doSomething(List<Long> X){
for (int i = 0; i < X.size(); i++) {
long x = X.get(i);
...
}
}
```

`get(index)`

### Immutable Methods

```void parse(String elem){
elem.trim(); // ??????, elem = elem.trim();
...
}
```

### Method Reference

```Map<Long, List<Point>> map;
List<Point> list =
map.computeIfAbsent(a.mX, key -> new LinkedList<>()); // X, Point::prepare
}
static List<Point> prepare(Long key){
}
```

### Boxing

```DoublegetRotate(){ // X, double
double r = ...;
return r;
}
boolean getMirror(){...};
Boolean isMirror = getMirror(); // X, boolean
```

，請不要過度包裝。拆拆裝裝的狀況會造成垃圾過多。

### Exception is NOT a Return Value

```public String getFileExt(File f){
try {
String token = parseExt(f);
return "." + token;
} catch (NullPointerException e) {
return null;
}
}
```

```class Point{
private Throwable trace = new Throwable();
}
```

### Lightweight Exit

```void process(Point p){
List<Long> array = new ArrayList<>(10000); // ?????
if (p == null)
return;
}
```

### If-Elif-Else

```if (token.equals("a"))
{
}
else if (token.equals("b"))
{
}
if (token.equals("c"))
{
}
```

### Dead `instanceof`

```public abstract class Shape;
public class Polyextends Shape;
public class Rectextends Poly;
void write(Shape shape){
if (shape instanceof Poly) {
} else if (shape instanceof Rect) {
// ?????, unsearchable
}
}
```

### Observer Pattern

```private List<ObsListener> list = new LinkedList<>();
private Set<ObsListener> list = new HashSet<>();
```

。當你需要嚴格地再現 BUG，就不要使用不穩定順序的 `HashSet`
，請使用 `LinkedHashSet`

### Remove Observer

```class CreateUIextends Dialog{
public CreateUI(){
}
// where is your db.removeListener
}
```

### Opposite Behavior

```assert pathA.endsWith(pathB) ==
pathB.isEndOf(pathA); // fail ??????
```

### Global Garbage

```static List<DbObj> tmp;
List<DbObj>getXXX(){
tmp = new LinkedList<>();
parallel...
return tmp;
}
```

，會看到一堆資料庫物件被卡在全區變數裡頭。

### Useless Argument

```class Path{
boolean startsWith(Path p);
boolean startsWith(Path p, Object a); // new one
}
```

### Count

```int getPointCount(){
return mPoints.parallelStream().count();
// return mPoints.size();
}
```

### Tooltip

```String tooltip = ""; // should StringBuilder
for (DbObj t : db.getObjects(XXX.class))
tooltip = tooltip + t.toString();
```

### Convert Set to Array

```List<Point>toArray(Set<Point> set){
List<Point> arr = new ArrayList<>();
for (Point e : set)
return arr; // return new ArrayList<>(set);
}
```

### Error Message

```IntegerparseInteger(String x){
String errMsg = x + "is an invalid integer format...";
errMsg = attachCurrentLineMessage(errMsg);
try {
Integer n = Integer.parseInt(x);
return n;
} catch (Exception e) {
System.err.println(errMsg);
return null;
}
}
```

### New Option

```static void import(boolean a);
static void import(boolean a, boolean b);
static void import(boolean a, boolean b, int c);
static void import(boolean a, boolean b, int c, String d);
...
```