How to convert Collection<Number> to Collection<Integer> safety? - java

I have Collection<Number> but I needed Collection<Integer>
How can I convert it safety?
And more common issue:
How to convert Collection<Parent> to Collection<Child>

You can try this
Collection<Number> numbers = ...
Collection<Integer> integers = numbers.getClass().newInstance();
for(Number n : numbers) {
integers.add(n == null ? null : n.intValue());
}

Example with Guava :
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
Collection<Number> collection = ...
return Collections2.transform(collection, new Function<Number, Integer>() {
#Nullable
#Override
public Integer apply(#Nullable Number input) {
if(input == null) {
return null;
}
return input.intValue();
}
});
Note : Guava is an external lib, you will need to import it it.

You could do it with something like this convert method -
public static Collection<Integer> convert(Collection<Number> in) {
List<Integer> al = new ArrayList<Integer>();
for (Number n : in) {
if (n != null) {
al.add(n.intValue());
}
}
return al;
}

You can use instanceof operator.Try this
Iterator<Number> itr = collection.iterator();
while(itr.hasNext())
{
Number number = itr.next();
if(number instanceof Integer)
{
Integer value = (Integer)number ;
System.out.print("Integer is "+value );
}
}

For each loop to iterate the collection having any numeric data type and then individually insert converting those numeric data types into Integer one's into another collection.
List<Integer> i = new ArrayList<Integer>();
for (Number n : in){
i.add(n.intValue());
}}

Related

How to change a instance in a set

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.

How to Sort a String list which contains integer

I want to sort a list of String that also contains numbers.
For example, I have a list containing elements "1,2,3,4,5,11,12,21,22,31,32,A101,A102,A103,A104,B405".
If i use Collection.sort method means output is "1,11,12,2,21,22,3,31,32... ".
If i use Comparator function means it gives
output as "1,2,3,4,5,11,12,21,22,31,32,A101... ".
But i need to display as
"A101,A102,A103,A104,B405,1,2,3,4,5,11,12,21,22,31,32"
Please any one give me a solution. Thanks in advance.
Implement your own comparator that tries to convert the objects to be compared to an integer, and if succesful, uses the compareTo of the Integer class, and otherwise uses the compareTo of the String class.
Like this:
public class MyComparator implements Comparator<String,String>
{
public int compare(String s1, String s2)
{
try
{
int i1 = Integer.parseInt(s1);
int i2 = Integer.parseInt(s2);
return i1 - i2;
}
catch (NumberFormatException e)
{
return s1.compareTo(s2);
}
}
}
ArrayList<String> myList = (...);
Collections.sort(myList,new MyComparator());
As commented, this sorts like this 1,12,A102,A103. But wanted is: A102,A103,1,12. To do this we need to take care of situations where s1 is parsable as int and s2 is not and the other way around. I'm not sure if I got -1 and 1 right, so maybe they should be swapped.
public class MyComparator implements Comparator<String,String>
{
public int compare(String s1, String s2)
{
Integer i1 = null
Integer i2 = null
try
{
i1 = Integer.parseInt(s1);
}
catch (NumberFormatException e) {}
try
{
i2 = Integer.parseInt(s2);
}
catch (NumberFormatException e) {}
if (i1 == null && i2 == null)
return s1.compareTo(s2);
if (i1 == null && i2 != null)
return -1;
if (i1 != null && i2 == null)
return 1;
return i1 - i2;
}
}
Create a new "holder" object for the strings and implement the Comparable interface. Override the "compareTo" method. That should do the trick ;)
Answer is present there in your question, just create two lists and sort them separately!
package com.kvvssut.misc;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class SortStringThenNumber {
public static void main(String[] args) {
List<String> inputs = Arrays.asList(new String[]{"1","5","3","4","2","11","11","21","31","32","22","A101","A103","A104","B405","A102"});
List<Object> result = sortStringThenNumber(inputs);
for (Object sorted : result) {
System.out.println(String.valueOf(sorted));
}
}
private static List<Object> sortStringThenNumber(List<String> inputs) {
List<Integer> numbers = new ArrayList<Integer>();
List<String> strings = new ArrayList<String>();
for (String input : inputs) {
if (input.matches("-?\\d+")) {
numbers.add(Integer.valueOf(input));
} else {
strings.add(input);
}
}
inputs = null;
Collections.sort(numbers);
Collections.sort(strings);
ArrayList<Object> all = new ArrayList<Object>();
all.addAll(strings);
all.addAll(numbers);
return all;
}
}

How to differentiate String and Integer in ArrayList?

I have array list like this
ArrayList list = new ArrayList();
list.add("somethingold");
list.add(3);
list.add("somethingnew");
list.add(5);
Now if I print the list output will be like:
[somethingold, 3, somethingnew, 5 ]
Here i want to fetch only integer elements.
I want the output like, if it is an integer put it in some other list, else in one more list.
This is what i want:
[3,5]
[somethingold, somethingnew]
have you tried this?:
if(list.get(0) instanceof Integer) {
// is an integer
} else if (list.get(0) instanceof String) {
// is a String
}
Looping through each element in List
for loop:
for (int i = 0; i < list.size(); i++) {
if (list.get(i) instanceof Integer) {
// do your stuff
}
if (list.get(i) instanceof String) {
// do your stuff
}
}
for-each loop:
for (Object obj: list) {
if (obj instanceof Integer) {
// do your stuff
}
...
}
You can achieve it using instanceof operator.
for (Object object : list)
{
if(object instanceof Integer)
{
System.out.println(object); // Integer
}
else if(object instanceof String)
{
System.out.println(object); // String
}
}
its very simple. Just two lines of code
string[] stringList = list.OfType<string>().ToArray();
Int32[] intList = list.OfType<Int32>().ToArray();
It is recommended that should create typed Collection like List<Integer> or List<String> if you are using java 1.5+.
In case of generic array you can use instanceOf operator to differentiate .
for(Object obj: list){
if(obj instanceOf Ineteger){
...
}else if(obj instanceOf String){
...
}
}
you are trying to go over the JDK API , that was one of the most important reason why Generics were introduced in java, to provide you type safe collections.
And you have no need to worry while adding or fetching the elements(no explicit typecasting required).
A friendly suggestion go by the book.
Thanks
You want [3,5] [somethingold, somethingnew] which looks already like 2 separate lists.
So you could do
class IntegersAndStrings {
private final List<String> strings = new ArrayList<String>();
private final List<Integer> ints = new ArrayList<Integer>();
public void add(int i) {
ints.add(Integer.valueOf(i));
}
public void add(String s) {
strings.add(s);
}
#Override
public String toString() {
return ints.toString() + strings.toString();
}
}
and use it like before
class Main {
public static void main(String[] args) {
IntegersAndStrings list = new IntegersAndStrings();
list.add("somethingold");
list.add(3);
list.add("somethingnew");
list.add(5);
System.out.println(list);
}
}
and the output would be
[3, 5][somethingold, somethingnew]
You have to fetch list of objects by using for-loop, in that you can find out string and integers.
Below example shows how to get the values..
ArrayList list = new ArrayList();
for (Object o : list) {
if (o.getClass().equals(Integer.TYPE)) {
...
}
else if (o.getClass().equals(String.class)) {
...
}
}
Collections.sort(list);
int index = 0;
for (Object obj: list) {
index ++;
if (obj instanceof String) {
break;
}
}
List<Integer> integerList = list.subList(0.index);
List<String> stringList = list.subList(index,list.size());
System.out.println(integerList);
System.out.println(stringList);
Try this, i hope it works
Using guava library you can do it like this:
System.out.println(
Iterators.toString(Iterators.filter(list.iterator(), String.class)));
System.out.println(
Iterators.toString(Iterators.filter(list.iterator(), Integer.class)));

Compare strings in two different arraylist (JAVA)

This is a pice of my code :
ArrayList<String> Alist= new ArrayList<String>();
ArrayList<String> Blist= new ArrayList<String>();
Alist.add("gsm");
Alist.add("tablet");
Alist.add("pc");
Alist.add("mouse");
Blist.add("gsm");
Blist.add("something");
Blist.add("pc");
Blist.add("something");
so i have two array list i want to compare all items and check if they are not equal and if they are to print out only the items that are not equal.
so i make something like this:
http://postimage.org/image/adxix2i13/
sorry for the image but i have somekind of bug when i post here a for looop.
and the result is :
not equals..:tablet
not equals..:pc
not equals..:mouse
not equals..:gsm
not equals..:tablet
not equals..:pc
not equals..:mouse
not equals..:gsm
not equals..:tablet
not equals..:pc
not equals..:mouse
not equals..:gsm
not equals..:tablet
i want to print only the 2 that are not equal in the example they are gsm and pc
not equals..:gsm
not equals..:pc
Don't use != to compare strings. Use the equals method :
if (! Blist.get(i).equals(Alist.get(j))
But this wouldn't probably fix your algorithmic problem (which isn't clear at all).
If what you want is know what items are the same at the same position, you could use a simple loop :
int sizeOfTheShortestList = Math.min(Alist.size(), Blist.size());
for (int i=0; i<sizeOfTheShortestList; i++) {
if (Blist.get(i).equals(Alist.get(i))) {
System.out.println("Equals..: " + Blist.get(i));
}
}
If you want to get items that are in both lists, use
for (int i = 0; i < Alist.size(); i++) {
if (Blist.contains(Alist.get(i))) {
System.out.println("Equals..: " + Alist.get(i));
}
}
You can use the RemoveAll(Collection c) on one of the lists, if you happen to know if one list always contains them all.
You could use the following code:
ArrayList<String> Alist = new ArrayList<String>();
ArrayList<String> Blist = new ArrayList<String>();
Alist.add("gsm");
Alist.add("tablet");
Alist.add("pc");
Alist.add("mouse");
Blist.add("gsm");
Blist.add("something");
Blist.add("pc");
Blist.add("something");
for (String a : Alist)
{
for (String b : Blist)
{
if (a.equals(b))
{
System.out.println("Equals " + a);
break;
}
}
}
Output is:
Equals gsm
Equals pc
right now your comparing each element to all of the other ones. Do something like
for (int i = 0; i < Alist.size(); i++) {
if (!Alist.get(i).equals(Blist.get(i)) {
// print what you want
}
}
Thats of course assuming both lists have the same length.
Rather than writing code to manually compare list elements you might consider using Apache Commons Collections.
import org.apache.commons.collections.CollectionUtils;
List listA = ...;
List listB = ...;
Collection intersection = CollectionUtils.intersection(listA, listB);
import java.util.HashSet;
public class CheckSet<T> extends HashSet<T>{
#Override
public boolean add(T e) {
if (contains(e)) {
remove(e);
return true;
} else {
return super.add(e);
}
}
}
Add all elements of both of your lists to a CheckSet intance, and at the end it will only contain the ones not equal.
Here is one way:
public static boolean compare(List<String> first, List<String> second) {
if (first==null && second==null) return true;
if (first!=null && second==null) return false;
if (first==null && second!=null) return false;
if ( first.size()!=second.size() ) return false;
HashMap<String, String> map = new HashMap<String, String>();
for (String str : first) {
map.put(str, str);
}
for (String str : second) {
if ( ! map.containsKey(str) ) {
return false;
}
}
return true;
}
public static void main(String args[] ) throws Exception {
List<String> arrayList1 = new ArrayList<String>();
arrayList1.add("a");
arrayList1.add("b");
arrayList1.add("c");
arrayList1.add("d");
List<String> arrayList2 = new ArrayList<String>();
arrayList2.add("a");
arrayList2.add("b");
arrayList2.add("c");
arrayList2.add("d");
boolean isEqual = false;
if(arrayList1.size() == arrayList2.size()){
List<String> arrayListTemp = new ArrayList<String>();
arrayListTemp.addAll(arrayList1);
arrayListTemp.addAll(arrayList2);
HashSet<Object> hashSet = new HashSet<Object>();
hashSet.addAll(arrayListTemp);
if(hashSet.size() == arrayList1.size() &&
hashSet.size() == arrayList2.size()){
isEqual = true;
}
}
System.out.println(isEqual);
}
we can compare two different size arrayList in java or Android as follow.
ArrayList<String> array1 = new ArrayList<String>();
ArrayList<String> array2 = new ArrayList<String>();
array1.add("1");
array1.add("2");
array1.add("3");
array1.add("4");
array1.add("5");
array1.add("6");
array1.add("7");
array1.add("8");
array2.add("1");
array2.add("2");
array2.add("3");
array2.add("4");
for (int i = 0; i < array1.size(); i++) {
for (int j=0;j<array2.size();j++) {
if (array1.get(i) == array2.get(j)) {
//if match do the needful
} else {
// if not match
}
}
}
import java.util.Arrays;
public class ExampleContains {
public static boolean EligibleState(String state){
String[] cities = new String[]{"Washington", "London", "Paris", "NewYork"};
boolean test = Arrays.asList(cities).contains(state)?true:false;
return test;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(EligibleState("London"));
}
}

How to convert nested List into multidimensional array?

In Java I want to convert a nested List which contains at the deepest level a uniform type into an multidimensional array of that type. For example, ArrayList<ArrayList<ArrayList<ArrayList<String>>>> into String[][][][]. I've tried several things and I only can obtain an array of objects like Object[][][][]. For 'simple lists' it seems that Apache Commons Lang does the work but I cannot figure out for nested cases.
Update:
In order to obtain a multidimensional array of Object type I'm using a recursive function so I cannot set the key type using toArray() see excerpt:
// the argument of this function is a (nested) list
public static Object convert(Object object) {
Object[] result = null;
List list = (List) object;
if (list != null) {
Object type = getElementType(list);
if (type instanceof List) {
int size = list.size();
result = new Object[size];
for (int counter = 0; counter < size; counter++) {
Object element = list.get(counter);
result[counter] = (element != null) ? convert(element) : null;
}
} else {
result = list.toArray();
}
}
return result;
}
private static Object getElementType(List list) {
Object result = null;
for (Object element : list) {
if (element != null) {
result = element;
break;
}
}
return result;
}
To create any kind of non-Object array, you need to pass a type key to the toArray method. This is because for generic types (e.g., ArrayList), the type argument is erased (so, at runtime, ArrayList<String> is treated as a plain ArrayList), whereas for arrays, the type is not.
It seems you already have the Object array creation sorted, so with that and the use of the type key, I think you're all sorted! :-)
This is the way that someone suggested to solved for String type. Cast2(List<?>) returns the multidimensional array. It may be generalized to use the class type as parameter. Thank you for your comments.
static int dimension2(Object object) {
int result = 0;
if (object instanceof List<?>) {
result++;
List<?> list = (List<?>) object;
for (Object element : list) {
if (element != null) {
result += dimension2(element);
break;
}
}
}
return result;
}
static Object cast2(List<?> l) {
int dim = dimension2(l);
if (dim == 1) {
return l.toArray(new String[0]);
}
int[] dims = new int[dimension2(l)];
dims[0] = l.size();
Object a = Array.newInstance(String.class, dims);
for (int i = 0; i < l.size(); i++) {
List<?> e = (List<?>) l.get(i);
if (e == null) {
Array.set(a, i, null);
} else if (dimension2(e) > 1) {
Array.set(a, i, cast2(e));
} else {
Array.set(a, i, e.toArray(new String[0]));
}
}
return a;
}
hehe, heres a answer too but i dunno if that really helps:
List<ArrayList<ArrayList<ArrayList<String>>>> x = new ArrayList<ArrayList<ArrayList<ArrayList<String>>>>();
public static void main(String[] args) throws MalformedURLException, IOException, SecurityException, NoSuchFieldException {
Type t = ((ParameterizedType)(jdomTEst.class.getDeclaredField("x").getGenericType())).getActualTypeArguments()[0];
int[] dims = new int[t.toString().split("List").length];
Object finalArray = Array.newInstance(String.class, dims);
System.out.println(finalArray);
}
this prints: [[[[Ljava.lang.String;#4e82701e
looks pretty messy but i love reflections :)
You can use transmorph :
ArrayList<ArrayList<ArrayList<ArrayList<String>>>> arrayList = new ArrayList<ArrayList<ArrayList<ArrayList<String>>>>();
/// populate the list ...
[...]
Transmorph transmorph = new Transmorph(new DefaultConverters());
String[][][][] array = transmorph.convert(arrayList, String[][][][].class);

Categories