0

Edit2: : I have main data(list or array,it's no matter) like this:

{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}

I want to:

1-replace all values containing 3 with "julie"

2-all values that are val % 15 == 0 should be replaced with "jack".

3-also replace all values that are val % 5 == 0 should be replaced with "john" ,

Note: Without If Else Just With Java 8.

In the end I should have this data :

("1","2","julie","4","john","6","7","8","9","john","11","12","julie","14","jack","16","17","18","19","john")

for this issue I use stream and replaced these values with related string and i created 3 related list for each string:

1-Result for need1(replace all values containing 3 with "julie"): ("1","2","julie","4","5","6","7","8","9","10","11","12","julie","14","15","16","17","18","19","20")

2-Result for need2(all values that are val % 15 == 0 should be replaced with "jack"): ("1","2","3","4","5","6","7","8","9","10","11","12","13","14","jack","16","17","18","19","20")

3-Result for need3(replace all values that are val % 5 == 0 should be replaced with "john") :("1","2","3","4","john","6","7","8","9","john","11","12","13","14","john","16","17","18","19","john")

Now I want to have a final result such as below(either with mereg these lists or any other method without If&Else just with java8): :

("1","2","julie","4","john","6","7","8","9","john","11","12","julie","14","jack","16","17","18","19","john")

Thanks!

mi_mo
  • 135
  • 1
  • 8
  • 2
    How are these lists created originally? It seems like you should create a more appropriate data structure to begin with rather than trying to do it after the fact. Many programming tasks can be simplified by using the correct data structure. In this case, a list that contains names and numbers seems strange. Usually lists should be homogenous. That is they should contain a sequence of similar kinds of items. – Code-Apprentice May 24 '22 at 21:09
  • 1
    Your expected output does not adequately explain your criteria for merging the lists. Please provide more detail. – WJS May 24 '22 at 22:47
  • i updated the question could you review again, tnx – mi_mo May 25 '22 at 06:28
  • 1
    `val % 15 == 0` *should be replaced with `"jack"`* - then why `"jack"` appear in place of `2` and `9`? – Alexander Ivanchenko May 25 '22 at 14:13
  • 1
    `just the string fields must be replaced with pure value` - this phrase is not clear at all. By looking at example of the resulting list I assume that you need to obtain a list of the same size as previous three, and at each position where names like `"john"`, `"julie"` or `"jack"` appear in one of the lists they should take residence over the numbers. Where this guessing is correct or not you should edit the question to clarify it. And it is still not clear how resolve the case when two name would appear at the same position. Both `"john"` and `"jack"` would clash at index `15`. – Alexander Ivanchenko May 25 '22 at 14:23
  • Ok, you said *all values containing 3 should be replaced with Julie*. What does containing mean? Contains the digit or is divisible by 3? And why was 6 replaced and not 9 in the first list? And why do you stop at 11? Can you just post the challenge as it was presented to you? – WJS May 25 '22 at 15:16
  • Ok. also explain how you get `("1","jack","3","4","5","6","7","8","jack","10","11")` by applying `val % 15 == 0 should be replaced with "jack" ` Why di d you replace `2` and `9` with `jack`? – WJS May 25 '22 at 15:30
  • Sorry for my unclear question, I added more samples and edited the question with a more clear objective – mi_mo May 25 '22 at 20:42
  • What to do with 30? Julie? Jack? John? – Jean-Baptiste Yunès May 27 '22 at 16:33
  • @Jean-BaptisteYunès That was addressed in the last sentence of my answer. Order of evaluation is important. Since the test for `3` comes first, it would be `julie`. – WJS May 27 '22 at 16:36

5 Answers5

2

Ok, based on your clarification I can create the final String like so.

Here is how to merge the three lists per your criteria.

String[] arr1 = { "1", "2", "julie", "4", "5", "6", "7", "8",
        "9", "10", "11", "12", "julie", "14", "15", "16",
        "17", "18", "19", "20" };
String[] arr2 = { "1", "2", "3", "4", "5", "6", "7", "8", "9",
        "10", "11", "12", "13", "14", "jack", "16", "17",
        "18", "19", "20" };
String[] arr3 = { "1", "2", "3", "4", "john", "6", "7", "8",
        "9", "john", "11", "12", "13", "14", "john", "16",
        "17", "18", "19", "john" };
  • IntStream from 0 to size of array
  • check if each array element equals julie or jack and use the match
  • otherwise, it must be either john or an unfilled space so use that.
String[] merged = IntStream.range(0, arr1.length)
        .mapToObj(i->
                arr1[i].equals("julie") ? "julie" :
                arr2[i].equals("jack") ? "jack" : arr3[i])
        .toArray(String[]::new);

System.out.println(Arrays.toString(merged));

prints

[1, 2, julie, 4, john, 6, 7, 8, 9, john, 11, 12, julie, 14, jack, 16, 17, 18, 19
, john]

I think you may be able to do it straight from the data like so.

  • create a list of values and shuffle them. They could also be just random.
  • stream them and apply your criteria and return an array.
List<Integer> list = new ArrayList<>(IntStream.range(0, 21).boxed().toList());
Collections.shuffle(list);
System.out.println(list);

String[] result = list.stream()
        .map(i -> Integer.toString(i).contains("3") ?
                "julie" : i % 15 == 0 ? "jack" :
                i % 5 == 0 ? "john" : i + "")
        .toArray(String[]::new);
            
System.out.println(Arrays.toString(result));

Prints the source data and the result

[17, 9, 13, 8, 16, 19, 0, 6, 3, 1, 7, 2, 11, 4, 15, 20, 12, 18, 14, 5, 10]

[17, 9, julie, 8, 16, 19, jack, 6, julie, 1, 7, 2, 11, 4, jack, john, 12, 18, 14
, john, john]

Note: Based on your updated answer I tested in the order provided in 1,2,and 3. Anything divisible by 15 will be divisible by 5. This is also true for 30 which contains '3' and is divisible by 5 and 15. So the order in which one checks is important.

WJS
  • 36,363
  • 4
  • 24
  • 39
  • thanks, but I want to be able to do this solution on my main data which could have variable items: for example `23,10,1,15,2,6,29` and for any inputted data, the algorithm is same. right now you do solution just on data that are from 0 to 20 and these are constant – mi_mo May 25 '22 at 21:39
  • BTW, did you try the merge function. It is independent of the range from 0 to 20. – WJS May 25 '22 at 21:45
  • @JWS yes this is important, but i mentioned it in my question I said I have main data like this not exactly this and this will be constant – mi_mo May 25 '22 at 21:48
  • Okay, are the names constant? Can the name data start with a digit? – WJS May 25 '22 at 21:50
  • yes the names are constant, just inputted data can be variable between some integers – mi_mo May 25 '22 at 21:52
  • Well, I think my merge may work for you. – WJS May 25 '22 at 21:53
  • Thanks dude, your solution worked and your treat is very good. – mi_mo May 25 '22 at 22:21
1

Edit 1: I am not sure what you mean with:

merge all of them into each other and duplicate values should not be deleted to have below list

I am assuming you mean to return a list whose values are present in all three lists (common elements shared by all lists) which also includes the duplicate values inside respective lists.

Maybe you can find the intersection between 3 lists (finding common elements among them) and then append the duplicates value from each list - However, one can think of a case where all the lists contain same duplicate values e.g list1 = [1 1], list2 = [1 1] and list3 = [1 1]. How many 1s do you want on your final result?)

    // merge lists together - only common elements
    List<String> intersect = list1
        .stream()
        .filter(list2::contains)
        .filter(list3::contains)
        .collect(Collectors.toList());
    
    // iterate through your lists
    List<List<String>> listAll = Arrays.asList(list1, list2, list3);
    for (List<String> list: listAll) {
        // find duplicates inside each the list
        Set<String> items = new HashSet<>();
        List<String> duplicateValue = list
           .stream()
           .filter(n -> !items.add(n))
           .collect(Collectors.toList());
        // add to the duplicate to the final result
        intersect.addAll(duplicateValue);
        intersect.addAll(duplicateValue);
    }
    

Output: [1, 4, 7, 8, 11, julie, julie, john, john, jack, jack] where 1, 4, 7, 8, 11 are common on all lists, while the names are duplicates in respective single list


However, if you just want to merge all values of the lists together, there are a couple of ways you can do that:

Use Stream (https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html) to combine the lists. Create a stream with lists and then flatten it to retrieve all elements

List<String> uniqueList = Stream.of(list1, list2, list3)
    .flatMap(Collection::stream).collect(Collectors.toList());

or

List<String> uniqueList = new ArrayList<>();
Stream.of(list1, list2, list3).forEach(joinedList::addAll);

See this related question for more details: Combine multiple lists in Java

besjon_c
  • 170
  • 2
  • 12
  • This doesn't work. Do you see a 3,5, 6, or 10 in the expected output? – WJS May 24 '22 at 22:57
  • I am waiting for him to clarify the question. From my first understanding of the question it appears he just want to combine the lists. The expected resulting list is a bit weird though. Maybe he is trying to return a list whose values are present in all three lists and also the duplicate values inside respective lists are preserved. – besjon_c May 24 '22 at 23:02
  • I edited the answer to also satisfy the expected output – besjon_c May 25 '22 at 00:02
  • i updated the question could you review again, tnx – mi_mo May 25 '22 at 06:29
1

You can use this approach to get the result

Stream<Integer> list = Stream.of(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
    String result = list
            .map(String::valueOf)
            .map(s -> s.equals("3") ? "julie" : s)
            .map(s -> ( StringUtils.isNumeric(s) ? ((Integer.parseInt(s)%15)==0 ? "jack":s):s))
            .map(s -> ( StringUtils.isNumeric(s) ? ((Integer.parseInt(s)%5)==0 ? "jack":s):s))
            .collect(Collectors.joining(","));
    System.out.print(result);

Console output

1,2,julie,4,jack,6,7,8,9,jack,11,12,13,14,jack,16,17,18,19,jack
0

I want to merge all of them into each other and duplicate values should not be deleted

If you want to preserve only duplicates and each element should appear only once in the resulting list, you can create an intermediate map Map<String, Boolean>, that would associate each unique string with a boolean value denoting whether it is a duplicate or not.

Then create a stream over the set of map entries, filter out the duplicates and collect the remained keys into a list.

List<String> result = Stream.of(collect1, collect2, collect3)
    .flatMap(List::stream)
    .collect(Collectors.toMap(
        Function.identity(),
        str -> false,         // first occurence - key isn't proved to be a duplicate
        (left, right) -> true // is a duplicate
    ))
    .entrySet().stream()
    .filter(Map.Entry::getValue)
    .map(Map.Entry::getKey)
    .collect(Collectors.toList());
Alexander Ivanchenko
  • 25,667
  • 5
  • 22
  • 46
0

How about this:

public void solution() {
        Integer[] integers = new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
        List<String> numbers = Stream.of(integers).map(this::yourMappingFunction).collect(Collectors.toList());
        LOG.info("numbers: {}", numbers);
        // prints [1, 2, julie, 4, john, 6, 7, 8, 9, john, 11, 12, julie, 14, john, 16, 17, 18, 19, john]
    }

    // in the same class
    public String yourMappingFunction(Integer integer) {
        // write needed if conditions here and return the needed string for each
        // condition
        if (integer.toString().contains("3")) {
            return "julie";
        } else if (integer % 5 == 0) {
            return "john";
        } else if (integer % 15 == 0) {
            return "jack";
        } else {
            return integer.toString();
        }
    }
gunescelil
  • 313
  • 1
  • 23
  • do you read question after edit? could you describe more with at least one example? tnx – mi_mo May 25 '22 at 20:47
  • So the main question is to not use if and else? How can somebody write a conditional logic without writing a if or else? – gunescelil May 25 '22 at 20:51
  • İs switch allowed? I am asking this because even method `contains` should be using `if` in its implementation – gunescelil May 25 '22 at 20:51
  • Are you also aware that some of the conditions intersect? For example 15 holds for val % 5 == 0 and val % 15 == 0 which one you should keep? – gunescelil May 25 '22 at 20:55
  • yes, i wrote this part1 code with stream like this: `Arrays.stream(strvals1).map(x -> x.contains("3") ? "julie" : x).toArray(String[]::new);` and about your second comment i replace 15 with related string at the first to not to be considering in the step `val % 5 == 0` statatment – mi_mo May 25 '22 at 20:56
  • btw I did not write this code in IDE please correct if there is a typo – gunescelil May 25 '22 at 21:00
  • no there is not any issue i copy this code from IDE without any problems just consider strvals1 is a `String[] strvals1 = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"};` – mi_mo May 25 '22 at 21:03
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/245057/discussion-between-gunescelil-and-milad-mofidii). – gunescelil May 25 '22 at 21:03
  • I tried in IDE and wrote the result in the answer – gunescelil May 25 '22 at 21:20
  • dear @gunescelil I said i must just use java8 features without using If statement, I already wrote your solution myself . – mi_mo May 25 '22 at 21:44
  • Ok bruh but I really dont understand how can somebody write a condition without using an if? What I mean, even if you use contains, equals methods they all have if checks inside them. What kind of use case there is? – gunescelil May 26 '22 at 02:26