Hot questions for Operating List in Guava

Top 10 Java Open Source / Guava / Operating List

Google Guava “zip” two lists

Question: Using Google Guava (Google Commons), is there a way to merge two equally sized lists into one list, with the new list containing composite objects of the two input lists?

Example:

public class Person {
    public final String name;
    public final int age;

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

    public String toString() {
        return "(" + name + ", " + age + ")";
    }
}

and

List<String> names = Lists.newArrayList("Alice", "Bob", "Charles");
List<Integer> ages = Lists.newArrayList(42, 27, 31);

List<Person> persons =
    transform with a function that converts (String, Integer) to Person
System.out.println(persons);

Would output:

[(Alice, 42), (Bob, 27), (Charles, 31)]

Answer: As of Guava 21, this is possible via Streams.zip():

List<Person> persons = Streams.zip(names.stream(), ages.stream(), Person::new)
                              .collect(Collectors.toList());

How to get max() element from List in Guava

Question: Let's say we have a Collection of Items:

class Item {
    public String title;
    public int price;
}

List<Item> list = getListOfItems();

I would like to get an Item with a maximum price out of that list with Guava library (with Ordering, I presume). I mean something similar to this Groovy code:

list.max{it.price}

How do I do that? How efficient is it?

Answer: It's as efficient as it can be: it iterates through the items of the list, and returns the first of the Items having the maximum price: O(n).

Ordering<Item> o = new Ordering<Item>() {
    @Override
    public int compare(Item left, Item right) {
        return Ints.compare(left.price, right.price);
    }
};
return o.max(list);

Interface/enum listing standard mime-type constants

Question: I am looking among the standard libraries (like apache commons, jax, jboss, javax) for an interface or enum that lists the values of all the standard mime-type (aka content-type).

This interface should not be encumbered with too deep with other classes that would make it difficult to include the whole bunch as gwt source code.

for example

interface ContentType{
  String JSON = "Application/JSON";
  blah ... blah ...
}

or,

enum ContentType{
  JSON("Application/JSON"),
  blah ... blah ...
}

Answer: Guava have a class for this: com.google.common.net.MediaType.

It was released with Guava 12 as stated in the source code.

Or view the list below:

staticjava.lang.String APPLICATION_ATOM_XML             "application/atom+xml"
staticMediaType        APPLICATION_ATOM_XML_TYPE        "application/atom+xml"
staticjava.lang.String APPLICATION_FORM_URLENCODED      "application/x-www-form-urlencoded"
staticMediaType        APPLICATION_FORM_URLENCODED_TYPE "application/x-www-form-urlencoded"
staticjava.lang.String APPLICATION_JSON                 "application/json"
staticMediaType        APPLICATION_JSON_TYPE            "application/json"
staticjava.lang.String APPLICATION_OCTET_STREAM         "application/octet-stream"
staticMediaType        APPLICATION_OCTET_STREAM_TYPE    "application/octet-stream"
staticjava.lang.String APPLICATION_SVG_XML              "application/svg+xml"
staticMediaType        APPLICATION_SVG_XML_TYPE         "application/svg+xml"
staticjava.lang.String APPLICATION_XHTML_XML            "application/xhtml+xml"
staticMediaType        APPLICATION_XHTML_XML_TYPE       "application/xhtml+xml"
staticjava.lang.String APPLICATION_XML                  "application/xml"
staticMediaType        APPLICATION_XML_TYPE             "application/xml"
staticjava.lang.String MEDIA_TYPE_WILDCARD              The value of a type or subtype wildcard: "*"
staticjava.lang.String MULTIPART_FORM_DATA              "multipart/form-data"
staticMediaType        MULTIPART_FORM_DATA_TYPE         "multipart/form-data"
staticjava.lang.String TEXT_HTML                        "text/html"
staticMediaType        TEXT_HTML_TYPE                   "text/html"
staticjava.lang.String TEXT_PLAIN                       "text/plain"
staticMediaType        TEXT_PLAIN_TYPE                  "text/plain"
staticjava.lang.String TEXT_XML                         "text/xml"
staticMediaType        TEXT_XML_TYPE                    "text/xml"
staticjava.lang.String WILDCARD                         "*/*"
staticMediaType        WILDCARD_TYPE                    "*/*"

Populating a List with a contiguous range of integers

Question: I'd like to have a list which contains the integers in the range 1 to 500. Is there some way to create this list using Guava (or just plain Java) without having to loop through the range and add the values individually within my own code?

Answer: Using Guava, you can resort to a Range.

Of course, there will still be loops in your code, but they just might be hidden from the code for simplicity sake.

For instance:

Range<Integer> yourValues = Range.closed(1, 500);

Keep in mind that if you do need to eventually iterate over the Range, you cannot do so directly, only through using DiscreteDomains.integers().

Or in Java 8 way:

List<Integer> range = IntStream.range(0, 500).boxed().collect(Collectors.toList());

How to make a new list with a property of an object which is in another list

Question: Imagine that I have a list of certain objects:

List<Student>

And I need to generate another list including the ids of Students in the above list:

List<Integer>

Avoiding using a loop, is it possible to achieve this by using apache collections or guava?

Answer: With Guava you can use Function like

private enum StudentToId implements Function<Student, Integer> {
        INSTANCE;

        @Override
        public Integer apply(Student input) {
            return input.getId();
        }
    }

and you can use this function to convert List of students to ids like

Lists.transform(studentList, StudentToId.INSTANCE);

Surely it will loop in order to extract all ids, but remember guava methods returns view and Function will only be applied when you try to iterate over the List<Integer>. If you don't iterate, it will never apply the loop.

Remember this is the view and if you want to iterate multiple times it will be better to copy the content in some other List<Integer> like

ImmutableList.copyOf(Iterables.transform(students, StudentToId.INSTANCE));

Or Java 8 way of doing it:

List<Integer> idList = students.stream().map(Student::getId).collect(Collectors.toList());

Java-get most common element in a list

Question: Does Java or Guava have something that will return most common element in a list?

List<BigDecimal> listOfNumbers=  new ArrayList<BigDecimal>(); 

[1,3,4,3,4,3,2,3,3,3,3,3]

return 3

Answer: Probably the simplest solution with Guava looks like

Multiset<BigDecimal> multiset = HashMultiset.create(listOfNumbers);
BigDecimal maxElement = null;
int maxCount = 0;
for (Multiset.Entry<BigDecimal> entry : multiset.entrySet()) {
  if (entry.getCount() > maxCount) {
    maxElement = entry.getElement();
    maxCount = entry.getCount();
  }
}

Java 8 solution looks like this

Stream.of(1, 3, 4, 3, 4, 3, 2, 3, 3, 3, 3, 3)
      .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
      .entrySet()
      .stream()
      .max(Comparator.comparing(Entry::getValue))
      .ifPresent(System.out::println);

Which yields:

3=8

Is there a JDK or Guava method to turn a null into an empty list?

Question: Is there a method like this one in the JDK or Google Guava

public static <T> Collection<T> safe(Collection<T> collection) {
    if (collection == null) {
        return new ArrayList<>(0);
    } else {
        return collection;
    }
}

which makes it easy to not crash on a an enhanced loop if something returns a null list for example

for (String string : CollectionUtils.safe(foo.canReturnANullListOfStrings())) {
    // do something
}

would not crash.

I looked around but could not find any such method, and I am wondering if I missed it or if there is a reason why such a handy method is not handy and therefore not included?

Answer: There's no need for a specialized method, and this is indeed the solution we recommend you use immediately whenever you get a potentially-null collection from a naughty API that ideally shouldn't do that in the first place.

Objects.firstNonNull(list, ImmutableList.<Foo>of());

Text file into Java List<String> using Commons or Guava

Question: What is the most elegant way to put each line of text (from the text file) into LinkedList (as String object) or some other collection, using Commons or Guava libraries.

Answer: You can use Guava:

List<String> lines = Files.readLines(new File("myfile.txt"), Charsets.UTF_8);

Or Using Apache Commons IO:

List<String> lines = FileUtils.readLines(new File("myfile.txt"));

Depending on your exact use, assuming the "default encoding" might be a good idea or not. Either way, personally I find it good that the Guava API makes it clear that you're making an assumption about the encoding of the file.


Iterate through Collection<List<Integer>>

Question: I use Guava library to generate permutations of integers 1, 2 and 3.

Collection<List<Integer>> vehCombinations = Collections2.orderedPermutations(vehicles);

Next I need to iterate through vehCombinations and check each permutation with respect to some constraint:

for (int j=0; j<vehCombinations.size(); j++)
{
  List<Integer> veh = vehCombinations.get(i);
}

vehCombinations.get(i) is not allowed.

So, how do I extract permutations from vehCombinations?

Answer: Use a foreach, like this:

for(List<Integer> veh : vehCombinations){
    veh.doSomething();
}