DATACMNS-635 - Slice and Page can now be mapped using a Converter.

Introduced a map(Converter converter) method on Slice and Page to be able to easily transform the elements and create a new Slice or Page of the transformation result.

On Java 8 this allows code like this:

Page<String> strings = …;
Page<Integer> ints = strings.map(String::length);
This commit is contained in:
Oliver Gierke
2015-01-22 19:01:16 +01:00
parent aff6b6cca7
commit 5cc4811c52
6 changed files with 91 additions and 5 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014 the original author or authors.
* Copyright 2014-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.springframework.core.convert.converter.Converter;
import org.springframework.util.Assert;
/**
@@ -151,6 +152,25 @@ abstract class Chunk<T> implements Slice<T>, Serializable {
return content.iterator();
}
/**
* Applies the given {@link Converter} to the content of the {@link Chunk}.
*
* @param converter must not be {@literal null}.
* @return
*/
protected <S> List<S> getConvertedContent(Converter<? super T, ? extends S> converter) {
Assert.notNull(converter, "Converter must not be null!");
List<S> result = new ArrayList<S>(content.size());
for (T element : this) {
result.add(converter.convert(element));
}
return result;
}
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2008-2014 the original author or authors.
* Copyright 2008-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,8 @@
*/
package org.springframework.data.domain;
import org.springframework.core.convert.converter.Converter;
/**
* A page is a sublist of a list of objects. It allows gain information about the position of it in the containing
* entire list.
@@ -37,4 +39,13 @@ public interface Page<T> extends Slice<T> {
* @return the total amount of elements
*/
long getTotalElements();
/**
* Returns a new {@link Page} with the content of the current one mapped by the given {@link Converter}.
*
* @param converter must not be {@literal null}.
* @return a new {@link Page} with the content of the current one mapped by the given {@link Converter}.
* @since 1.10
*/
<S> Page<S> map(Converter<? super T, ? extends S> converter);
}

View File

@@ -17,6 +17,7 @@ package org.springframework.data.domain;
import java.util.List;
import org.springframework.core.convert.converter.Converter;
import org.springframework.util.Assert;
/**
@@ -30,6 +31,7 @@ public class PageImpl<T> extends Chunk<T> implements Page<T> {
private static final long serialVersionUID = 867755909294344406L;
private final long total;
private final Pageable pageable;
/**
* Constructor of {@code PageImpl}.
@@ -45,6 +47,7 @@ public class PageImpl<T> extends Chunk<T> implements Page<T> {
Assert.isTrue(total >= content.size(), "Total must not be less than the number of elements given!");
this.total = total;
this.pageable = pageable;
}
/**
@@ -93,6 +96,15 @@ public class PageImpl<T> extends Chunk<T> implements Page<T> {
return !hasNext();
}
/*
* (non-Javadoc)
* @see org.springframework.data.domain.Slice#transform(org.springframework.core.convert.converter.Converter)
*/
@Override
public <S> Page<S> map(Converter<? super T, ? extends S> converter) {
return new PageImpl<S>(getConvertedContent(converter), pageable, total);
}
/*
* (non-Javadoc)
* @see java.lang.Object#toString()

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014 the original author or authors.
* Copyright 2014-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,8 @@ package org.springframework.data.domain;
import java.util.List;
import org.springframework.core.convert.converter.Converter;
/**
* A slice of data that indicates whether there's a next or previous slice available. Allows to obtain a
* {@link Pageable} to request a previous or next {@link Slice}.
@@ -113,4 +115,13 @@ public interface Slice<T> extends Iterable<T> {
* @return
*/
Pageable previousPageable();
/**
* Returns a new {@link Slice} with the content of the current one mapped by the given {@link Converter}.
*
* @param converter must not be {@literal null}.
* @return a new {@link Slice} with the content of the current one mapped by the given {@link Converter}.
* @since 1.10
*/
<S> Slice<S> map(Converter<? super T, ? extends S> converter);
}

View File

@@ -17,6 +17,8 @@ package org.springframework.data.domain;
import java.util.List;
import org.springframework.core.convert.converter.Converter;
/**
* Default implementation of {@link Slice}.
*
@@ -28,6 +30,7 @@ public class SliceImpl<T> extends Chunk<T> {
private static final long serialVersionUID = 867755909294344406L;
private final boolean hasNext;
private final Pageable pageable;
/**
* Creates a new {@link Slice} with the given content and {@link Pageable}.
@@ -40,6 +43,7 @@ public class SliceImpl<T> extends Chunk<T> {
super(content, pageable);
this.hasNext = hasNext;
this.pageable = pageable;
}
/**
@@ -60,6 +64,15 @@ public class SliceImpl<T> extends Chunk<T> {
return hasNext;
}
/*
* (non-Javadoc)
* @see org.springframework.data.domain.Slice#transform(org.springframework.core.convert.converter.Converter)
*/
@Override
public <S> Slice<S> map(Converter<? super T, ? extends S> converter) {
return new SliceImpl<S>(getConvertedContent(converter), pageable, hasNext);
}
/*
* (non-Javadoc)
* @see java.lang.Object#toString()