I have three object classes called Size1, Size2, Size3
All Size classes has different values (all Values are Strings):
Size1.getValue() = "1"
Size2.getValue() = "2"
Size3.getValue() = "1"
I want to sort a List so that it wouldn't contain duplicate values.
Here it is what I tried:
private List<Size> getSortedSizes(List<Size> allSizes){
List<Size> sortedArray = new ArrayList<>();
for (int i = 0; i < allSizes.size(); i++){
Size size = allSizes.get(i);
if (sortedArray.size() == 0){
sortedArray.add(Size);
} else {
for (int a = 0; a < sortedArray.size(); a++) {
if (!sortedArray.get(a).getValue().equals(Size.getValue())) {
sortedArray.add(Size);
}
}
}
}
return sortedArray;
}
Add to a TreeSet, not an Arraylist
TreeSets are ordered and cannot contain duplicates
You could implement your method in the following way:
private Set<Size> getSortedSizes(List<Size> allSizes) {
Set<Size> sorted = new TreeSet<>(sortedArray);
return sorted;
}
But you have to implement two methods in your Size class, they are: hashCode() and int compareTo(Object o) from the Comparable interface
Related
public class MyArrayList<T> implements MyList<T>{
int num; //number of things in the list
T[] vals; //to store the contents
#SuppressWarnings("unchecked")
public MyArrayList() {
num = 0;
vals = (T[]) new Object[3];
}
public T getUnique(){
T distinct = null;
int count = 0;
for (int i=0; i<vals.length; i++){
distinct = vals[i];
for (int j = 0; j<vals.length; j++){
if (vals[j] == vals[i]){
count++;
}
if (count == 1){
return distinct;
}
}
}
if (distinct == null){
throw new IllegalArgumentException();
}
return distinct;
}
I am trying to work on a get Unique Method. A method getUnique that takes no arguments and returns the first value in the list that appears only once. (For example, calling the method on the list [1,2,3,1,2,4] would return 3 since 1 and
2 both appear more than once.) If the list is empty or all its values appear more than once, the method throws a NoSuchElementException
I have added some FIXME's to your code:
public T getUnique(){
T distinct = null;
int count = 0; // FIXME: move this initialization inside the i loop
for (int i=0; i<vals.length; i++){
distinct = vals[i];
for (int j = 0; j<vals.length; j++){
if (vals[j] == vals[i]){ // FIXME: use .equals() not ==
count++;
}
if (count == 1){ // FIXME: move this check outside the j loop
return distinct;
}
}
}
if (distinct == null){ //FIXME: no check needed, just throw it
throw new IllegalArgumentException();
}
return distinct; //FIXME: no valid return can reach this point
}
Patrick Parker's advice will fix your code, but I wanted to provide a cleaner and faster solution to the problem of finding a unique element in a list. This algorithm runs in time O(n) instead of O(n^2).
public static <T> Optional<T> getUnique(List<T> ls) {
// Create a map whose keys are elements of the list and whose values are
// lists of their occurences. E.g. [1,2,3,1,2,4] becomes {1->[1, 1],
// 2->[2, 2], 3->[3], 4->[4]}. Then elements.get(x).size() tells us how
// many times x occured in ls.
Map<T, List<T>> elements = ls.stream()
.collect(Collectors.groupingBy(x -> x));
// Find the first element that occurs exactly one time in ls.
return ls.stream().filter(x -> elements.get(x).size() == 1)
.findFirst();
}
You might call it like this:
Integer[] vals = {1,2,3,1,2,4};
System.out.println(getUnique(Arrays.asList(vals))
.orElseThrow(NoSuchElementException::new));
This code uses Java 8 streams and Optional. Below is another implementation of the same algorithm that doesn't use Java 8 language features; if you've never encountered streams, you may find it more understandable.
private static <T> T getUnique(List<T> arr) {
Map<T, Integer> numOccurrences = new HashMap<>();
for (T item : arr) {
numOccurrences.put(item, 1 + numOccurrences.getOrDefault(item, 0));
}
for (T item : arr) {
if (numOccurrences.get(item) == 1) {
return item;
}
}
throw new NoSuchElementException();
}
I am comparing two arraylist (Contacts .java is an pojo class). First Arraylist contains some Items and second arraylist contains some Items. By comparing two list, if both list contains same element it should not be added and else added to first list. But I cannot do it. Below is my code. Help will be appreciated.
public void insertmanualandxmldata()
{
mContacts = storage.getarraylist(); // Arraylist
if(mContacts != null)
{
for(int i=0; i<mContacts.size(); i++)
{
ContactVO mShareddata = mContacts.get(i);
//mParsedDataSetList arraylist
for(int j=0; j<mParsedDataSetList.size(); j++)
{
ContactVO mXmldata = mParsedDataSetList.get(j);
if(mShareddata.getNumber().contains(mXmldata.getNumber()))
{
mContacts.add(mXmldata);
}
}
}
storage.savearraylist(mContacts);
}
else
{
storage.savearraylist(mParsedDataSetList);
}
}
Implement Comparable
private class ContactsVO implements Comparable<ContactsVO>{
int number;
#Override
public int compareTo(ContactsVO that)
{
if (this.number> that.number)
return 1;
else if (this.number< that.number)
return -1;
else
return 0;
}
}
And your logic.. Add contents of list 2 to list 1. while adding we have to compare if list 1 already has that item.
for(int j=0; j < mParsedDataSetList.size(); j++)
{
ContactVO mXmldata = mParsedDataSetList.get(j);
boolean exists = false;
for(int i=0; i< mContacts.size(); i++)
{
ContactVO mShareddata = mContacts.get(i);
if(mShareddata.comprareTo(mXmldata) == 0)
{
exists = true;
break;
}
}
if(!exists)
{
mContacts.add(mXmldata);
}
}
You could implement a class that extends ArrayList and create a Comparator like this:
public static Comparator<T> Comp = new Comparator<T>(){
public int compare(Type e1, Type e2){
return (e1.getSomething().compareTo(e2.getSomething()));
}
};
If you have never used comparators before here is a good tutorial https://docs.oracle.com/javase/tutorial/collections/interfaces/order.html
What comparators basically do is to provide a criteria for comparing elements.
There are two approaches by implementing comparator or comparable.
For your requirement I would suggest you can implements Comparable in your ContactVO class. And override compareTo method.
private class ContactsVO implements Comparable<ContactsVO> {
private Integer number;
// Remaining attributes and their getter setter.
public Integer getNumber() {
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
#Override
public int compareTo(ContactsVO compareWith) {
if (this.getNumber() > compareWith.getNumber())
return 1;
else if (this.getNumber() < compareWith.getNumber())
return -1;
else
return 0;
}
}
If comparing attribute (in our case is number) implements Comparable then we can rewrite compareTo method as
#Override
public int compareTo(ContactsVO compareWith) {
return this.getNumber().compareTo(compareWith.getNumber());
}
Note: Some basic data types such as Integer, String implements Comparable.
Here contactList1 and contactList2 is your two list of POJO class Contacts
Set<Contacts> contactList3 = new HashSet<Contacts>(contactList1);
contactList3.addAll(contactList2);
ArrayList<Contacts> newList = new ArrayList<Contacts>(contactList3);
System.out.println("New List :"+newList);
Try to use LinkedHashSet which will not allow duplicates :
ArrayList arrayList1 = new ArrayList();
ArrayList arrayList2 = new ArrayList();
ArrayList arrayList3 = new ArrayList();
arrayList3.addAll(arrayList1);
arrayList3.addAll(arrayList2);
HashSet hashSet = new HashSet();
hashSet.addAll(arrayList3);
arrayList3.clear();
arrayList3.addAll(hashSet);
Note : when you required to maintain ordering of you list item use LinkedHashSet instead of HashSet.
I wanted to know if there's a native method in array for Java to get the index of the table for a given value ?
Let's say my table contains these strings :
public static final String[] TYPES = {
"Sedan",
"Compact",
"Roadster",
"Minivan",
"SUV",
"Convertible",
"Cargo",
"Others"
};
Let's say the user has to enter the type of car and that then in the background the program takes that string and get's it's position in the array.
So if the person enters : Sedan
It should take the position 0 and store's it in the object of Cars created by my program ...
Type in:
Arrays.asList(TYPES).indexOf("Sedan");
String carName = // insert code here
int index = -1;
for (int i=0;i<TYPES.length;i++) {
if (TYPES[i].equals(carName)) {
index = i;
break;
}
}
After this index is the array index of your car, or -1 if it doesn't exist.
for (int i = 0; i < Types.length; i++) {
if(TYPES[i].equals(userString)){
return i;
}
}
return -1;//not found
You can do this too:
return Arrays.asList(Types).indexOf(userSTring);
I had an array of all English words. My array has unique items. But using…
Arrays.asList(TYPES).indexOf(myString);
…always gave me indexOutOfBoundException.
So, I tried:
Arrays.asList(TYPES).lastIndexOf(myString);
And, it worked. If your arrays don't have same item twice, you can use:
Arrays.asList(TYPES).lastIndexOf(myString);
try this instead
org.apache.commons.lang.ArrayUtils.indexOf(array, value);
Use Arrays class to do this
Arrays.sort(TYPES);
int index = Arrays.binarySearch(TYPES, "Sedan");
No built-in method. But you can implement one easily:
public static int getIndexOf(String[] strings, String item) {
for (int i = 0; i < strings.length; i++) {
if (item.equals(strings[i])) return i;
}
return -1;
}
There is no native indexof method in java arrays.You will need to write your own method for this.
An easy way would be to iterate over the items in the array in a loop.
for (var i = 0; i < arrayLength; i++) {
// (string) Compare the given string with myArray[i]
// if it matches store/save i and exit the loop.
}
There would definitely be better ways but for small number of items this should be blazing fast. Btw this is javascript but same method should work in almost every programming language.
Try this Function :
public int indexOfArray(String input){
for(int i=0;i<TYPES,length();i++)
{
if(TYPES[i].equals(input))
{
return i ;
}
}
return -1 // if the text not found the function return -1
}
Testable mockable interafce
public interface IArrayUtility<T> {
int find(T[] list, T item);
}
implementation
public class ArrayUtility<T> implements IArrayUtility<T> {
#Override
public int find(T[] array, T search) {
if(array == null || array.length == 0 || search == null) {
return -1;
}
int position = 0;
for(T item : array) {
if(item.equals(search)) {
return position;
} else {
++position;
}
}
return -1;
}
}
Test
#Test
public void testArrayUtilityFindForExistentItemReturnsPosition() {
// Arrange
String search = "bus";
String[] array = {"car", search, "motorbike"};
// Act
int position = arrayUtility.find(array, search);
// Assert
Assert.assertEquals(position, 1);
}
Use this as a method with x being any number initially.
The string y being passed in by console and v is the array to search!
public static int getIndex(int x, String y, String[]v){
for(int m = 0; m < v.length; m++){
if (v[m].equalsIgnoreCase(y)){
x = m;
}
}
return x;
}
Refactoring the above methods and showing with the use:
private String[] languages = {"pt", "en", "es"};
private Integer indexOf(String[] arr, String str){
for (int i = 0; i < arr.length; i++)
if(arr[i].equals(str)) return i;
return -1;
}
indexOf(languages, "en")
all I have list containing Duplicate values I want somehow to get only Unique values from it and store it another list or set.So that I can perform some operation on it.
My code:
{
List<Integer[]> list1 = new ArrayList<Integer[]>();
list1.add(new Integer[] { 1,10 });
list1.add(new Integer[] { 1,10 });
list1.add(new Integer[] { 1,10 });
list1.add(new Integer[] { 2,10 });
list1.add(new Integer[] { 1,10 });
list1.add(new Integer[] { 3,10 });
for(int i=0;i<list1.size();i++)
{
System.out.println("I - 0 :"+list1.get(i)[0]+"\t I - 1 :"+list1.get(i)[1]+"\n");
}
Set<Integer[]> uniquelist = new HashSet<Integer[]>(list1);
for(Integer[] number: uniquelist){
System.out.println(number[0]+"\t"+number[1]);
}
}
I want the result {1,10;2,10;3,10} to be in separate list.When i googled I got to know for unique we should use set as in Set<Integer[]> uniquelist = new HashSet<Integer[]>(list1); But after doing this I dont know how to access each elements Thanks in advance
Output:
1 10
2 10
1 10
3 10
1 10
1 10
You won't get the result you want using the normal Set approach. As your List contains Integer[], and then won't be considered unique by default. All the array objects are distinct. So, your Set will contain the same elements as your list. However, you can define your Custom Comparator, and use it with a TreeSet constructor.
Another way of doing it can be, define a method contains(List<Integer[]> list, Integer[] value), which checks whether your list contains that array. Define a list named uniqueList. Now, iterate over your original list, and then for each value, call contains method passing uniqueList and that value, as parameters.
Here's how your contains method would look like: -
public static boolean contains(List<Integer[]> list, Integer[] value) {
for (Integer[] arr: list) {
// We can compare two arrays using `Arrays.equals` method.
if (Arrays.equals(arr, value)) {
return true;
}
}
return false;
}
So, you can see that, checking for containment is not the same as, how it would look for just Integer.
Now, from your main method, use this code: -
List<Integer[]> unique = new ArrayList<Integer[]>();
for (Integer[] arr: list1) {
// Use your method here, to test whether this value - `arr`
// is already in `unique` List or not. If not, then add it.
if (!contains(unique, arr)) {
unique.add(arr);
}
}
for (Integer[] arr: unique) {
System.out.println(arr);
}
I would rather use a Set implementation in this case. Use LinkedHashSet if you want your elements to be ordered.
You could declare a class IntegerPair to hold your pairs:
class IntegerPair {
private int key;
private int value;
public IntegerPair(int k, int v) {
key = k;
value = v;
}
public int getKey() {
return key;
}
public int getValue() {
return value;
}
public int hashCode() {
return key * value;
}
public boolean equals(Object o) {
if (!(o instanceof IntegerPair)) {
return false;
}
IntegerPair other = (IntegerPair) o;
return key == other.key && value == other.value;
}
}
Declare it this way:
Set<IntegerPair> set = new LinkedHashSet<IntegerPair>();
Instead of putting new Integer[] values, just do set.add(new IntegerPair(1, 10));
You can loop through your elements using the foreach approach:
for (IntegerPair value : set) {
System.out.println(value.getKey() + " = " + value.getValue());
}
You can access elements by Iterator or by using for each loop
for(Integer number: setOfNumbers){
System.out.println(number);
}
Put them into set using your custom comparator like following:
new TreeSet(list1, new Comparator<Integer[]>() {
public int compare(Integer[] one, Integer[] two) {
int n = one.length;
for (int i = 0; i < n; i++) {
int comp = one.compareTo(two);
if (comp != 0) {
return comp;
}
}
return 0;
}
});
Pay attention that I used TreeSet that can accept custom comparator. It is because you are dealing with arrays. If however you define your own class that holds 2 int values you can make it to implement equals() and hashCode() that allows using any Set implementation.
the Integer[] number in your for loop is an array. to get the values inside you have to use number[index] instruction. to do that you can either do a classic while or for loop using a variable as an index
for(int i=0;i<number.length;i++) {
...
}
or a foreach loop:
for(Integer num : number){
...
}
This may help you...
public static void main(String [] args){
Set<Integer []> set = new TreeSet<Integer []>(new Comparator<Integer[]>(){
public int compare(Integer[] o1, Integer[] o2) {
if(o1.length == o2.length){
for(int i = 0; i < o1.length; i++){
if(o1[i] != o2[i]){
return -1;
}
}
return 0;
}
return -1;
}
});
set.add(new Integer[]{1,2});
set.add(new Integer[]{1,2});
set.add(new Integer[]{1,2});
set.add(new Integer[]{1,3});
int j = 0;
for(Integer[] i: set){
System.out.println("\nElements: "+j);
j++;
for(Integer k : i){
System.out.print(k+" ");
}
}
}
You need to use Comparator to compare two elements of same. As we don't have comparator for Array, Set will use actual object to compare.. using comparator you will have to tell set that this two arrays are same and do not add other same array
Try Table collection in Google-guava.
Example :
Table<Integer, Integer, Integer[]> sampleTable = HashBasedTable.create();
sampleTable.put(1, 10, new Integer[] { 1,10 });
sampleTable.put(2, 10, new Integer[] { 2,10 });
sampleTable.put(1, 10, new Integer[] { 1,10 });
So it will overwrite the duplicate values. Finally you have only unique values.
The lists are sorted the way they are supposed to but when I try to merge the two lists together in my makeUnion it prints out the list is empty. can anyone help me and tell my why? in main when I try SortedLinkedList merge = sortedNames1.makeUnion(sortedNames2) I get "Empty list".
public class SortedLinkedList<T extends Comparable<? super T>>
extends LinkedList<T>
{
private LinkedList<T> list; //the sorted list
//the constructor
public SortedLinkedList(LinkedList<T> in)
{
if(in.isEmpty())
{
System.out.println("Empty list");
}
if(in.size() < 2)
{
return;
}
else
{
list = new LinkedList<T>();
for(int i = 1; i < in.size(); i++)
{
T temp = in.get(i);
int j = i;
while(j > 0 && in.get(j - 1).compareTo(temp) > 0)
{
in.set(j, in.get(j-1));
j--;
}
in.set(j, temp);
}
for(T elements : in)
{
list.add(elements);
}
}
}
//return the union of the sorted linked lists this and other
public SortedLinkedList<T> makeUnion( SortedLinkedList<T> other)
{
SortedLinkedList<T> first = new SortedLinkedList<T>(other);
SortedLinkedList<T> second = new SortedLinkedList<T>(list);
SortedLinkedList<T> UnionList = null;
int i = 0;
int j = 0;
while(i<first.size() && j<second.size())
{
if(first.get(i).compareTo(second.get(j)) <= 0)
{
UnionList.add(first.get(i));
i++;
}
else
{
UnionList.add(second.get(j));
j++;
}
}
if(i == first.size())
{
for(int k = j; k<second.size(); k++)
{
UnionList.add(second.get(k));
}
}
else if(j == second.size())
{
for(int x = i; x<first.size(); x++)
{
UnionList.add(first.get(x));
}
}
return UnionList;
}
//print the items int list
public void print()
{
ListIterator itr = list.listIterator();
while(itr.hasNext())
{
System.out.println(itr.next());
}
}
}
SortedLinkedList<T> UnionList = null;
You can't call UnionList.add() if UnionList is null. You will need to allocate a new list before you can add things to it.
Actually, I think your original problem might be that SortedLinkedList both extends LinkedList and also contains an instance of a LinkedList. You should choose one or the other, but not both. Your code sometimes accesses one list, and sometimes the other, so one list appears empty because you've added items to the other list.
You don't initialize UnionList before you start using it.
SortedLinkedList<T> UnionList = null;
should read
SortedLinkedList<T> UnionList = new SortedLinkedList<T>();
As a bonus, ListIterator ought to be ListIterator<T> so that the right toString() method is used. As it is, you'll be calling Object.toString().
Because you used inheritance instead of delegation. You inherit LinkedList, and the only thing you do is define a constructor which adds the content of an unsorted list to a new one, in the appropriate order. But you don't override the size method, so this method is inherited from LinkedList, which doesn't care about your internal sorted list and thus always returns 0.
Extending a collection is, most of the time, a bad idea. In this case, it's a particularly bad idea because it's impossible to have a sorted LinkedList that respects the LinkedList API. Suppose your list contains A, B and C, and you call addFirst("Z") on it. Where will you put Z, if at the beginning, your list is not sorted anymore. If at the end, you don't respect the contract of addFirst.
Just use linked lists (instead of extending them), and sort them. You could just do :
LinkedList list = new LinkedList(someUnsortedList);
Collections.sort(list); // now the list is sorted
list.addAll(someOtherList);
Collections.sort(list); // now both lists are merged, and the resulting list is sorted.