new appendix

This commit is contained in:
Bruce Eckel 2017-01-10 14:11:16 -08:00
parent 5d0f0fe3f9
commit 5ec9f9b901
28 changed files with 329 additions and 173 deletions

View File

@ -14,7 +14,7 @@ public class Bits {
System.out.println("bit pattern: " + bbits);
}
public static void main(String[] args) {
SplittableRandom rand = new SplittableRandom(47);
Random rand = new Random(47);
// Take the LSB of nextInt():
byte bt = (byte)rand.nextInt();
BitSet bb = new BitSet();

View File

@ -11,7 +11,9 @@ class Element {
@Override
public String toString() { return ident; }
@Override
public int hashCode() { return ident.hashCode(); }
public int hashCode() {
return Objects.hashCode(ident);
}
@Override
public boolean equals(Object r) {
return r instanceof Element &&

View File

@ -1,18 +0,0 @@
// collectiontopics/Prediction.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Predicting the weather with groundhogs
import java.util.*;
public class Prediction {
private static SplittableRandom rand = new SplittableRandom(47);
private boolean shadow = rand.nextDouble() > 0.5;
@Override
public String toString() {
if(shadow)
return "Six more weeks of Winter!";
else
return "Early Spring!";
}
}

View File

@ -1,39 +0,0 @@
// collectiontopics/SpringDetector.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// What will the weather be?
import java.lang.reflect.*;
import java.util.*;
public class SpringDetector {
// Uses a Groundhog or class derived from Groundhog:
public static <T extends Groundhog>
void detectSpring(Class<T> type) throws Exception {
Constructor<T> ghog = type.getConstructor(int.class);
Map<Groundhog,Prediction> map = new HashMap<>();
for(int i = 0; i < 10; i++)
map.put(ghog.newInstance(i), new Prediction());
System.out.println("map = " + map);
Groundhog gh = ghog.newInstance(3);
System.out.println("Looking up prediction for " + gh);
if(map.containsKey(gh))
System.out.println(map.get(gh));
else
System.out.println("Key not found: " + gh);
}
public static void
main(String[] args) throws Exception {
detectSpring(Groundhog.class);
}
}
/* Output:
map = {Groundhog #2=Early Spring!, Groundhog #5=Early
Spring!, Groundhog #6=Early Spring!, Groundhog #4=Early
Spring!, Groundhog #9=Six more weeks of Winter!, Groundhog
#8=Six more weeks of Winter!, Groundhog #0=Early Spring!,
Groundhog #1=Early Spring!, Groundhog #3=Early Spring!,
Groundhog #7=Six more weeks of Winter!}
Looking up prediction for Groundhog #3
Key not found: Groundhog #3
*/

View File

@ -1,22 +0,0 @@
// collectiontopics/SpringDetector2.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// A working key
public class SpringDetector2 {
public static void
main(String[] args) throws Exception {
SpringDetector.detectSpring(Groundhog2.class);
}
}
/* Output:
map = {Groundhog #0=Early Spring!, Groundhog #1=Early
Spring!, Groundhog #2=Early Spring!, Groundhog #3=Early
Spring!, Groundhog #4=Early Spring!, Groundhog #5=Early
Spring!, Groundhog #6=Early Spring!, Groundhog #7=Six more
weeks of Winter!, Groundhog #8=Six more weeks of Winter!,
Groundhog #9=Six more weeks of Winter!}
Looking up prediction for Groundhog #3
Early Spring!
*/

View File

@ -1,4 +1,4 @@
// collectiontopics/ComposedEquality.java
// equalshashcode/ComposedEquality.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

View File

@ -1,4 +1,4 @@
// collectiontopics/CountedString.java
// equalshashcode/CountedString.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
@ -41,8 +41,7 @@ public class CountedString {
Objects.equals(id, ((CountedString)o).id);
}
public static void main(String[] args) {
Map<CountedString,Integer> map =
new HashMap<>();
Map<CountedString,Integer> map = new HashMap<>();
CountedString[] cs = new CountedString[5];
for(int i = 0; i < cs.length; i++) {
cs[i] = new CountedString("hi");

View File

@ -0,0 +1,24 @@
// equalshashcode/DefaultComparison.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
class DefaultComparison {
private int i, j, k;
public DefaultComparison(int i, int j, int k) {
this.i = i;
this.j = j;
this.k = k;
}
public static void main(String[] args) {
DefaultComparison
a = new DefaultComparison(1, 2, 3),
b = new DefaultComparison(1, 2, 3);
System.out.println(a == a);
System.out.println(a == b);
}
}
/* Output:
true
false
*/

View File

@ -1,4 +1,4 @@
// collectiontopics/Equality.java
// equalshashcode/Equality.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

View File

@ -1,4 +1,4 @@
// collectiontopics/EqualityFactory.java
// equalshashcode/EqualityFactory.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

View File

@ -1,4 +1,4 @@
// collectiontopics/Groundhog.java
// equalshashcode/Groundhog.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

View File

@ -1,4 +1,4 @@
// collectiontopics/Groundhog2.java
// equalshashcode/Groundhog2.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

View File

@ -1,4 +1,4 @@
// collectiontopics/IndividualTest.java
// equalshashcode/IndividualTest.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
@ -13,12 +13,19 @@ public class IndividualTest {
MapOfList.petPeople.values())
for(Pet p : lp)
pets.add(p);
System.out.println(pets);
pets.forEach(System.out::println);
}
}
/* Output:
[Cat Elsie May, Cat Pinkola, Cat Shackleton, Cat Stanford
aka Stinky el Negro, Cymric Molly, Dog Margrett, Mutt Spot,
Pug Louie aka Louis Snorkelstein Dupree, Rat Fizzy, Rat
Freckly, Rat Fuzzy]
Cat Elsie May
Cat Pinkola
Cat Shackleton
Cat Stanford aka Stinky el Negro
Cymric Molly
Dog Margrett
Mutt Spot
Pug Louie aka Louis Snorkelstein Dupree
Rat Fizzy
Rat Freckly
Rat Fuzzy
*/

View File

@ -1,4 +1,4 @@
// collectiontopics/MapEntry.java
// equalshashcode/MapEntry.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
@ -24,21 +24,19 @@ public class MapEntry<K, V> implements Map.Entry<K, V> {
}
@Override
public int hashCode() {
return (key==null ? 0 : key.hashCode()) ^
(value==null ? 0 : value.hashCode());
return Objects.hash(key, value);
}
@SuppressWarnings("unchecked")
@Override
public boolean equals(Object rval) {
return rval instanceof MapEntry &&
Objects.equals(key,
((MapEntry<K, V>)rval).getKey()) &&
Objects.equals(value,
((MapEntry<K, V>)rval).getValue());
}
@Override
public boolean equals(Object o) {
if(!(o instanceof MapEntry)) return false;
@SuppressWarnings("unchecked")
MapEntry<K, V> me = (MapEntry<K, V>)o;
return
(key == null ? me.getKey() == null :
key.equals(me.getKey()))
&&
(value == null ? me.getValue() == null :
value.equals(me.getValue()));
public String toString() {
return key + "=" + value;
}
@Override
public String toString() { return key + "=" + value; }
}

View File

@ -0,0 +1,15 @@
// equalshashcode/Prediction.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Predicting the weather
import java.util.*;
public class Prediction {
private static Random rand = new Random(47);
@Override
public String toString() {
return rand.nextBoolean() ?
"Six more weeks of Winter!" : "Early Spring!";
}
}

View File

@ -1,4 +1,4 @@
// collectiontopics/SimpleHashMap.java
// equalshashcode/SimpleHashMap.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
@ -62,30 +62,29 @@ class SimpleHashMap<K, V> extends AbstractMap<K, V> {
public static void main(String[] args) {
SimpleHashMap<String,String> m =
new SimpleHashMap<>();
m.putAll(Countries.capitals(25));
System.out.println(m);
System.out.println(m.get("ERITREA"));
System.out.println(m.entrySet());
m.putAll(Countries.capitals(8));
m.forEach((k, v) ->
System.out.println(k + "=" + v));
System.out.println(m.get("BENIN"));
m.entrySet().forEach(System.out::println);
}
}
/* Output:
{CAPE VERDE=Praia, ANGOLA=Luanda, ETHIOPIA=Addis Ababa,
BENIN=Porto-Novo, CONGO=Brazzaville, LESOTHO=Maseru,
CENTRAL AFRICAN REPUBLIC=Bangui, EQUATORIAL GUINEA=Malabo,
ERITREA=Asmara, COMOROS=Moroni, BURKINA FASO=Ouagadougou,
GABON=Libreville, THE GAMBIA=Banjul, GUINEA=Conakry,
EGYPT=Cairo, BURUNDI=Bujumbura, ALGERIA=Algiers,
CAMEROON=Yaounde, GHANA=Accra, KENYA=Nairobi, COTE D'IVOIR
(IVORY COAST)=Yamoussoukro, BISSAU=Bissau,
DJIBOUTI=Dijibouti, CHAD=N'djamena, BOTSWANA=Gaberone}
Asmara
[CAPE VERDE=Praia, ANGOLA=Luanda, ETHIOPIA=Addis Ababa,
BENIN=Porto-Novo, CONGO=Brazzaville, LESOTHO=Maseru,
CENTRAL AFRICAN REPUBLIC=Bangui, EQUATORIAL GUINEA=Malabo,
ERITREA=Asmara, COMOROS=Moroni, BURKINA FASO=Ouagadougou,
GABON=Libreville, THE GAMBIA=Banjul, GUINEA=Conakry,
EGYPT=Cairo, BURUNDI=Bujumbura, ALGERIA=Algiers,
CAMEROON=Yaounde, GHANA=Accra, KENYA=Nairobi, COTE D'IVOIR
(IVORY COAST)=Yamoussoukro, BISSAU=Bissau,
DJIBOUTI=Dijibouti, CHAD=N'djamena, BOTSWANA=Gaberone]
CAMEROON=Yaounde
ANGOLA=Luanda
BURKINA FASO=Ouagadougou
BURUNDI=Bujumbura
ALGERIA=Algiers
BENIN=Porto-Novo
CAPE VERDE=Praia
BOTSWANA=Gaberone
Porto-Novo
CAMEROON=Yaounde
ANGOLA=Luanda
BURKINA FASO=Ouagadougou
BURUNDI=Bujumbura
ALGERIA=Algiers
BENIN=Porto-Novo
CAPE VERDE=Praia
BOTSWANA=Gaberone
*/

View File

@ -1,4 +1,4 @@
// collectiontopics/SlowMap.java
// equalshashcode/SlowMap.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
@ -36,24 +36,29 @@ public class SlowMap<K, V> extends AbstractMap<K, V> {
}
public static void main(String[] args) {
SlowMap<String,String> m= new SlowMap<>();
m.putAll(Countries.capitals(15));
System.out.println(m);
System.out.println(m.get("BULGARIA"));
System.out.println(m.entrySet());
m.putAll(Countries.capitals(8));
m.forEach((k, v) ->
System.out.println(k + "=" + v));
System.out.println(m.get("BENIN"));
m.entrySet().forEach(System.out::println);
}
}
/* Output:
{ANGOLA=Luanda, CAPE VERDE=Praia, EGYPT=Cairo,
BURUNDI=Bujumbura, BENIN=Porto-Novo, ALGERIA=Algiers,
CAMEROON=Yaounde, CONGO=Brazzaville, CENTRAL AFRICAN
REPUBLIC=Bangui, EQUATORIAL GUINEA=Malabo, COMOROS=Moroni,
DJIBOUTI=Dijibouti, BURKINA FASO=Ouagadougou,
CHAD=N'djamena, BOTSWANA=Gaberone}
null
[ANGOLA=Luanda, CAPE VERDE=Praia, EGYPT=Cairo,
BURUNDI=Bujumbura, BENIN=Porto-Novo, ALGERIA=Algiers,
CAMEROON=Yaounde, CONGO=Brazzaville, CENTRAL AFRICAN
REPUBLIC=Bangui, EQUATORIAL GUINEA=Malabo, COMOROS=Moroni,
DJIBOUTI=Dijibouti, BURKINA FASO=Ouagadougou,
CHAD=N'djamena, BOTSWANA=Gaberone]
CAMEROON=Yaounde
ANGOLA=Luanda
BURKINA FASO=Ouagadougou
BURUNDI=Bujumbura
ALGERIA=Algiers
BENIN=Porto-Novo
CAPE VERDE=Praia
BOTSWANA=Gaberone
Porto-Novo
CAMEROON=Yaounde
ANGOLA=Luanda
BURKINA FASO=Ouagadougou
BURUNDI=Bujumbura
ALGERIA=Algiers
BENIN=Porto-Novo
CAPE VERDE=Praia
BOTSWANA=Gaberone
*/

View File

@ -0,0 +1,62 @@
// equalshashcode/SpringDetector.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// What will the weather be?
import java.util.*;
import java.util.stream.*;
import java.util.function.*;
import java.lang.reflect.*;
public class SpringDetector {
public static <T extends Groundhog>
void detectSpring(Class<T> type) {
try {
Constructor<T> ghog =
type.getConstructor(int.class);
Map<Groundhog, Prediction> map =
IntStream.range(0, 10)
.mapToObj(i -> {
try {
return ghog.newInstance(i);
} catch(Exception e) {
throw new RuntimeException(e);
}
})
.collect(Collectors.toMap(
Function.identity(),
gh -> new Prediction()));
map.forEach((k, v) ->
System.out.println(k + ": " + v));
Groundhog gh = ghog.newInstance(3);
System.out.println(
"Looking up prediction for " + gh);
if(map.containsKey(gh))
System.out.println(map.get(gh));
else
System.out.println("Key not found: " + gh);
} catch(NoSuchMethodException |
IllegalAccessException |
InvocationTargetException |
InstantiationException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
detectSpring(Groundhog.class);
}
}
/* Output:
Groundhog #3: Six more weeks of Winter!
Groundhog #0: Early Spring!
Groundhog #8: Six more weeks of Winter!
Groundhog #6: Early Spring!
Groundhog #4: Early Spring!
Groundhog #2: Six more weeks of Winter!
Groundhog #1: Early Spring!
Groundhog #9: Early Spring!
Groundhog #5: Six more weeks of Winter!
Groundhog #7: Six more weeks of Winter!
Looking up prediction for Groundhog #3
Key not found: Groundhog #3
*/

View File

@ -0,0 +1,25 @@
// equalshashcode/SpringDetector2.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// A working key
public class SpringDetector2 {
public static void main(String[] args) {
SpringDetector.detectSpring(Groundhog2.class);
}
}
/* Output:
Groundhog #0: Six more weeks of Winter!
Groundhog #1: Early Spring!
Groundhog #2: Six more weeks of Winter!
Groundhog #3: Early Spring!
Groundhog #4: Early Spring!
Groundhog #5: Six more weeks of Winter!
Groundhog #6: Early Spring!
Groundhog #7: Early Spring!
Groundhog #8: Six more weeks of Winter!
Groundhog #9: Six more weeks of Winter!
Looking up prediction for Groundhog #3
Early Spring!
*/

View File

@ -1,4 +1,4 @@
// collectiontopics/StringHashCode.java
// equalshashcode/StringHashCode.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

View File

@ -0,0 +1,60 @@
// equalshashcode/SubtypeEquality.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
import java.util.*;
enum Size { SMALL, MEDIUM, LARGE }
class Animal {
private static int counter = 0;
private final int id = counter++;
private final String name;
private final Size size;
public Animal(String name, Size size) {
this.name = name;
this.size = size;
}
@Override
public boolean equals(Object rval) {
return rval instanceof Animal &&
// Objects.equals(id, ((Animal)rval).id) && // [1]
Objects.equals(name, ((Animal)rval).name) &&
Objects.equals(size, ((Animal)rval).size);
}
@Override
public int hashCode() {
return Objects.hash(name, size);
// return Objects.hash(name, size, id); // [2]
}
@Override
public String toString() {
return String.format("%s[%d]: %s %s %x",
getClass().getSimpleName(), id,
name, size, hashCode());
}
}
class Dog extends Animal {
public Dog(String name, Size size) {
super(name, size);
}
}
class Pig extends Animal {
public Pig(String name, Size size) {
super(name, size);
}
}
public class SubtypeEquality {
public static void main(String[] args) {
Set<Animal> pets = new HashSet<>();
pets.add(new Dog("Ralph", Size.MEDIUM));
pets.add(new Pig("Ralph", Size.MEDIUM));
pets.forEach(System.out::println);
}
}
/* Output:
Dog[0]: Ralph MEDIUM a752aeee
*/

View File

@ -0,0 +1,40 @@
// equalshashcode/SubtypeEquality2.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
import java.util.*;
class Dog2 extends Animal {
public Dog2(String name, Size size) {
super(name, size);
}
@Override
public boolean equals(Object rval) {
return rval instanceof Dog2 &&
super.equals(rval);
}
}
class Pig2 extends Animal {
public Pig2(String name, Size size) {
super(name, size);
}
@Override
public boolean equals(Object rval) {
return rval instanceof Pig2 &&
super.equals(rval);
}
}
public class SubtypeEquality2 {
public static void main(String[] args) {
Set<Animal> pets = new HashSet<>();
pets.add(new Dog2("Ralph", Size.MEDIUM));
pets.add(new Pig2("Ralph", Size.MEDIUM));
pets.forEach(System.out::println);
}
}
/* Output:
Dog2[0]: Ralph MEDIUM a752aeee
Pig2[1]: Ralph MEDIUM a752aeee
*/

View File

@ -1,4 +1,4 @@
// collectiontopics/SuccinctEquality.java
// equalshashcode/SuccinctEquality.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

View File

@ -17,7 +17,7 @@ public class Holder<T> {
}
@Override
public int hashCode() {
return Objects.hash(value);
return Objects.hashCode(value);
}
public static void main(String[] args) {
Holder<Apple> apple = new Holder<>(new Apple());

View File

@ -5,13 +5,16 @@ project(':validating') {
}
project(':collectiontopics') {
jmh {
include = 'collectiontopics.jmh.*'
}
}
project(':equalshashcode') {
dependencies {
compile project(':typeinfo')
compile project(':collections')
}
jmh {
include = 'collectiontopics.jmh.*'
}
}
project(':lowlevel') {

View File

@ -44,7 +44,7 @@ extends AbstractMap<Integer,String> {
}
@Override
public int hashCode() {
return Integer.valueOf(index).hashCode();
return Objects.hashCode(index);
}
}
@Override
@ -64,7 +64,7 @@ extends AbstractMap<Integer,String> {
.limit(LIM)
.forEach(System.out::println);
System.out.println();
new Random().ints(LIM, 0, 1000)
new Random(47).ints(LIM, 0, 1000)
.mapToObj(cm::get)
.forEach(System.out::println);
}
@ -86,10 +86,10 @@ D0
E0
F0
E4
X33
P15
L28
M24
Y36
Y9
J21
R26
D33
Z36
N16
*/

View File

@ -225,7 +225,7 @@ public class Countries {
}
@Override
public int hashCode() {
return DATA[index][0].hashCode();
return Objects.hashCode(DATA[index][0]);
}
@Override
public String getKey() { return DATA[index][0]; }

View File

@ -26,11 +26,7 @@ Individual implements Comparable<Individual> {
}
@Override
public int hashCode() {
int result = 17;
if(name != null)
result = 37 * result + name.hashCode();
result = 37 * result + (int)id;
return result;
return Objects.hash(name, id);
}
@Override
public int compareTo(Individual arg) {
@ -39,7 +35,7 @@ Individual implements Comparable<Individual> {
String argFirst = arg.getClass().getSimpleName();
int firstCompare = first.compareTo(argFirst);
if(firstCompare != 0)
return firstCompare;
return firstCompare;
if(name != null && arg.name != null) {
int secondCompare = name.compareTo(arg.name);
if(secondCompare != 0)