Sort a Set in reverse order - java

Apologies for the newbie question, but what's the proper way to get a Set (say LinkedHashSet) in reverse order? For Collections there's Collections.reverse(Collection c), but how does one do it for a Set with ordered elements (like a LinkedHashSet)?

Sets are not ordered in general, so to preserve the sorting, after sorting the set as a list, you would need to use a known iteration order implementation of Set, such as LinkedHashSet
List list = new ArrayList(set);
Collections.sort(list, Collections.reverseOrder());
Set resultSet = new LinkedHashSet(list);
You could also use TreeSet with a comparator, but that is not as fast as the ArrayList method above.

public class LargestArray {
public static void main(String[] args) {
ArrayList<Integer> al = new ArrayList<>();
Set<Integer> set = new TreeSet<>();
set.add(10);
set.add(20);
set.add(7);
set.add(4);
set.add(1);
set.add(2);
set.add(3);
set.add(4);
System.out.println("after Sorting");
for(int i : set) {
System.out.print(" " + i);
}
al.addAll(set);
set.clear();
Collections.reverse(al);
System.out.println();
System.out.println("After Reverse");
for (int i : al) {
System.out.print(" " + i);
}
}
}
output = after Sorting
1 2 3 4 7 10 20
After Reverse
20 10 7 4 3 2 1

Check this out
http://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html#descendingSet()
If you use a TreeSet you can get reverse order by calling descendingSet.

I will explain you with an example. Comments are added in mid of the code for better understanding.
public class ReverseLinkedHashSet {
public static void main(String[] args) {
// creating a LinkedHashSet object which is
// of type String or any. Will take a example of String.
HashSet<String> cars = new LinkedHashSet<String>();
// adding car elements to LinkedHashSet object as below
cars.add("Toyato");
cars.add("Hundai");
cars.add("Porshe");
cars.add("BMW");
// Iterating using enhanced for-loop to see the order.
System.out.println("Insertion Order: Iterating LinkedHashSet\n");
for(String car : cars) {
System.out.println(car);
// Output will be as below
//Toyato
//Hundai
//Porshe
//BMW
}
// Now convert to ArrayList to rearrange to reverse
// the linkedHashset
List<String> listOfCars = new ArrayList<String>(cars);
// to reverse LinkedHashSet contents
Collections.reverse(listOfCars);
// reverse order of LinkedHashSet contents
// can be done as below
System.out.println("\n\n\nReverse Order of LinkedHashSet\n");
for(String car : listOfCars) {
System.out.println(car);
// Output will be as below
//BMW
//Porshe
//Hundai
//Toyato
}
}
}
Also, I suggest not to use LinkedhashSet without a strong reason. For a complex application, it will reduce the performance. Use HashSet instead.

Java 8, I using solution below,
Set<String> setTest = new HashSet<>();
setTest.add("1");
setTest.add("2");
setTest.add("3");
List<String> list = new ArrayList<>(setTest);
list.sort(Collections.reverseOrder());
Set<String> result = new LinkedHashSet<>(list);
for (String item: result) {
System.out.println("---> " + item);
}
Result:
---> 3
---> 2
---> 1
Work for me.

Related

Not able to access individual element from sublist

I am a beginner in java. I want to read elements one by one in sublist.
public class ListFirst {
public static void main(String[] args) {
List<Integer>list1= Arrays.asList(10,20,30,40);
List<Integer>list2=Arrays.asList(100,200,300,400);
List<List<Integer>>bigList= new ArrayList<>();
// I want to access an element of bigList one by one. how to do that?
}
}
If there is no sublist I can print using for loop upto list.size() and list.get() to print but here element is list itself..so I dont know how to read. could you please help me with that.
I modified your code to achieve what you wanted to do:
public class ListFirst {
public static void main(String[] args) {
List<Integer>list1= Arrays.asList(10,20,30,40);
List<Integer>list2=Arrays.asList(100,200,300,400);
List<List<Integer>>bigList= new ArrayList<>();
bigList.add(list1);
bigList.add(list2);
for (List<Integer> list : bigList) {
for (Integer i : list) {
System.out.print(i.intValue() + " ");
}
}
}
}
An alternative would be to not use nested List for storing your Integers:
public static void main(String[] args) {
List<Integer>list1= Arrays.asList(10,20,30,40);
List<Integer>list2=Arrays.asList(100,200,300,400);
// bigList is a list of Integers not list of lists
List<Integer>bigList= new ArrayList<>();
bigList.addAll(list1); // add all elements from list1
bigList.addAll(list2); // add all elements from list2
for (Integer i : bigList) {
System.out.print(i.intValue() + " ");
}
}
Assuming that the lists have bee added to bigList, you can iterate it using the for-each loop as shown below:
bigList.add(list1);
bigList.add(list2);
for (List<Integer> list : bigList) {
System.out.println(list);
}
DEMO
Using the traditional loop, you can print bigList as shown below:
for (int i = 0; i < bigList.size(); i++) {
System.out.println(bigList.get(i));
}
You can do the following:
bigList.stream()
.flatMap(Collection::stream)
.forEach(x -> System.out.println(x));
Output:
10
20
30
40
100
200
300
400

How to merge two corresponding values of two different variables in arraylist?

I want to merge two corresponding values of two different variables with comma separator in a row :
like
Plate Numbers(Output) : MH 35353, AP 35989, NA 24455, DL 95405.
There is two different variables one is plate State and another is plate Number, I want to merge them together with their corresponding values like 1st values of plate State with 1st value of plate Number after that comma then so on..
I tried this code snippet but didn't work :
ArrayList<String>
list1 = new ArrayList<String>();
list1.add("MH");
list1.add("AP");
list1.add("NA ");
list1.add("DL");
ArrayList<String>
list2 = new ArrayList<String>();
list2.add("35353");
list2.add("35989");
list2.add("24455");
list2.add("95405");
list1.addAll(list2);
use this :
ArrayList<String>
list1 = new ArrayList<String>();
list1.add("MH");
list1.add("AP");
list1.add("NA ");
list1.add("DL");
ArrayList<String>
list2 = new ArrayList<String>();
list2.add("35353");
list2.add("35989");
list2.add("24455");
list2.add("95405");
Iterator iterable = list2.iterator();
List<String> list3 =list1.stream()
.map(x->{
x= x+" "+((String) iterable.next());
return x;})
.collect(Collectors.toList());
String output = String.join(", ", list3);
System.out.println(output);
From ArrayList#addAll Javadoc:
Appends all of the elements in the specified collection to the end of this list[...]
This is not what you want, because you actually don't want to append the objects, you want to merge the String of the first list with the String from the second list. So in a sense, not merge the List but merge the objects (Strings) in the lists.
The easiest (most beginner friendly) solution would be to just create a simple helper method yourself, that does what you need.
Something like this:
public static void main(String[] args) {
ArrayList<String> list1 = new ArrayList<String>();
list1.add("MH");
list1.add("AP");
list1.add("NA");
list1.add("DL");
ArrayList<String> list2 = new ArrayList<String>();
list2.add("35353");
list2.add("35989");
list2.add("24455");
list2.add("95405");
ArrayList<String> combined = combinePlateNumbers(list1, list2);
System.out.println(combined);
}
private static ArrayList<String> combinePlateNumbers(List<String> list1, List<String> list2) {
ArrayList<String> result = new ArrayList<>();
if (list1.size() != list2.size()) {
// lists don't have equal size, not compatible
// your decision on how to handle this
return result;
}
// iterate the list and combine the strings (added optional whitespace here)
for (int i = 0; i < list1.size(); i++) {
result.add(list1.get(i).concat(" ").concat(list2.get(i)));
}
return result;
}
Output:
[MH 35353, AP 35989, NA 24455, DL 95405]

How to iterate through a 2D LinkedHashSet and print its contents?

I am using a 2D LinkedHashSet for my program. I was wondering how I can iterate through the two dimensional HashSet and print its contents without doing this:
System.out.println(name of initialized HashSet)
Here is my code for initialization of the 2D LinkedHashSet:
LinkedHashSet<LinkedHashSet<String>> block = new LinkedHashSet<LinkedHashSet<String>>();
You can use 2 loops for this, similar to how you would for an array:
for (Set<String> innerSet : block) {
for (String string : innerSet) {
System.out.println(string);
}
}
You can also use streams to print each element:
block.stream()
.flatMap(Collection::stream)
.forEach(System.out::println);
If one wants to use a functional solution, one could use the following:
Ideone demo
import java.util.LinkedHashSet;
public class Streamify {
public static void main (final String... args) {
final LinkedHashSet<LinkedHashSet<String>> block = new LinkedHashSet<>();
final LinkedHashSet<String> lineOne = new LinkedHashSet<>();
lineOne.add("Hello");
lineOne.add("World");
block.add(lineOne);
final LinkedHashSet<String> lineTwo = new LinkedHashSet<>();
lineTwo.add("Hi");
lineTwo.add("Universe");
block.add(lineTwo);
block.forEach(line -> {
line.forEach(System.out::print);
System.out.println();
});
}
}

Unique set from ArrayList of ArrayList

Hi I have an arraylist of arraylist in this format:
[[val1, val2],[val3,val4],[val1,val2],[val1,val5]]
and would like to get the unique set of arraylists:
[[val1, val2],[val3,val4],[val1,val5]]
I have tried the following:
Set<String> uniques = new HashSet<>();
for (ArrayList<String> sublist : mappedEntities) {
uniques.addAll(sublist);
}
but this merges all the values of the internal arraylist together
can use Java 8 Collection Stream Distinct,
return in Set datatype :
Set<List<String>> uniques = mappedEntities.stream().distinct().collect(Collectors.toSet());
if you want return in List :
List<List<String>> uniques = mappedEntities.stream().distinct().collect(Collectors.toList());
Why not simply put them in a Set like this?
Set<List<String>> uniques = new HashSet<>(mappedEntities);
Your mistake is that you are flattening the inner lists and putting their items in the set separately.
The issue here is that you need a Set of ArrayList Set<ArrayList<String>>, but you are using a Set of Strings Set<String> instead.
Given the list :
List<List<String>> mappedEntities = Arrays.asList(Arrays.asList("val1", "val2"),
Arrays.asList("val3", "val4"),
Arrays.asList("val1", "val2"),
Arrays.asList("val1", "val5"));
All you need to do is just declare the set and use the addAll().
Set<List<String>> mySet = new HashSet<>();
mySet.addAll(mappedEntities);
Since a set can hold only unique values, all duplicates will not be added to the set (No need to explicitly check this). You can now print it out :
mySet.forEach(System.out::println);
Or more simply, initialize the HashSet using the list mappedEntities :
Set<List<String>> mySet = new HashSet<>(mappedEntities);
I am beginner on STACKOVERFLOW but i to try solve your problem
I think you want like this..
import java.util.*;
public class GFG {
public static void main(String[] args)
{
int n = 3;
// Here aList is an ArrayList of ArrayLists
ArrayList<ArrayList<String> > aList =
new ArrayList<ArrayList<String> >(n);
// Create n lists one by one and append to the
// master list (ArrayList of ArrayList)
ArrayList<String> a1 = new ArrayList<String>();
a1.add("1");
a1.add("2");
aList.add(a1);
ArrayList<String> a2 = new ArrayList<String>();
a2.add("11");
a2.add("22");
aList.add(a2);
ArrayList<String> a3 = new ArrayList<String>();
a3.add("1");
a3.add("2");
aList.add(a3);
Set<ArrayList<String>> uniques = new HashSet<ArrayList<String>>();
for (ArrayList<String> sublist : aList) {
uniques.add(sublist);
}
System.out.println("Your Answer");
for (ArrayList<String> x : uniques)
System.out.println(x);
}
}
try this code:
public class B {
public static void main(String[] args) throws Exception {
List<List<String>> list= Arrays.asList(
Arrays.asList("a","b","c"),
Arrays.asList("a","b","c"),
Arrays.asList("a","b","c","d"));
Set<List<String>> uniques = new HashSet<>();
for (List<String> sublist : list) {
if(!uniques.contains(sublist))
uniques.add(sublist);
}
System.out.println(uniques);
}
}
output:
[[a, b, c], [a, b, c, d]]

Representing multisets as LinkedLists

A multiset is similar to a set except that the duplications count.
We want to represent multisets as linked lists. The first representation
that comes to mind uses a LinkedList<T> where the same item can occur at
several indices.
For example:the multiset
{ "Ali Baba" , "Papa Bill", "Marcus", "Ali Baba", "Marcus", "Ali Baba" }
can be represented as a linked list
of strings with "Ali Baba" at index 0, "Papa Bill" at index 1,
"Marcus" at index 2, "Ali Baba" at index 3, and so on, for a total of
6 strings.
The professor wants a representation of the multiset as pair <item,integer> where the integer, called the multiplication of item, tells us how many times item occurs in the multiset. This way the above multiset is represented as the linked list with Pair("Ali Baba" ,3) at index 0, Pair("Papa Bill", 1) at index 1, and Pair("Marcus",2) at index 2.
The method is (he wrote good luck, how nice of him >:[ )
public static <T> LinkedList<Pair<T,Integer>> convert(LinkedList<T> in){
//good luck
}
the method transforms the first representation into the Pair representation.
If in is null, convert returns null. Also feel free to modify the input list.
He gave us the Pair class-
public class Pair<T,S>
{
// the fields
private T first;
private S second;
// the constructor
public Pair(T f, S s)
{
first = f;
second = s;
}
// the get methods
public T getFirst()
{
return first;
}
public S getSecond()
{
return second;
}
// the set methods
// set first to v
public void setFirst(T v)
{
first = v;
}
// set second to v
public void setSecond(S v)
{
second = v;
}
}
I am new to programming and I've been doing well, however I have no idea how to even start this program. Never done something like this before.
If you are allowed to use a temporary LinkedList you could do something like that:
import java.util.LinkedList;
public class Main {
public static void main(String[] args) {
LinkedList<String> test = new LinkedList<String>();
test.add("Ali Baba");
test.add("Papa Bill");
test.add("Marcus");
test.add("Ali Baba");
test.add("Marcus");
test.add("Ali Baba");
LinkedList<Pair<String, Integer>> result = convert(test);
for(Pair<String, Integer> res : result) {
System.out.println(res.getFirst() + " :" + res.getSecond());
}
}
public static <T> LinkedList<Pair<T, Integer>> convert(LinkedList<T> in) {
LinkedList<Pair<T, Integer>> returnList = new LinkedList<>();
LinkedList<T> tmp = new LinkedList<T>();
// iterate over your list to count the items
for(T item : in) {
// if you already counted the current item, skip it
if(tmp.contains(item)) {
continue;
}
// counter for the current item
int counter = 0;
//iterate again over your list to actually count the item
for(T item2 : in) {
if(item.equals(item2)) {
counter ++;
}
}
// create your pair for your result list and add it
returnList.add(new Pair<T, Integer>(item, counter));
// mark your item as already counted
tmp.add(item);
}
return returnList;
}
}
With that i get the desired output of
Ali Baba :3
Papa Bill :1
Marcus :2
Your requirements put:
your input : LinkedList
your output : LinkedList>
1 - write a loop to read your input
2 - process / store it in a convenient way: user Map . In fact, use linkedhashmap which keeps the order
2bis - if you can't use a Map, do the same thing directly with two arrays: an array of T, and an array of integer. You must manager insertion, search, and keep count.
3 - iterate over your arrays, and create your output
It is easier to begin with 2, and if it works, replace with 2bis

Categories

Resources