How to change a instance in a set - java

I have the following Set, I would like to replace any instance that is multiple of 10 by the string "10". Can anyone guide me in the right direction please.
Set<Integer> set3 = new HashSet<Integer>();
for(int i = 0; i<10; i++){
Random ran = new Random();
number = 1+ran.nextInt(1000);
set3.add(number);
}

You can try this
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.stream.Stream;
public class ReplaceIntegers {
public static void main(String[] args) {
Set<Integer> set3 = new HashSet<>();
Set<Object> objectSet = new HashSet<>();
Random generator = new Random();
for(int i = 0; i < 1000; i++) {
set3.add(1+generator.nextInt(1000));
}
set3.stream()
.filter(n -> n%10 == 0)
.forEach(n -> objectSet.add(n.toString()));
objectSet.stream()
.forEach(v -> System.out.println(v));
for(Integer i : set3) {
if(i%10 == 0)
System.out.println(i + " is a multiple of 10");
else
System.out.println("Number: " + i);
}
}
}
Patrick

The output is going to be a mixed set of integers and strings, so the method signature you're writing is going to look like:
Set<Object> foo(Set<Integer> input);
First let's write the algorithm the easy way, in Scala, then we'll convert it to Java. You want to change each item in the collection, so that's a map operation.
def foo(s: Set[Int]): Set[Any] = s map { i => if (i % 10 == 0) "10" else i }
In Java 8, it's similar, but you have to convert the Set to a Stream to do the mapping, and then back to a Set again.
static Set<Object> foo(Set<Integer> s) {
return s.stream()
.map(i -> i % 10 == 0 ? "10" : i)
.collect(Collectors.toSet());
}
If you want to go back to Java 7, you don't even have streams, or lambdas to make defining the map operation feasible, so you just have to understand how map is defined and then implement it procedurally in your code.
static Set<Object> foo(Set<Integer> s) {
Set<Object> result = new HashSet<>();
for (Integer i : s) {
result.add(i % 10 == 0 ? "10" : i);
}
return result;
}
The Java 5-6 solution is almost the same, just without the diamond syntax:
static Set<Object> foo(Set<Integer> s) {
Set<Object> result = new HashSet<Object>();
for (Integer i : s) {
result.add(i % 10 == 0 ? "10" : i);
}
return result;
}
And in Java 3-4 you lose the for loop, autounboxing, and generics...
static Set foo(Set s) {
Set result = new HashSet();
Iterator it = s.iterator();
while (it.hasNext()) {
Integer i = (Integer) it.next();
Object o = i;
if (i.intValue() % 10 == 0) o = "10";
result.add(o);
}
return result;
}

Set<Integer> set3 = new HashSet<Integer>();
Set<Object> set4 = new HashSet<Object>();
for(Integer integer: set3){
if(integer%10==0){
set4.add(integer.toString());
} else {
set4.add(integer);
}
};
set3=set4;
You are unable to put String into Set<Integer>, you should decrease the specificity of the type to the closest common parent class of both String and Integer - Object. In addition, I would strongly discourage using "replace" (remove+add) on a Set you are iterating through: this can lead to potential problems with data consistency. Just copy your elements in another Set and then replace the original one.

Related

Combine values of a list of data that are almost equal

so i asked before but it seems i wasnt clear enough of what im talking about, so im trying to make it clearer now:
what im trying to do is prepare data for an import. the data i get is human made an not very efficient, so im removing unnecessary entrys and try to combine the data as much as possible.
its for something like a configurator. the data i get looks something like this:
123 : 45 : AB = 12
This means: if Option 1 is 1 OR 2 OR 3 and Option 2 is 4 OR 5 and Option 3 is A OR B the result will be 1 AND 2
i created a class thats something like this:
Class Options{
String opt1;
String opt2;
String opt3;
String optResult;
//and some other stuff
boolean hasSameOptions(Options o){
return opt1.equals(o.opt1) && opt2.equals(o.opt2) && opt3.equals(o.opt3);
}
public void AddOptions(String options) {
for (String s : options.split("")) {
if (!optResult.contains(s)) {
optResult = optResult + s;
}
}
}
}
now, the data is repetitive and can be combined. Like:
12 : 45 : AB = 12
12 : 45 : AB = 3
12 : 45 : AB = 4
This would mean actually mean: 12 : 45 : AB = 1234
So, what i do is break the Strings apart to get only single values with the result, for example:
1 : 4 : A = 12
1 : 4 : B = 12
1 : 5 : A = 12
//and so on.
I make a list of all these Values and then try to Combine them again to get more efficient List.
The first step i do is get all Objects who have the same Options but different Results and combine the results. that happens like this:
public static List<Options> cleanList(List<Options> oldList) {
List<Options> newList = new ArrayList<>();
for (Options item : oldList) {
Options temp = findEqualOptions(newList, item);
if (temp != null)
temp.AddOptions(item.optResult);
else
newList.add(item);
}
return newList;
}
public static <T> T findByProperty(Collection<T> col, Predicate<T> filter) {
return col.stream().filter(Objects::nonNull).filter(filter).findFirst().orElse(null);
}
public static Options findEqualOptions(List<Options> list, Options opt) {
return findByProperty(list, d -> d.hasSameOptions(opt));
}
After that, i try to compress the list even more, by combining elements who have only ONE different value. For example:
1 : 2 : A = 12
1 : 3 : A = 12
-> 1 : 23 : A = 12
i do it like this:
for (int i = 0; i < list.size(); i++) {
for (int j = i + 1; j < list.size(); j++) {
Option o1 = list.get(i);
Option o2 = list.get(j);
int diff1 = 0;
int diff2 = 0;
int diff3 = 0;
int diff4 = 0;
if(!o1.opt1.equals(o2.opt1))
diff1 = 1;
if(!o1.opt2.equals(o2.opt2))
diff2 = 1;
//and so on
if((diff1+diff2+diff3+diff4)>1)
continue;
if(diff1 == 1)
o1.opt1 = o1.opt1 + o2.opt1;
//and so on...
list.remove(j--);
}
}
i do this until there are no more changes. It works well, but slowly. especially the method cleanList().
does anybody have any idea how to make it better? i tried to use a stream to get the whole list of equals options directly like this:
public static <T> List<T> findByMultipleValue(Collection<T> col, Predicate<T> filter) {
return col.stream().filter(filter).collect(Collectors.toList());
}
public static List<Options> getEqualOptionsList(List<Options> optList, Options opt){
return findByMultipleValue(optList, o -> o.hasSameOptions(opt));
}
but that made it A LOT slower.
PS. : its not the complete code, just an example of what im trying to do. I hope it is more understandable this time :)
probably not the most elegant or optimal solution but here is already a quick approach that give the result based on your description. It use the HashMap as proposed in the comment of #Joseph Larson
I went for a set of char to ensure values are not duplicate in it but feel free to adapt :)
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
class Scratch {
public static class Option{
String opt1;
String opt2;
String opt3;
String optResult;
public Option(String opt1, String opt2, String opt3, String optResult) {
this.opt1 = opt1;
this.opt2 = opt2;
this.opt3 = opt3;
this.optResult = optResult;
}
public static String merge(String a, String b){
StringBuilder value = new StringBuilder();
Set<Character> result = new HashSet<>();
for(char c : a.toCharArray()){
result.add(c);
}
for(char c : b.toCharArray()){
result.add(c);
}
for(char c : result){
value.append(c);
}
return value.toString();
}
public Option(Option a, Option b) {
this(merge(a.opt1, b.opt1), merge(a.opt2, b.opt2), merge(a.opt3, b.opt3), merge(a.optResult, b.optResult));
}
String getKey(){
return String.join(":", opt1, opt2, opt3);
}
int distance(Option option){
int diff1 = this.opt1.equals(option.opt1)?0:1;
int diff2 = this.opt2.equals(option.opt2)?0:1;
int diff3 = this.opt3.equals(option.opt3)?0:1;
int diff4 = this.optResult.equals(option.optResult)?0:1;
return diff1 + diff2 + diff3 + diff4;
}
public String toString(){
return getKey();
}
}
public static void main(String[] args) {
Option[] data = new Option[]{
new Option("12", "45", "AB", "12"),
new Option("12", "45", "AB", "3"),
new Option("12", "45", "AB", "4"),
new Option("12", "45", "AC", "1"),
new Option("12", "45", "AC", "12"),
new Option("3", "45", "AC", "13"),
new Option("12", "45", "AD", "12"),
};
mergeExact(data);
mergeClose(data, 1);
}
private static void mergeClose(Scratch.Option[] data, int distance){
Map<Option, Set<Character>> buffer = new HashMap<>();
for(Option option : data) {
boolean found = false;
Option toDelete = null;
for(Map.Entry<Option, Set<Character>> entry : buffer.entrySet()){
if(option.distance(entry.getKey()) <= distance){
Option merged = new Option(entry.getKey(), option);
for(char c : option.optResult.toCharArray()){
entry.getValue().add(c);
}
buffer.put(merged, entry.getValue());
toDelete = entry.getKey();
found = true;
break;
}
}
if(found) {
buffer.remove(toDelete);
}else{
Set<Character> set = new HashSet<>();
for(char c : option.optResult.toCharArray()){
set.add(c);
}
buffer.put(option, set);
}
}
System.out.println(String.format("merge with distance of %d:: %s", distance, buffer));
}
private static void mergeExact(Scratch.Option[] data) {
Map<String, Set<Character>> buffer = new HashMap<>();
for(Option option : data){
Set<Character> item = buffer.computeIfAbsent(option.getKey(), k -> new HashSet<>());
for(char c : option.optResult.toCharArray()){
item.add(c);
}
}
System.out.println("exact merge:: "+buffer);
}
}
output is
exact merge:: {3:45:AC=[1, 3], 12:45:AD=[1, 2], 12:45:AC=[1, 2], 12:45:AB=[1, 2, 3, 4]}
merge with distance of 1:: {12:45:AB=[1, 2, 3, 4], 3:45:AC=[1, 3], 12:45:ACD=[1, 2]}
EDIT: missed a part of the question, updating to add the merge when difference is close. This part is probably even worst that the first one in terms of optimisation but it's a working bases :)

Java 8 for each and first index

Anyone knows how to achieve following piece code in a Java 8 way respectively is there any stream methods to detect the first element in a forEach?
List<String> myList = new ArrayList<String>();
myList.add("A");
myList.add("B");
int i = 0;
for (final String value : myList) {
if (i == 0) {
System.out.println("Hey that's the first element");
}
System.out.println(value);
i++;
}
Java8:
myList.stream().forEach(value -> {
// TODO: How to do something special for first element?
System.out.println(value);
});
Furthermore, let's says that the goal is the following (console output):
A Something special
B
C
D
E
F
May this work for you?
myList.stream().findFirst().ifPresent(e -> System.out.println("Special: " + e));
myList.stream().skip(1).forEach(System.out::println);
Output:
Special: A
B
Alternative:
myList.stream().findFirst().ifPresent(e -> somethingSpecial(e));
myList.stream().forEach(System.out::println);
I don't think there is something provided in stream.
There are several alternatives you may consider:
Method 1:
int[] i = {0}; // I am using it only as an int holder.
myList.stream().forEach(value -> {
if (i[0]++ == 0) {
doSomethingSpecial;
}
System.out.println(value);
});
Method 2:
If your list is quick for random access (e.g. ArrayList), you may consider:
IntStream.range(0, myList.size())
.forEach(i -> {
ValueType value = myList.get(i);
if (i == 0) {
doSomethingSpecial();
}
System.out.println(value);
});
Try StreamEx
StreamEx.of("A", "B", "C") //
.peekFirst(e -> System.out.println(e + " Something special")).skip(1) //
.forEach(System.out::println);
If you were trying to achieve it in a single stream statement, here's how I'd do it:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
public class Solution {
public static void main(String[] args) {
List<String> myList = new ArrayList<>();
myList.add("A");
myList.add("B");
myList.add("C");
myList.add("D");
myList.add("E");
myList.add("F");
AtomicBoolean firstElementProcessed = new AtomicBoolean(false);
myList.stream().map(s -> {
if (firstElementProcessed.getAndSet(true)) {
return s;
}
return (s + " Something special");
}).forEach(System.out::println);
}
}
And maybe for better readability, I'd refactor it to:
public class Solution {
...
AtomicBoolean firstElementProcessed = new AtomicBoolean(false);
myList.stream().map(s -> getString(firstElementProcessed, s)).forEach(System.out::println);
}
private static String getString(AtomicBoolean firstElementProcessed, String s) {
if (firstElementProcessed.getAndSet(true)) {
return s;
}
return (s + " Something special");
}
}
Something like
List<String> mylist = Arrays.asList("A", "B", "C", "D", "E", "F");
Optional<String> findFirst = mylist.stream().findFirst();
findFirst.ifPresent(i -> System.out.println("Hey! " + i + ", that's the first element"));
mylist.stream().skip(1).forEach(System.out::println);
There is no reason to not use simple for loop, foreach is is pretty but limited to side effects.

How to create combinations of values in Java?

I have the following map: Map<Integer,String[]> map = new HashMap<Integer,String[]>();
The keys are integers and the values are arrays (could also be replaced by lists).
Now, I would like to get all possible combinations of the values among the keys. For example, let's say the map contains the following entries:
key 1: "test1", "stackoverflow"
key 2: "test2", "wow"
key 3: "new"
The combinations consists of
("test1","test2","new")
("test1","wow","new")
("stackoverflow", "test2", "new")
("stackoverflow", "wow", "new")
For this I imagine a method boolean hasNext() which returns true if there is a next pair and a second method which just returns the next set of values (if any).
How can this be done? The map could also be replaced by an other data structure.
The algorithm is essentially almost the same as the increment algorithm for decimal numbers ("x -> x+1").
Here the iterator class:
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.TreeSet;
public class CombinationsIterator implements Iterator<String[]> {
// Immutable fields
private final int combinationLength;
private final String[][] values;
private final int[] maxIndexes;
// Mutable fields
private final int[] currentIndexes;
private boolean hasNext;
public CombinationsIterator(final Map<Integer,String[]> map) {
combinationLength = map.size();
values = new String[combinationLength][];
maxIndexes = new int[combinationLength];
currentIndexes = new int[combinationLength];
if (combinationLength == 0) {
hasNext = false;
return;
}
hasNext = true;
// Reorganize the map to array.
// Map is not actually needed and would unnecessarily complicate the algorithm.
int valuesIndex = 0;
for (final int key : new TreeSet<>(map.keySet())) {
values[valuesIndex++] = map.get(key);
}
// Fill in the arrays of max indexes and current indexes.
for (int i = 0; i < combinationLength; ++i) {
if (values[i].length == 0) {
// Set hasNext to false if at least one of the value-arrays is empty.
// Stop the loop as the behavior of the iterator is already defined in this case:
// the iterator will just return no combinations.
hasNext = false;
return;
}
maxIndexes[i] = values[i].length - 1;
currentIndexes[i] = 0;
}
}
#Override
public boolean hasNext() {
return hasNext;
}
#Override
public String[] next() {
if (!hasNext) {
throw new NoSuchElementException("No more combinations are available");
}
final String[] combination = getCombinationByCurrentIndexes();
nextIndexesCombination();
return combination;
}
private String[] getCombinationByCurrentIndexes() {
final String[] combination = new String[combinationLength];
for (int i = 0; i < combinationLength; ++i) {
combination[i] = values[i][currentIndexes[i]];
}
return combination;
}
private void nextIndexesCombination() {
// A slightly modified "increment number by one" algorithm.
// This loop seems more natural, but it would return combinations in a different order than in your example:
// for (int i = 0; i < combinationLength; ++i) {
// This loop returns combinations in the order which matches your example:
for (int i = combinationLength - 1; i >= 0; --i) {
if (currentIndexes[i] < maxIndexes[i]) {
// Increment the current index
++currentIndexes[i];
return;
} else {
// Current index at max:
// reset it to zero and "carry" to the next index
currentIndexes[i] = 0;
}
}
// If we are here, then all current indexes are at max, and there are no more combinations
hasNext = false;
}
#Override
public void remove() {
throw new UnsupportedOperationException("Remove operation is not supported");
}
}
Here the sample usage:
final Map<Integer,String[]> map = new HashMap<Integer,String[]>();
map.put(1, new String[]{"test1", "stackoverflow"});
map.put(2, new String[]{"test2", "wow"});
map.put(3, new String[]{"new"});
final CombinationsIterator iterator = new CombinationsIterator(map);
while (iterator.hasNext()) {
System.out.println(
org.apache.commons.lang3.ArrayUtils.toString(iterator.next())
);
}
It prints exactly what's specified in your example.
P.S. The map is actually not needed; it could be replaced by a simple array of arrays (or list of lists). The constructor would then get a bit simpler:
public CombinationsIterator(final String[][] array) {
combinationLength = array.length;
values = array;
// ...
// Reorganize the map to array - THIS CAN BE REMOVED.
I took this as a challenge to see whether the new Java 8 APIs help with these kind of problems. So here's my solution for the problem:
public class CombinatorIterator implements Iterator<Collection<String>> {
private final String[][] arrays;
private final int[] indices;
private final int total;
private int counter;
public CombinatorIterator(Collection<String[]> input) {
arrays = input.toArray(new String[input.size()][]);
indices = new int[arrays.length];
total = Arrays.stream(arrays).mapToInt(arr -> arr.length)
.reduce((x, y) -> x * y).orElse(0);
counter = 0;
}
#Override
public boolean hasNext() {
return counter < total;
}
#Override
public Collection<String> next() {
List<String> nextValue = IntStream.range(0, arrays.length)
.mapToObj(i -> arrays[i][indices[i]]).collect(Collectors.toList());
//rolling carry over the indices
for (int j = 0;
j < arrays.length && ++indices[j] == arrays[j].length; j++) {
indices[j] = 0;
}
counter++;
return nextValue;
}
}
Note that I don't use a map as an input as the map keys actually don't play any role here. You can use map.values() though to pass in the input for the iterator. With the following test code:
List<String[]> input = Arrays.asList(
new String[] {"such", "nice", "question"},
new String[] {"much", "iterator"},
new String[] {"very", "wow"}
);
Iterator<Collection<String>> it = new CombinatorIterator(input);
it.forEachRemaining(System.out::println);
the output will be:
[such, much, very]
[nice, much, very]
[question, much, very]
[such, iterator, very]
[nice, iterator, very]
[question, iterator, very]
[such, much, wow]
[nice, much, wow]
[question, much, wow]
[such, iterator, wow]
[nice, iterator, wow]
[question, iterator, wow]

Is there a way to compare two objects in a List and combine their values that is most optimal?(Java)

Quick question. Suppose I have a function total (List list) and I have a MyObject class that have a String and an int displayed below and I want to compare two different object Strings in my total method. If they are the same, add the value on both of them. Otherwise, do nothing.
For example data is
{[Johanna, 200], [Jack, 205], [Johanna, 100], [Jack, 50]};
The output should look like
{[Johanna, 300], [Jack, 255]};
public static class MyObject {
int value;
String name;
public MyObject(String nm, int val)
{
name = nm;
value = val;
}
}
public void total(List<MyObject> list) {
List<MyObject> newList = new ArrayList<MyObject>();
Collections.sort(list);
Iterator<Order> ItrL = list.iterator();
int index = 0;
while(ItrL.hasNext())
{
MyObject compare = ItrL.next();
Iterator<MyObject> ItrR = list.listIterator(index);
index++;
while (cmp.name.equals(ItrR.next().name)))
newList.add(new MyObject(cmp.name, cmp.value + ItrR.value));
}
}
You can do summing and comparisons in parallel with no need to sort first using streams.
List<MyObject> newList = Arrays.asList(
new MyObject("Johanna", 200),
new MyObject("Jack", 205),
new MyObject("Johanna", 100),
new MyObject("Jack", 50)
);
Map<String,Integer> map =
newList.stream().parallel()
.collect(Collectors.groupingBy(mo -> mo.name,
Collectors.summingInt(mo -> mo.value)));
System.out.println("map = " + map);
There is no method that is "most optimal" as it depends on how big the data is. The problem seems suitable for map-reduce, but if you have like only 4 elements, then the overhead cost doesn't justify a real map reduce algorithm.
So anyway, here's one alternative that is pre-Java 8 (list doesn't need to be sorted first):
public static Map<String, Integer> total(List<MyObject> list) {
Map<String, Integer> result = new HashMap<String, Integer>();
for (MyObject myObject : list) {
Integer prevValue = result.get(myObject.name);
if (prevValue == null) {
result.put(myObject.name, myObject.value);
} else {
result.put(myObject.name, myObject.value + prevValue);
}
}
return result;
}
You can reduce from n^2 to n*(n/2) by using
for(int i = 0 ...
for(int j = i + 1 ...

Is it possible to find out if a value exists twice in an arraylist?

I have an integer arraylist..
ArrayList <Integer> portList = new ArrayList();
I need to check if a specific integer has already been entered twice. Is this possible in Java?
You could use something like this to see how many times a specific value is there:
System.out.println(Collections.frequency(portList, 1));
// There can be whatever Integer, and I use 1, so you can understand
And to check if a specific value is there more than once you could use something like this:
if ( (Collections.frequency(portList, x)) > 1 ){
System.out.println(x + " is in portList more than once ");
}
My solution
public static boolean moreThanOnce(ArrayList<Integer> list, int searched)
{
int numCount = 0;
for (int thisNum : list) {
if (thisNum == searched)
numCount++;
}
return numCount > 1;
}
If you are looking to do this in one method, then no. However, you could do it in two steps if you need to simply find out if it exists at least more than once in the List. You could do
int first = list.indexOf(object)
int second = list.lastIndexOf(object)
// Don't forget to also check to see if either are -1, the value does not exist at all.
if (first == second) {
// No Duplicates of object appear in the list
} else {
// Duplicate exists
}
This will tell you if you have at least two same values in your ArrayList:
int first = portList.indexOf(someIntValue);
int last = portList.lastIndexOf(someIntValue);
if (first != -1 && first != last) {
// someIntValue exists more than once in the list (not sure how many times though)
}
If you really want to know how many duplicates of a given value you have, you need to iterate through the entire array. Something like this:
/**
* Will return a list of all indexes where the given value
* exists in the given array. The list will be empty if the
* given value does not exist at all.
*
* #param List<E> list
* #param E value
* #return List<Integer> a list of indexes in the list
*/
public <E> List<Integer> collectFrequency(List<E> list, E value) {
ArrayList<Integer> freqIndex = new ArrayList<Integer>();
E item;
for (int i=0, len=list.size(); i<len; i++) {
item = list.get(i);
if ((item == value) || (null != item && item.equals(value))) {
freqIndex.add(i);
}
}
return freqIndex;
}
if (!collectFrequency(portList, someIntValue).size() > 1) {
// Duplicate value
}
Or using the already availble method:
if (Collections.frequency(portList, someIntValue) > 1) {
// Duplicate value
}
Set portSet = new HashSet<Integer>();
portSet.addAll(portList);
boolean listContainsDuplicates = portSet.size() != portList.size();
I used the following solution to find out whether an ArrayList contains a number more than once. This solution comes very close to the one listed by user3690146, but it does not use a helper variable at all. After running it, you get "The number is listed more than once" as a return message.
public class Application {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(4);
list.add(8);
list.add(1);
list.add(8);
int number = 8;
if (NumberMoreThenOnceInArray(list, number)) {
System.out.println("The number is listed more than once");
} else {
System.out.println("The number is not listed more than once");
}
}
public static boolean NumberMoreThenOnceInArray(ArrayList<Integer> list, int whichNumber) {
int numberCounter = 0;
for (int number : list) {
if (number == whichNumber) {
numberCounter++;
}
}
if (numberCounter > 1) {
return true;
}
return false;
}
}
Here is my solution (in Kotlin):
// getItemsMoreThan(list, 2) -> [4.45, 333.45, 1.1, 4.45, 333.45, 2.05, 4.45, 333.45, 2.05, 4.45] -> {4.45=4, 333.45=3}
// getItemsMoreThan(list, 1)-> [4.45, 333.45, 1.1, 4.45, 333.45, 2.05, 4.45, 333.45, 2.05, 4.45] -> {4.45=4, 333.45=3, 2.05=2}
fun getItemsMoreThan(list: List<Any>, moreThan: Int): Map<Any, Int> {
val mapNumbersByElement: Map<Any, Int> = getHowOftenItemsInList(list)
val findItem = mapNumbersByElement.filter { it.value > moreThan }
return findItem
}
// Return(map) how often an items is list.
// E.g.: [16.44, 200.00, 200.00, 33.33, 200.00, 0.00] -> {16.44=1, 200.00=3, 33.33=1, 0.00=1}
fun getHowOftenItemsInList(list: List<Any>): Map<Any, Int> {
val mapNumbersByItem = list.groupingBy { it }.eachCount()
return mapNumbersByItem
}
By looking at the question, we need to find out whether a value exists twice in an ArrayList. So I believe that we can reduce the overhead of "going through the entire list just to check whether the value only exists twice" by doing the simple check below.
public boolean moreThanOneMatch(int number, ArrayList<Integer> list) {
int count = 0;
for (int num : list) {
if (num == number) {
count ++ ;
if (count == 2) {
return true;
}
}
}
return false;
}

Categories