Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #38550
| Path | csiph.com!eternal-september.org!feeder.eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail |
|---|---|
| From | Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> |
| Newsgroups | comp.lang.java.programmer |
| Subject | Re: Is there a better way to group and sort objects? |
| Date | Thu, 9 Aug 2018 16:06:59 +0200 |
| Organization | A noiseless patient Spider |
| Lines | 285 |
| Message-ID | <pkhhsd$mgd$1@dont-email.me> (permalink) |
| References | <8c045ff4-98c5-4253-9136-b26b34cf8f77@googlegroups.com> |
| Mime-Version | 1.0 |
| Content-Type | text/plain; charset=utf-8 |
| Content-Transfer-Encoding | 7bit |
| Injection-Date | Thu, 9 Aug 2018 14:08:13 -0000 (UTC) |
| Injection-Info | reader02.eternal-september.org; posting-host="17451a47b8cd9bd681876d7a42321b59"; logging-data="23053"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19aS8bxUjDMPJ5zinCukKPy" |
| User-Agent | Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 |
| Cancel-Lock | sha1:kHrbd6XpA4EUgiV85PSbM8V6eCQ= |
| In-Reply-To | <8c045ff4-98c5-4253-9136-b26b34cf8f77@googlegroups.com> |
| X-Antivirus-Status | Clean |
| Content-Language | en-GB |
| X-Antivirus | AVG (VPS 180808-4, 08/08/2018), Outbound message |
| Xref | csiph.com comp.lang.java.programmer:38550 |
Show key headers only | View raw
On 2018-08-07 15:00, Eric Douglas wrote:
> I want to combine and sort objects by key properties and merge their secondary properties. Is there a better way? This is what I came up with..
<snip />
I was bored, so here's some code. Omitted imports and most of the
argument and null checks. Also, you might need Java 9 to run it.
public class ScratchPad {
private static final class GroupBy<T, P> {
private final String name;
private final Function<T, P> extractor;
private final BinaryOperator<P> accumulatorFunction;
private final Supplier<P> initialValueSupplier;
public GroupBy( String name, Function<T, P> extractor,
BinaryOperator<P> accumulatorFunction, Supplier<P> initialValueSupplier ) {
this.name = name;
this.extractor = extractor;
this.accumulatorFunction = accumulatorFunction;
this.initialValueSupplier = initialValueSupplier;
}
public GroupBy( String name, Function<T, P> extractor,
BinaryOperator<P> accumulatorFunction ) {
this( name, extractor, accumulatorFunction, null );
}
public String name(){ return name; }
public Function<T, P> extractor() {
return extractor;
}
public BinaryOperator<P> accumulatorFunction() {
return accumulatorFunction;
}
public Accumulator<T, P> newAccumulator(){
return new Accumulator<>(
this,
initialValueSupplier == null ? null :
initialValueSupplier.get()
);
}
}
private static final class Accumulator<T, P> {
private final GroupBy<T, P> groupBy;
private P accumulation;
public Accumulator( GroupBy<T, P> groupBy ) {
this.groupBy = groupBy;
}
public Accumulator( GroupBy<T, P> groupBy, P initialValue ) {
this( groupBy );
accumulation = initialValue;
}
public String groupByName(){ return groupBy.name(); }
public P accumulation(){ return accumulation; }
public P accumulate( T t ){
P newVal = groupBy.extractor().apply(t);
return accumulation = accumulation == null ? newVal :
groupBy.accumulatorFunction().apply( accumulation, newVal );
}
}
private static final class GroupAndSort<T, K extends Comparable<K>> {
private final Function<T, K> keyExtractor;
private final List<GroupBy<T, ?>> merged;
private final SortedMap<K, List<Accumulator<T, ?>>>
sieve = new TreeMap<>()
;
@SafeVarargs
public static <T, K extends Comparable<K>> GroupAndSort<T, K>
newInstance(
Class<T> itemClass, Function<T, K> keyExtractor, GroupBy<T,
?>... merges
){
return new GroupAndSort<>( keyExtractor, List.of( merges ) );
}
public GroupAndSort( Function<T, K> keyExtractor,
Collection<GroupBy<T, ?>> merges ){
this.keyExtractor = keyExtractor;
List<GroupBy<T, ?>> accs = new ArrayList<>();
accs.add(
new GroupBy<T, List<T>>(
null,
List::of,
(old, niou) -> {
old.addAll( niou );
return old;
},
ArrayList::new
)
);
Set<String> groupNames = new HashSet<>();
for( GroupBy<?, ?> g: merges ){
if( g.name() == null ){
throw new IllegalArgumentException( "null groupBy
name: " + g );
}
if( ! groupNames.add(g.name()) ){
throw new IllegalArgumentException( "Duplicate
groupBy name: " + g.name() );
}
}
accs.addAll( merges );
this.merged = List.copyOf( accs );
}
public void put( T item ){
K key = keyExtractor.apply( item );
sieve.compute(
key,
(k, list) -> {
if( list == null ){
list = merged.stream().map(
GroupBy::newAccumulator ).collect(Collectors.toList());
}
list.forEach( acc -> acc.accumulate(item) );
return list;
}
);
}
@SafeVarargs
public final void putAll( T... items ){
for( T item: items ) this.put( item );
}
public Stream<K> keys(){
return sieve.keySet().stream();
}
@SuppressWarnings( "unchecked" )
public Stream<T> items(){
return sieve.values().stream().flatMap( (l) ->
((Collection<T>)l.get(0).accumulation()).stream() );
}
@SuppressWarnings( "unchecked" )
public Stream<T> items( K key ){
List<Accumulator<T, ?>> props = sieve.get( key );
if( props == null ){
return Stream.empty();
}
else {
return
((Collection<T>)props.get(0).accumulation()).stream();
}
}
public List<?> mergedPropertiesFor( K key ){
List<Accumulator<T, ?>> props = sieve.get( key );
if( props == null ){
return Collections.emptyList();
}
else {
return props.stream().skip(1).map(
Accumulator::accumulation ).collect(Collectors.toList());
}
}
public Map<String, ?> mergedPropertyMapFor( K key ){
List<Accumulator<T, ?>> props = sieve.get( key );
if( props == null ){
return null;
}
else {
return props.stream().skip(1).collect(
Collectors.toMap( Accumulator::groupByName,
Accumulator::accumulation )
);
}
}
}
private static final class TestObject {
private final String id;
private final int sortingKey;
private final int intProperty;
private final boolean boolProperty;
public TestObject( String id, int sortingKey, int intProperty,
boolean boolProperty ) {
this.id = id;
this.sortingKey = sortingKey;
this.intProperty = intProperty;
this.boolProperty = boolProperty;
}
public String id(){ return id; }
public int sortingKey() {
return sortingKey;
}
public int someIntProperty() {
return intProperty;
}
public boolean someBoolProperty() {
return boolProperty;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder( "TestObject{" );
sb.append( "id='" ).append( id ).append( '\'' );
sb.append( ", sortingKey=" ).append( sortingKey );
sb.append( ", intProperty=" ).append( intProperty );
sb.append( ", boolProperty=" ).append( boolProperty );
sb.append( '}' );
return sb.toString();
}
}
public static void main( String[] ss ){
TestObject t1 = new TestObject( "t1", 1, 34907, true );
TestObject t2 = new TestObject( "t2", 1, 4, false );
TestObject t3 = new TestObject( "t3", 10, 1, true );
TestObject t4 = new TestObject( "t4", 4, 8, false );
GroupAndSort<TestObject, Integer> group = GroupAndSort.newInstance(
TestObject.class,
TestObject::sortingKey,
new GroupBy<>( "intProperty", TestObject::someIntProperty,
Integer::sum ),
new GroupBy<>( "boolProperty", TestObject::someBoolProperty,
Boolean::logicalAnd )
);
group.putAll( t1, t3, t4, t2 );
System.err.println( "Items: " +
group.items().collect(Collectors.toList()) );
System.err.println( "Keys: " +
group.keys().collect(Collectors.toList()) );
System.err.println( "Grouped items:" );
group.keys().forEach(
key -> System.err.printf( "%s -> %s%n", key,
group.items(key).collect(Collectors.toList()) )
);
System.err.println( "Merged properties:" );
group.keys().forEach(
key -> System.err.printf( "%s -> %s%n", key,
group.mergedPropertiesFor( key ) )
);
System.err.println( "Merged property maps:" );
group.keys().forEach(
key -> System.err.printf( "%s -> %s%n", key,
group.mergedPropertyMapFor( key ) )
);
}
}
Back to comp.lang.java.programmer | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
Is there a better way to group and sort objects? Eric Douglas <e.d.programmer@gmail.com> - 2018-08-07 06:00 -0700
Re: Is there a better way to group and sort objects? Eric Sosman <esosman@comcast-dot-net.invalid> - 2018-08-07 09:44 -0400
Re: Is there a better way to group and sort objects? Eric Sosman <esosman@comcast-dot-net.invalid> - 2018-08-07 11:33 -0400
Re: Is there a better way to group and sort objects? Eric Douglas <e.d.programmer@gmail.com> - 2018-08-07 10:22 -0700
Re: Is there a better way to group and sort objects? Eric Sosman <esosman@comcast-dot-net.invalid> - 2018-08-07 14:16 -0400
Re: Is there a better way to group and sort objects? Eric Sosman <esosman@comcast-dot-net.invalid> - 2018-08-07 14:36 -0400
Re: Is there a better way to group and sort objects? Eric Douglas <e.d.programmer@gmail.com> - 2018-08-07 12:13 -0700
Re: Is there a better way to group and sort objects? Eric Sosman <esosman@comcast-dot-net.invalid> - 2018-08-07 16:00 -0400
Re: Is there a better way to group and sort objects? Martin Gregorie <martin@mydomain.invalid> - 2018-08-08 08:20 +0000
Re: Is there a better way to group and sort objects? Eric Sosman <esosman@comcast-dot-net.invalid> - 2018-08-08 06:57 -0400
Re: Is there a better way to group and sort objects? Martin Gregorie <martin@mydomain.invalid> - 2018-08-08 11:08 +0000
Re: Is there a better way to group and sort objects? Martin Gregorie <martin@mydomain.invalid> - 2018-08-08 11:22 +0000
Re: Is there a better way to group and sort objects? Eric Sosman <esosman@comcast-dot-net.invalid> - 2018-08-08 07:45 -0400
Re: Is there a better way to group and sort objects? Martin Gregorie <martin@mydomain.invalid> - 2018-08-08 14:12 +0000
Re: Is there a better way to group and sort objects? Eric Douglas <e.d.programmer@gmail.com> - 2018-08-08 05:50 -0700
Re: Is there a better way to group and sort objects? Eric Sosman <esosman@comcast-dot-net.invalid> - 2018-08-08 09:23 -0400
Re: Is there a better way to group and sort objects? Eric Douglas <e.d.programmer@gmail.com> - 2018-08-08 06:47 -0700
Re: Is there a better way to group and sort objects? Eric Sosman <esosman@comcast-dot-net.invalid> - 2018-08-08 10:31 -0400
Re: Is there a better way to group and sort objects? Eric Douglas <e.d.programmer@gmail.com> - 2018-08-08 08:24 -0700
Re: Is there a better way to group and sort objects? Robert Klemme <shortcutter@googlemail.com> - 2018-08-14 14:06 +0200
Re: Is there a better way to group and sort objects? Eric Douglas <e.d.programmer@gmail.com> - 2018-08-14 05:49 -0700
Re: Is there a better way to group and sort objects? Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2018-08-09 16:06 +0200
Re: Is there a better way to group and sort objects? Eric Douglas <e.d.programmer@gmail.com> - 2018-08-14 05:47 -0700
csiph-web