I am writing a myset class that has a Array of Object. I am trying override the toString method but it is not printing the elements when I call testing.
here is the method override
#Override
public String toString()
{
if(size==0){
return "[]";
}else{
string result="["+ arr[0];
for(int i=1;i<size;i++)
{
result+=", "+arr[i];
}
}
result+="]";
return result;
}
this is the array I am Trying to call
private static Object[] arr={1, 2, 3, 4 ,5, 6, 'A', 8 , "easha", 0, 44};
System.out.print(arr);
this is how I am calling it in the main
this is the result I get
[Ljava.lang.Object;#1dbd16a6%
FYI: I have a size method that calculates the size.
I was expecting the array to look like this {1, 2, 3, 4 ,5, 6, 'A', 8 , "easha", 0, 44}
but the result is this [Ljava.lang.Object;#1dbd16a6% `
Related
This question already has answers here:
Flatten nested arrays in java
(9 answers)
Closed 3 months ago.
This question was asked to me in Razorpay. I could not come up with a solution. Can anyone help me in writing Java code for this.
Object[] array = { 1, 2, new Object[]{ 3, 4, new Object[]{ 5 }, 6, 7 }, 8, 9, 10};
Answer should be:
Integer[] = {1,2,3,4,5,6,7,8,9,10};
i.e. all the Integer elements should be stored
What I did is
for(Object obj: array){
if(obj instanceof Integer) list.add((int)(obj));
}
Which results in -> 1,2,8,9,10. How do I add 3,4,5,6,7 inside list?
As there's no finite depth of nesting of Object[] you'll need a recursive approach:
import java.util.ArrayList;
import java.util.List;
public class Answer {
static void extractIntegers(Object[] source, List<Integer> destination) {
for (Object i : source) {
if (i instanceof Object[] array) {
extractIntegers(array, destination);
} else if (i instanceof Integer integer) {
destination.add(integer);
} else {
throw new IllegalArgumentException("Unexpected: " + i);
}
}
}
public static void main(String[] args) {
List<Integer> ints = new ArrayList<>();
Object[] array = { 1, 2, new Object[]{ 3, 4, new Object[]{ 5 }, 6, 7 }, 8, 9, 10};
extractIntegers(array, ints);
System.out.println(ints);
}
}
Note that I'm using the recently added "pattern matching for instanceof" feature of Java.
You could ignore objects which are not Object[] or Integer. I've chosen to throw an excpetion.
The operation you are looking for is called flattening an array. Your input is an array of Object which can consist of either Integer or Object[]. So we have to handle both cases here, and it is easier done with recursion:
Write a function flatten(Object[] arr) that takes in an Object[] as parameter. The function will return List<Integer> which is the result after arr is flattened.
The logic is simple for the recursive flatten() function:
create empty result_array
for each obj in Object[]:
if obj is an Integer:
add obj to the result_array
else obj is Object[]:
flat_obj := flatten(obj)
add all integers of flat_obj into result_array
return result_array
Here are the Java code for the above logic implemented. Hope it helps!
public class Test {
public static List<Integer> flatten(Object[] array) {
List<Integer> result = new ArrayList<>();
for (Object o: array) {
if (o instanceof Object[])
result.addAll( flatten( (Object[]) o) );
else
result.add((Integer) o);
}
return result;
}
public static void main(String[] args) {
Object[] array = { 1, 2, new Object[]{ 3, 4, new Object[]{ 5 }, 6, 7 }, 8, 9, 10};
System.out.println( flatten(array) );
}
}
You're only checking for integers, but you also have arrays in your array.
Together with the instanceof Integer check, you should also add a check on instanceof Object[]. Be careful that also the Object[] contains an Object[]. So you'll have to have the same check inside of it as well. You shall have 3 loops in the end, each of which will have checks on instanceof Integer and instanceof Object[]
I have two list as shown below
List<Test> fisrtList= Arrays.asList(
new Test(1, 1L),
new Test(2, 3L),
new Test(2, 4L)
);
List<Long> secondList=Arrays.asList(3L, 5L);
//Find value of second list that are not in first list
Expected answer from the comparision should be 5L as it is not in firstList.
Here is my Test class
public class Test {
public Test(int id, Long idNo) {
this.id=id;
this.idNo=idNo;
}
private int id;
private Long idNo;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Long getIdNo() {
return idNo;
}
public void setIdNo(Long idNo) {
this.idNo = idNo;
}
}
How can I find the Long values from secondList that are not in the firstList?
If you want to use streams for this purpose the most efficient approach will look like this:
public static List<Long> removeIntersection(List<Long> source, List<Test> valuesToRemove) {
Set<Long> toRemove = toSet(valuesToRemove);
return source.stream()
.filter(num -> !toRemove.contains(num))
.collect(Collectors.toList());
}
private static Set<Long> toSet(List<Test> valuesToRemove) {
return valuesToRemove.stream()
.map(Test::getIdNo)
.collect(Collectors.toSet());
}
The same result could be achieved by utilizing removeAll() and retainAll() methods from the Collection interface. These methods are optimized for ArrayList and perform in a linear time.
You just have to coerce your list of test objects to a list of Long and make a copy of the second list which gonna be mutated.
To demonstrate how these methods work let's consider the following example with lists of Integer values.
removeAll() will remove all elements contained in the given collection from this collection
retainAll() will retain only elements contained in both collections
public static void main(String[] args) {
List<Integer> source = new ArrayList<>(List.of(1, 2, 3, 4, 5, 6, 7, 8, 9));
List<Integer> valuesToRemove = new ArrayList<>(List.of(1, 2, 3, 4));
source.removeAll(valuesToRemove);
System.out.println("result of removeAll: " + source);
source = new ArrayList<>(List.of(1, 2, 3, 4, 5, 6, 7, 8, 9));
List<Integer> valuesToRetain = new ArrayList<>(List.of(5, 6, 7, 8, 9));
source.retainAll(valuesToRetain);
System.out.println("result of retainAll: " + source);
}
output
result of removeAll: [5, 6, 7, 8, 9]
result of retainAll: [5, 6, 7, 8, 9]
This will do it
secondList.removeAll(firstList);
If you need secondList to not be modified you must make a deep copy first and use the deep copy instead of secondList.
Problem
I have a task that reads as follows:
Implement an IntegerList class with a Vector list object attribute that contains a collection of integers. Implement the findMedian () method which, for a given object from o of the IntegerList class, returns a number m from the vector o.list such that there are at least half of the numbers less than or equal to m, and the numbers greater than or equal to m are also at least half:
For example, for [1, 4, 1, 3, 5, 7] it will be the number 4, and for [1, 1, 1, 2, 2] it will be the number 1 and only 1. If the vector is empty then the method is supposed to throw an IllegalArgumentException exception.
What I tried?
import java.util.Vector;
public class IntegerList {
Vector<Integer> list =new Vector<Integer>();
public int findMedian(Vector<Integer>list){
if(list.size() ==0){
throw new IllegalArgumentException();
}
int result =0;
return result;
}
}
public class Main {
public static void main(String[] args){
IntegerList v = new IntegerList();
v.list.add(2);
v.list.add(3);
v.list.add(4);
v.list.add(9);
System.out.println(v.findMedian(v.list));
}
}
My question:
Why this not working?
What would you change to even better solve this problem?
It is working, but only on empty list. To make it work: we should apply what we learned ..and little try.
Voila:
public int findMedian(Vector<Integer> list) {
if (list == null || list.isEmpty()) {
throw new IllegalArgumentException("'list' is null or empty");
} // from here: list not null and list.size() > 0 ... :
// sort the "list":
java.util.Collections.sort(list); // if you may not modify the list: create a copy first! (the list remains sorted, also when leaving the method...
// return "middle" element:
return list.get(list.size()/2);
}
javadoc
I have a MutableList with generic with Int, like MutableList.
I wonder how to use kotlin call java method remove(int position) and remove(Integer object) correctly?
public void remove(int position) {
if (this.list != null && this.list.size() > position) {
this.list.remove(position);
notifyDataSetChanged();
}
}
public void remove(T t) {
if (t != null && this.list != null && !this.list.isEmpty()) {
boolean removed = false;
try {
removed = this.list.remove(t);
} catch (Exception e) {
e.printStackTrace();
}
if (removed) {
notifyDataSetChanged();
}
}
}
There are overall 4 methods for removing items in kotlin.collections.MutableList as of Kotlin 1.2.30:
remove - used to remove element once. Calls to this method are compiled to calls to the Java method List.remove(Object o).
removeAt - used to remove at a certain position. Calls to this method are compiled to calls to the Java method List.remove(int index).
removeAll - used to remove a collection, each element multiple times
removeIf - remove using a predicate, each element multiple times
Below is an example of how you can use each method. In the comments you can find what each method would print to the console and a brief explanation of what it does:
fun main(args: Array<String>) {
val l: MutableList<Int> = mutableListOf<Int>(1, 2, 3, 3, 4, 5, 6, 7, 1, 1, 1)
println(l.remove(1)) // true
println(l) // [2, 3, 3, 4, 5, 6, 7, 1, 1, 1] - removes first element and stops
println(l.removeAt(0)) // 2 - removes exactly on a specific position
println(l) // [3, 3, 4, 5, 6, 7, 1, 1, 1]
try {
println(l.removeAt(10000))
} catch(e: IndexOutOfBoundsException) {
println(e) // java.lang.IndexOutOfBoundsException: Index: 10000, Size: 9
}
println(l.removeAll(listOf(3, 4, 5))) // true
println(l) // [6, 7, 1, 1, 1] - removes elements in list multiple times, 3 removed multiple times
println(l.removeIf { it == 1 }) // true
println(l) // [6, 7] - all ones removed
}
...
true
[2, 3, 3, 4, 5, 6, 7, 1, 1, 1]
2
[3, 3, 4, 5, 6, 7, 1, 1, 1]
java.lang.IndexOutOfBoundsException: Index: 10000, Size: 9
true
[6, 7, 1, 1, 1]
true
[6, 7]
Finally i find the answer in Kotlin doc by myself. Kotlin will box generics
int to Integer if you declare the variable as Int?, because only an Object can be null.You can use the tool in android studio which can show the kotlin bytecode to find out that.
If we call java method like the question image:
val a:Int = 0
remove(a) // will call java method remove(int position)
val a:Int? = 0
remove(a) // will call java method remove(T t) to remove object
the result is different! If have better choice, we should avoid use like that.
Seems that other answers just give alternatives of remove(int position) but they didn't answer the question directly (according to the edit).
So you can use this code:
val list = mutableListOf("ah!", "I", "died!")
(list as java.util.List<String>).remove(1)
println(list)
Result:
[ah!, died!]
That's it! You've successfully invoked remove(int position) from Java.
This will raise some warnings, just ignore them.
Try it online!
Say I have two ArrayLists:
name: [Four, Three, One, Two]
num: [4, 3, 1, 2]
If I do: Arrays.sort(num), then I have:
name: [Four, Three, One, Two]
num: [1, 2, 3, 4]
Is there any way I can possibly do a sort on num and have it reflected in name as well, so that I might end up with:
name: [One, Two, Three, Four]
num: [1, 2, 3, 4]
? Please do help me out. I thought of Comparators and Objects, but barely know them at all.
You should somehow associate name and num fields into one class and then have a list of instances of that specific class. In this class, provide a compareTo() method which checks on the numerical values. If you sort the instances, then the name fields will be in the order you desire as well.
class Entity implements Comparable<Entity> {
String name;
int num;
Entity(String name, int num) {
this.name = name;
this.num = num;
}
#Override
public int compareTo(Entity o) {
if (this.num > o.num)
return 1;
else if (this.num < o.num)
return -1;
return 0;
}
}
Test code could be like this:
public static void main(String[] args) {
List<Entity> entities = new ArrayList<Entity>();
entities.add(new Entity("One", 1));
entities.add(new Entity("Two", 2));
entities.add(new Entity("Three", 3));
entities.add(new Entity("Four", 4));
Collections.sort(entities);
for (Entity entity : entities)
System.out.print(entity.num + " => " + entity.name + " ");
}
Output:
1 => One 2 => Two 3 => Three 4 => Four
Instead of sorting the actual arrays you can have an array with just indices
a[i] = i for i = 0..n
and you can sort this array based on your numeruc array with a custom comparator. e.g.
bool compare( int a, int b ) { return num[a] < num[b]; }
Thus you have both arrays sorted by using these indices.
If you don't have repeated elements, then you could just use a sorted Map like a TreeMap instead:
int[] num = {4, 3, 1, 2};
String[] name = {"Four", "Three", "One", "Two"};
TreeMap<Integer,String> sortedMap = new TreeMap<Integer,String>();
for (int i=0; i<num.length; i++) sortedMap.put(num[i], name[i]);
// Resulting sortedMap: {1=One, 2=Two, 3=Three, 4=Four}
If you do have repeated elements then this won't work because the keys of the map must be unique.
In some cases it doesn't make much sense to create a new class just to do multiple sorts based off a given list. I've created a function that does this, but I've posted the code in a another SO post so I wont repeat it. Below is an example of how to use it.
Usage
Here is an example of how you can use the function to sort multiple lists of arbitrary types:
// The key can be any type that implements Comparable, Dupes are allowed
List<Integer> key = Arrays.asList(4, 3, 1, 2, 1);
// List Types do not need to be the same
List<String> list1 = Arrays.asList("Four", "Three", "One", "Two", "One");
List<Character> list2 = Arrays.asList('d', 'c', 'a', 'b', 'a');
// Sorts key, list1, list2 using key as the sorting key.
keySort(key, key, list1, list2);
Output:
key: [1, 1, 2, 3, 4]
list1: [One, One, Two, Three, Four]
list2: [a, a, b, c, d]