Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #38519 > unrolled thread
| Started by | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| First post | 2018-08-07 06:00 -0700 |
| Last post | 2018-08-14 05:47 -0700 |
| Articles | 3 on this page of 23 — 5 participants |
Back to article view | Back to comp.lang.java.programmer
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
Page 2 of 2 — ← Prev page 1 [2]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2018-08-14 05:49 -0700 |
| Message-ID | <99c4af45-54be-4dce-9b5f-729b15262a7e@googlegroups.com> |
| In reply to | #38558 |
On Tuesday, August 14, 2018 at 8:07:03 AM UTC-4, Robert Klemme wrote:
> I could not agree more. A few more thoughts:
>
> It seems the class design can be improved, e.g. by separating out the
> "8-10 fields that make up the address" in a class of its own. That
> could have proper hashCode() and equals() implementations and maybe a
> default order (once Eric catches up on the basics).
>
> I also think the flags should be removed altogether (basically leading
> to the same result as above) since the sort order is determined by the
> user ("One user wants to see all mail to addresses first, another needs
> to see ship to addresses first."), i.e. it is not part of the
> (presumably persistent) data but rather of the _use_ of it (i.e. viewing
> on the screen or processing it for some purpose). There should
> definitively be a Comparable instance that can be used as a Map key for
> the different orders supported. Definitively use specific classes for
> keys instead of abusing toString() for this!
>
> Cheers
>
> robert
>
I don't know about messing with the hashcode. It does seem the simplest thing is a custom method to return the comparable value and a separate custom comparator class.
[toc] | [prev] | [next] | [standalone]
| From | Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> |
|---|---|
| Date | 2018-08-09 16:06 +0200 |
| Message-ID | <pkhhsd$mgd$1@dont-email.me> |
| In reply to | #38519 |
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 ) )
);
}
}
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2018-08-14 05:47 -0700 |
| Message-ID | <bde9ba10-8e73-4f41-b717-12c438044ed7@googlegroups.com> |
| In reply to | #38550 |
On Thursday, August 9, 2018 at 10:08:24 AM UTC-4, Daniele Futtorovic wrote: > 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. Thanks, will check that out, but will have to wait if it doesn't run in Java 8. I tried setting up my Eclipse for Java 9 which didn't go so well, but we will soon need to get something newer working as Java 11 is coming.
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.lang.java.programmer
csiph-web