0

I am trying to create an array of unique values based on the properties of a number of identical Objects. These properties will have identical values, but some of them will be null, like so:

Object obj1 = new Object("Value 1", "Value 2", null);
Object obj2 = new Object("Value 1", null, "Value 3");
Object obj3 = new Object(null, "Value2", "Value3")

Object Class

public class Object {
   private String value1;
   private String value2;
   private String value3;

   // Constructor
   public Object(String value1, String value2, String value3){ // this.value1... }

   // Getters & Setters
}

(These Objects can have n number of properties, but assume just 3 for this question)

How can I take the above 3 objects (or any number objects) and quickly combine (or sample) each of their properties to create the below array?

["Value 1", "Value 2", "Value 3"] 

I'm thinking a Set could be useful here, but I'm not quite sure how to approach it

7
  • 2
    How does your object class look like? Commented Mar 14, 2018 at 19:12
  • 1
    You need logic to determine uniqueness and/or equality. Commented Mar 14, 2018 at 19:13
  • @AmitBera assume it has just 3 String properties Commented Mar 14, 2018 at 19:15
  • I need to know how you have stored those values in your object class. Is your object class constructor is a varargs constructor and you are assigning all the passed values to any array? How can get the passed values from your object? Commented Mar 14, 2018 at 19:16
  • @KuraiBankusu He said it could be n number of properties Commented Mar 14, 2018 at 19:17

3 Answers 3

1

I assume your Object look like this :

class MyObject {

    private String[] inputs;

    public MyObject(String... inputs) {
        this.inputs = inputs;
    }
    //Getters Setter

}

If you are using Java 8 you can use :

MyObject obj1 = new MyObject("Value 1", "Value 2", null);
MyObject obj2 = new MyObject("Value 1", null, "Value 3");
MyObject obj3 = new MyObject(null, "Value 2", "Value 3");

Set<String> result = Arrays.asList(obj1, obj2, obj3)
        .stream()
        .flatMap(item -> Stream.of(item.getInputs()))
        .filter(item -> item != null)
        .collect(Collectors.toSet());

System.out.println(result);

Outputs

[Value 3, Value 1, Value 2]
Sign up to request clarification or add additional context in comments.

Comments

1

Try the below solution :

public class Main {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        MyObject obj1 = new MyObject("Value 1", "Value 2", null);
        MyObject obj2 = new MyObject("Value 1", null, "Value 3");
        MyObject obj3 = new MyObject(null, "Value 2", "Value 3");

        System.out.println(myObjectPropToStringArray(obj1,obj2,obj3));


    }

    public static Set<String> myObjectPropToStringArray(MyObject... myObject) {
        Set<String> result = new HashSet<>();
        Arrays.stream(myObject).forEach(e ->{

            result.add(e.getValue1());
            result.add(e.getValue2());
            result.add(e.getValue3());
        });
        return result;
    }
}

 class MyObject {
       private String value1;
       private String value2;
       private String value3;



    public MyObject(String value1, String value2, String value3) {
        super();
        this.value1 = value1;
        this.value2 = value2;
        this.value3 = value3;
    }

    public String getValue1() {
        return value1;
    }

    public void setValue1(String value1) {
        this.value1 = value1;
    }

    public String getValue2() {
        return value2;
    }

    public void setValue2(String value2) {
        this.value2 = value2;
    }

    public String getValue3() {
        return value3;
    }

    public void setValue3(String value3) {
        this.value3 = value3;
    }
 }

1 Comment

I would advise against using side effects to add to the result set and instead use flatMap with Streams.of(e.getValue1(), e.getValue2(), e.getValue3()) followed by collect(Collectors.toSet())
0

If your intention is just to pick all distinct values in each field of those objects, then you can work with lists of each field's values:

List<Object> objects = Arrays.asList(new Object("Value 1", "Value 2", null), 
          new Object("Value 1", null, "Value 3"), 
          new Object(null, "Value2", "Value3");

//This should give you the first list...
List<String> values = objects.stream().map(o ->
             Arrays.asList(o.getVal1(), o.getVal2(), o.getVal3()))
             .distinct()
             .findFirst().get();

//If you need to prefer non-null values, then you can use
//an ordered stream:
List<String> values = objects.stream()
            .map(o ->
                 Arrays.asList(o.getVal1(), o.getVal2(), o.getVal3()))
            .distinct().ordered(list -> 
                (list.get(0) != null ? -1 : 1)
              + (list.get(1) != null ? -1 : 1)
              + (list.get(2) != null ? -1 : 1))
            .findFirst()
            .get();

The comparator implementation is just to make non-null values come at the beginning of the stream so that findFirst can hit them first. Of course you will need to check if the optional has a value.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.