Guava: Working with Collections II

阅读更多

1. Table

2. ImmutableCollections

3. Comparision Chain & Range

4. Ordering

 

1. Table: Map>

    1> Create table

package edu.xmu.guava.collection;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.junit.Test;

import com.google.common.collect.HashBasedTable;

public class TableTest {
    @Test
    public void createTest() {
	HashBasedTable table = HashBasedTable
		.create();
	table.put(0, 0, "A");
	table.put(0, 1, "B");
	table.put(0, 2, "C");
	table.put(1, 0, "D");
	table.put(1, 1, "E");

	assertTrue(table.contains(0, 0));
	assertTrue(table.contains(1, 1));
	assertFalse(table.contains(1, 2));
	assertFalse(table.contains(2, 0));

	table = HashBasedTable.create(2, 2);
	table.put(0, 0, "A");
	table.put(0, 1, "B");
	table.put(0, 2, "C"); // Will auto expand to ensure capacity
	table.put(1, 0, "D");
	table.put(1, 1, "E");

	HashBasedTable table2 = HashBasedTable
		.create(table);
	assertEquals(2, table2.rowMap().size()); // total 2 rows
	assertEquals(3, table2.row(0).size()); // total 3 cols in row 0
	assertEquals(3, table2.columnMap().size()); // total 3 cols
	assertEquals(1, table2.column(2).size()); // total 1 row in col 2

	table2.remove(0, 2);
	assertEquals(2, table2.rowMap().size()); // total 2 rows
	assertEquals(2, table2.row(0).size()); // total 3 cols in row 0
	assertEquals(2, table2.columnMap().size()); // total 2 cols
	assertEquals(2, table2.column(1).size()); // total 2 rows in col 1
    }
}

 This is the graph representation of the table created above.

    2> Table Views: The table provides some great methods for obtaining different views of the underlying data in the table.
Map columnMap = table.column(columnNo);
Map rowMap = table.row(rowNo);
package edu.xmu.guava.collection;

import static org.junit.Assert.assertEquals;

import java.util.Map;

import org.junit.Test;

import com.google.common.collect.HashBasedTable;
import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Table;

public class TableTest {
    @Test(expected = UnsupportedOperationException.class)
    public void tableViewTest() {
	Table table = HashBasedTable.create();
	table.put(0, 0, "A");
	table.put(0, 1, "B");
	table.put(0, 2, "C");
	table.put(1, 0, "D");
	table.put(1, 1, "E");

	assertEquals("C", table.row(0).get(2));
	assertEquals("D", table.row(1).get(0));
	assertEquals("E", table.row(1).get(1));

	Map rowMap = table.row(0);
	rowMap.put(3, "F"); // table is updated
	assertEquals("F", table.row(0).get(3));

	Map colMap = table.column(2);
	colMap.put(3, "G"); // table is updated
	assertEquals("G", table.row(3).get(2));
	assertEquals("G", table.column(2).get(3));

	Table immutableTable = ImmutableTable
		. builder().putAll(table).build();
	rowMap = immutableTable.row(0);
	rowMap.put(4, "H"); // UnsupporttedOperationException will be thrown
    }
}

 

2. ImmutableCollections

    1) If we don't explicitly have a need for a mutable collection, we should always favor using an immutable one.

        First of all, immutable collections are completely thread-safe.

        Secondly, they offer protection from unknown users who may try to access your code.

    @Test
    public void test() {
	List list = Lists.newArrayList("A", "B", "C", "D", "E");

	List addedList = ImmutableList. builder().addAll(list)
		.add("F").build();
	assertEquals(Lists.newArrayList("A", "B", "C", "D", "E", "F"),
		addedList);

	addedList = new ImmutableList.Builder().addAll(list).add("G")
		.build();
	assertEquals(Lists.newArrayList("A", "B", "C", "D", "E", "G"),
		addedList);
    }

    We can see in source code that ImmutableXXX.builder() == new ImmutableXXX.Builder();

  public static  Builder builder() {
    return new Builder();
  }

    Builder pattern is used to create an ImmutableXXX instance

 

3. ComparisonChain & Range

    1) ComparisionChain:

        1> UML for ComparisionChain: Attention that they are using Chain of Responsibity design pattern here.

Guava: Working with Collections II_第1张图片
        2> Usage:

package edu.xmu.guava.collection;

import java.util.Set;

import org.apache.log4j.Logger;
import org.junit.Test;

import com.google.common.collect.ComparisonChain;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;

public class ComparisionChainTest {

    Logger logger = Logger.getLogger(ComparisionChainTest.class);

    @Test
    public void sortTest() {
	Set persons = Sets.newTreeSet(Lists.newArrayList(new Person(
		"Yang", 23), new Person("Yang", 20), new Person("Yang", 33),
		new Person("Li", 12), new Person("Zhang", 21)));

	logger.info(persons);
    }

    static class Person implements Comparable {
	private String name;
	private int age;

	public Person(String name, int age) {
	    super();
	    this.name = name;
	    this.age = age;
	}

	public int compareTo(Person o) {
	    return ComparisonChain.start().compare(this.name, o.name)
		    .compare(this.age, o.age).result();
	}

	@Override
	public String toString() {
	    return "Person [name=" + name + ", age=" + age + "]";
	}

    }
}

    2) Range:

           1> It is usually used with ComparisionChain and serve as/for Predicate

           2> Range object implements the Predicate interface

    @Test
    public void comparableTest() {
	Range personRange = Range.closed(new Person("A", 1),
		new Person("B", 21));
	
	assertTrue(personRange.contains(new Person("A", 2)));
	assertTrue(personRange.contains(new Person("A", 21)));
	assertTrue(personRange.contains(new Person("A", Integer.MAX_VALUE)));
	assertTrue(personRange.contains(new Person("B", 1)));
	assertTrue(personRange.contains(new Person("B", 21)));
	assertFalse(personRange.contains(new Person("B", 22)));
    }

    public static class Person implements Comparable {
	private String name;
	private int age;

	public Person(String name, int age) {
	    super();
	    this.name = name;
	    this.age = age;
	}

	@Override
	public String toString() {
	    return "Person [name=" + name + ", age=" + age + "]";
	}

	@Override
	public int compareTo(Person o) {
	    return ComparisonChain.start().compare(this.name, o.name)
		    .compare(this.age, o.age).result();
	}

    }
    @Test
    public void comparableTest2() {
	Range personRange1 = Range.closed(new Person("A", 1),
		new Person("C", 1));

	Range personRange2 = Range.closed(new Person("D", 1),
		new Person("F", 2));

	Predicate personPredicate = Predicates.or(personRange1,
		personRange2);
	assertTrue(personPredicate.apply(new Person("B", 1)));
	assertTrue(personPredicate.apply(new Person("C", 1)));
	assertTrue(personPredicate.apply(new Person("D", Integer.MAX_VALUE)));
	assertTrue(personPredicate.apply(new Person("E", 1)));
	assertTrue(personPredicate.apply(new Person("E", Integer.MAX_VALUE)));
	assertFalse(personPredicate.apply(new Person("F", 3)));
    }

 

4. Ordering:

package edu.xmu.guava.collections;

import static org.junit.Assert.assertEquals;

import java.util.Comparator;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

import com.google.common.base.Function;
import com.google.common.base.Splitter;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;

public class OrderingTest {
    List versionList;
    List descSortedVersionList;

    @Before
    public void setUp() {
	versionList = Lists.newArrayList("11-0", "1-1", "2-1", "11-21",
		"11-111", "0-1");
	descSortedVersionList = Lists.newArrayList("11-111", "11-21", "11-0",
		"2-1", "1-1", "0-1");
    }

    @Test
    public void sortTest() {
	List sortedVersionList = Ordering
		.from(new Comparator() {
		    @Override
		    public int compare(String o1, String o2) {
			Function parseIntFunc = new Function() {
			    @Override
			    public Integer apply(String input) {
				return Integer.parseInt(input);
			    }
			};
			List prevVersions = FluentIterable
				.from(Splitter.on('-').trimResults()
					.omitEmptyStrings().split(o1))
				.transform(parseIntFunc).toList();
			List currVersions = FluentIterable
				.from(Splitter.on('-').trimResults()
					.omitEmptyStrings().split(o2))
				.transform(parseIntFunc).toList();
			return ComparisonChain
				.start()
				.compare(prevVersions.get(0),
					currVersions.get(0))
				.compare(prevVersions.get(1),
					currVersions.get(1)).result();
		    }
		}).reverse().sortedCopy(versionList);

	assertEquals(descSortedVersionList, sortedVersionList);
    }

    @Test
    public void sortTest2() {
	List personList = Lists.newArrayList(new Person("Yang", "Male",
		1), new Person("Li", "Female", 2), new Person("Zhang", "Male",
		24), new Person("Yang", "Female", 20));

	List sortedPersonList = Ordering.from(new Comparator() {
	    @Override
	    public int compare(Person o1, Person o2) {
		return o1.name.compareTo(o2.name);
	    }
	}).compound(new Comparator() {
	    @Override
	    public int compare(Person o1, Person o2) {
		return o1.age - o2.age;
	    }
	}).compound(new Comparator() {
	    @Override
	    public int compare(Person o1, Person o2) {
		return o1.gender.compareTo(o2.gender);
	    }
	}).sortedCopy(personList);
	System.out.println(sortedPersonList);
    }

    public class Person {
	private String name;
	private String gender;
	private int age;

	public Person(String name, String gender, int age) {
	    super();
	    this.name = name;
	    this.gender = gender;
	    this.age = age;
	}

	@Override
	public String toString() {
	    return "Person [name=" + name + ", gender=" + gender + ", age="
		    + age + "]";
	}

    }
}

    Comments: We can use Ordering without changing the Person (no need to implements Comparable).

 

Reference Links:

1) Getting Started with Google Guava -Bill Bejeck 

 

  • Guava: Working with Collections II_第2张图片
  • 大小: 6.6 KB
  • Guava: Working with Collections II_第3张图片
  • 大小: 10.4 KB
  • 查看图片附件

你可能感兴趣的:(Guava,Collections,Comparision,Chain)