-6

For example:

Public Class SomeClass{
      private String value1;
private String value2;
private String value3;
private Double value4;
//getters & setters of above
}

Consider the input ArrayList of Object(SomeClass): Object has variables of type String,String,String and double

`List<SomeClass> inputList = [{a,b,c,32.14},{d,e,f,47.50},{g,h,i,60.23}{j,k,l,47.69},{d,e,f,15.56},{a,b,c,25.41}];`

Consider 2 objects in inputList : {a,b,c,32.14},{a,b,c,25.41}

If variables of object {a,b,c,32.14} String,String,String.equals(String,String,String) of other objects {a,b,c,25.41} just sum their double value and convert it into single object {a,b,c,57.55}.

As a result of above I would like to have result in some ArrayList of object:

List<SomeClass> outputList = [{a,b,c,57.55},{d,e,f,62.66},{g,h,i,60.23},{j,k,l,47.69}];

Please let me know the logic to implement the above scenario?Nested for loop will be fine

3 Answers3

1

Use a hashMap and check if this key already exists then update the double value by adding existing double value then put in the map.

public static void main(String[] args) {
    List<MyObject> list = new ArrayList<MyObject>();
    list.add(new MyObject("a","b","c",new BigDecimal(10.23)));
    list.add(new MyObject("a","b","e",new BigDecimal(10.23)));
    list.add(new MyObject("a","b","c",new BigDecimal(10.23)));
    list.add(new MyObject("a","b","d",new BigDecimal(10.23)));
    Map<MyObject,MyObject> map = new HashMap<MyObject,MyObject>(){
       @Override
    public MyObject put(MyObject key, MyObject value) {
           //synchronize if required
        if (containsKey(key)) {
            value.addDouble(get(key).myDouble);
        }
        return super.put(key, value);
    }
    };

 for (MyObject obj:list) {
        map.put(obj, obj);
    }
    for (MyObject obj : map.values())
    System.out.println(obj);
}

Output:

abd10.230000000000000426325641456060111522674560546875
abc20.460000000000000852651282912120223045349121093750
abe10.230000000000000426325641456060111522674560546875

Make sure to use hashCode and equals only on first 3 properties. Not on double.

class MyObject {
    String myProp1;
    String myProp2;
    String myProb3;
    BigDecimal myDouble;

    public MyObject(String myProp1, String myProp2, String myProb3, BigDecimal myDouble) {
        super();
        this.myProp1 = myProp1;
        this.myProp2 = myProp2;
        this.myProb3 = myProb3;
        this.myDouble = myDouble;
    }
    public void addDouble(BigDecimal addValue) {
        myDouble = myDouble.add(addValue);
    }
    @Override
    public int hashCode() {
        final int PRIME = 31;
        int result = 1;
        result = PRIME * result + ((myProb3 == null) ? 0 : myProb3.hashCode());
        result = PRIME * result + ((myProp1 == null) ? 0 : myProp1.hashCode());
        result = PRIME * result + ((myProp2 == null) ? 0 : myProp2.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        final MyObject other = (MyObject) obj;
        if (myProb3 == null) {
            if (other.myProb3 != null)
                return false;
        } else if (!myProb3.equals(other.myProb3))
            return false;
        if (myProp1 == null) {
            if (other.myProp1 != null)
                return false;
        } else if (!myProp1.equals(other.myProp1))
            return false;
        if (myProp2 == null) {
            if (other.myProp2 != null)
                return false;
        } else if (!myProp2.equals(other.myProp2))
            return false;
          return true;
        }
      }
Tschallacka
  • 27,901
  • 14
  • 88
  • 133
Gaurava Agarwal
  • 974
  • 1
  • 9
  • 32
  • 1
    The equals and hashCode method can be simplified using `java.util.Objects` class. Look at my answer or code here https://www.codiva.io/p/cb3a388d-41dd-43b6-8ee6-1dd7f5f1df19 – JackDaniels Jul 18 '16 at 07:50
  • @Gaurava Agarwal what is the int PRIME initalized in hashcode method?and why 31? – sundaresan.c Jul 18 '16 at 09:58
  • Please see this post for explanation on PRIME: http://stackoverflow.com/questions/3613102/why-use-a-prime-number-in-hashcode – Gaurava Agarwal Jul 18 '16 at 09:59
  • @Gaurava Agarwal List **list** = new ArrayList(); where did you use **list** in the new HashMap ? – sundaresan.c Jul 18 '16 at 12:36
  • @sundaresan.c, I have added required code and output as well. Please vote up if it is helpful. – Gaurava Agarwal Jul 19 '16 at 02:02
  • Your code almost works .myDouble not getting added. Its showing input value itself. In output I am not getting summed value of mydouble. why did you use bigdecimal instead of double? @GauravaAgarwal . – sundaresan.c Jul 19 '16 at 10:07
  • Moreover I am using class variables with getters & setters for each parameters. Does the usage of constructor really necessary here? @GauravaAgarwal – sundaresan.c Jul 19 '16 at 10:21
  • You can check answer of both questions at stack overflow itself. I have shown you output of this code as is. See combination abc has updated Double value in map. Can you upload your code – Gaurava Agarwal Jul 19 '16 at 11:01
  • @GauravaAgarwal . I have used SomeClass as : Public Class SomeClass{ private String value1; private String value2; private String value3; private Double value4; //with getters & setters of above } Note: **I can't use constructors here** – sundaresan.c Jul 19 '16 at 11:22
  • @GauravaAgarwal . please suggest addDouble method in your answer for input parameter with double as datatype – sundaresan.c Jul 19 '16 at 11:37
  • @GauravaAgarwal . Thanks . Its working . I have slightly modified addDouble method. – sundaresan.c Jul 19 '16 at 12:12
1

First, define the equals and hashCode methods. Advise: Don't reimplement the wheel. Just use java.util.Objects class' equals and hash methods. That reduces a large number of errors.

@Override
public boolean equals(Object obj) {
  if (obj == null)
  {
     return false;
  }
  if (getClass() != obj.getClass())
  {
     return false;
  }
  final SomeClass other = (SomeClass) obj;

  return   Objects.equals(this.value1, other.value1)
        && Objects.equals(this.value2, other.value2)
        && Objects.equals(this.value3, other.value3);

}

For the combiner, use the Java 8's groupingBy method that groups by the key (which is identity in this case) and the you can define the value to be summing of the value4 field.

List<SomeClass> list = new ArrayList<>();
list.add(new SomeClass("a", "b", "c", 12.4));
list.add(new SomeClass("a", "b", "c", 31.4));
list.add(new SomeClass("c", "b", "c", 12.4));
list.add(new SomeClass("d", "b", "c", 12.4));


Function<SomeClass,SomeClass> identity = Function.identity();
Map<SomeClass, Double> map = list.stream()
    .collect(Collectors.groupingBy(identity,
        Collectors.summingDouble(SomeClass::getValue4)));

List<SomeClass> result = new ArrayList<>(map.entrySet().stream()
    .collect(Collectors.toMap(Map.Entry::getKey,
         e -> new SomeClass(e.getKey(), e.getValue()))).values());
System.out.println(result);

The full code in Codiva online java complier IDE.

JackDaniels
  • 985
  • 9
  • 26
-1

Implement hashCode and equals methods in your object and try to add object in set it will provide you desire output.

@Override
public boolean equals(Object obj) {
    MyObject newObj = (MyObject)obj;

    if (newObj.getA().equals(this.getA()) && newObj.getB().equals(this.getB()) && newObj.getC().equals(this.getC())){
        newObj.setDoubleValue(this.getDoubleValue()+newObj.getDoubleValue());
        return true;
    }
    return false;
}

@Override
public int hashCode() {
    return 1;
}
Rakesh
  • 139
  • 7
  • equals and hashcode need lot of improvements. You can see generated hashCode equals from IDE. To this particular question, its important to not use DoubleValue. – Gaurava Agarwal Jul 18 '16 at 07:41
  • That was sample code.. did not mean to use it directly – Rakesh Jul 18 '16 at 08:31
  • Everyone should take care what they are referring. And thanks for your suggestions **will keep that in mind** – Rakesh Jul 19 '16 at 06:14