Trouble trying to invert an array list - java

I'm trying to invert an arrayList of votes in order to yield preference (i.e. a vote of 2,4,1,3, after inverted is 3,1,4,2. the indexed preference is 3). I believe this can be done with Collections but the list is of difference type (type Vote). Just need some guidance on how i could sort this preference order when i cant use Collections methods on Vote.
public Vote invertVote() {
VoteList invVote = (VoteList) ((Vote) vote).copyVote();
Iterator<Integer> iter = invVote.iterator();
while(iter.hasNext()){
iter.next();
Collections.reverse(invVote);
}
return invVote;
}
Note Vote is a collection of integers representing a single vote. VoteList implements Vote. copyVote() is used to create a deep copy of the vote in order to not alter it and return a new Vote object. Still stuck the error during Collections.reverse(invVote)

Yes this can be done using collection you just need to call the method Collections.reverse...
public static void reverse(List<?> list)
Reverses the order of the elements in the specified list.
This method
runs in linear time.
Example:
public static void main(String[] args) {
Random rnd = new Random();
List<Integer> myInteger = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
myInteger.add(rnd.nextInt(10));
}
// the list
System.out.println(myInteger);
// the list sorted
Collections.sort(myInteger);
System.out.println(myInteger);
// the list inverted
Collections.reverse(myInteger);
System.out.println(myInteger);
}
in your case use the class Votes instead of integer and make the class to implement the comparable interface where you define the sorting logic....

You can use Collections.reverse(list); check documentation.

Related

Java <Streams> How to sort the list of my objects, based on the count of the components of the List

I have 2 classes in Java. One is a Car class that consists of 5 variables. Among them I have a List equipment variable. Another class contains the list of the Car class objects: List carlist.
My task is: I have to sort the list of car object, using Streams in Java based on the amount of the equipment items that the given car have.
How do I do that? I tried to build a separate method to count the items on the list of the object - but then within the Comparator I can't place an Object as an argument of this method.
Here's an excerpt of my code:
private int countEquipmentItems (Car s){
if (s == null){
return 0;
}
int countEquipment = 0;
List<String> a = s.getEquipment();
for (int i = 0; i <a.size() ; i++) {
countEquipment ++;
}
return countEquipment;
}
And I have tried to use this method within the Stream:
public void sortbyEquipment (List<Car> carList){
carList.stream()
.sorted(Comparator.comparing(countEquipmentItems(Car s)));
}
}
I appreciate any help
You don't need that countEquipmentItems method to count the amount of equipment. Just use car.getEquipment().size():
public void sortbyEquipment (List<Car> carList){
carList.stream()
.sorted(Comparator.comparing(car -> car.getEquipment().size()))
...
}
Of course, you can pass that Comparator directly to Collections.sort(), which will sort the list without having to create a Stream.
Your countEquipmentItems method is redundant and completely unnecessary.
Another solution to what Eran has provided would be to call the default sort method that is available for the List<T> type.
carList.sort(Comparator.comparingInt(car -> car.getEquipment().size()));
or if you want the sorted items to be in a new collection then you can do:
List<Car> clonedList = new ArrayList<>(carList); // clone the carList
clonedList.sort(Comparator.comparingInt(car -> car.getEquipment().size()));

Ordered Set based on linked list

I am working with java, and I need to implement an ordered set, base on a linked list using the interface SortedSet. How do I implement the methods from SortedSet by this conditions?
Since this is clearly homework (or a similar learning exercise) it is inappropriate to give you code. So here are some Hints to get you started.
You need to keep the elements of the linked list ordered at all times
If the linked list is a wrapped LinkedList, you can delegate a lot of the SortedSet methods to the list.
Alternatively, consider using AbstractSet as the base class for your set.
(You will need to check the wording of your homework's requirement to figure out if you are allowed to use LinkedList or AbstractList.)
As I understand, you need to use Set feature to delete duplicates from your LinkedList, and to use SortedSet to keep it sorted.
So, the easiest way to do that, if you have a linked list, is to do something like this. For this example I've used LinkedList which would be filled with random numbers:
public class Main {
public static void main(String[] args){
//Declare the LinkedList of Integers
LinkedList<Integer> linkedList = new LinkedList<Integer>();
//use special method to fill List with 10 numbers which are less than 100
linkedListRandomFill(linkedList, 10, 100);
//After you pass the LinkedList to the following constructor
// the list is sorted automatically
SortedSet<Integer> sortedSet = new TreeSet<Integer>(linkedList);
//After that you can recreate your linked list,
// just pass the SortedSet to LinkedList constructor
linkedList = new LinkedList<Integer>(sortedSet);
System.out.println(linkedList);
}
public static void linkedListRandomFill(
LinkedList<Integer> linkedList,
int size,
int limit){
Random rnd = new Random();
for(int i = 0; i < size; i++){
linkedList.add(rnd.nextInt(limit));
}
}
Also we could refactor that:
public class Main {
public static void main(String[] args){
LinkedList<Integer> linkedList = new LinkedList<Integer>();
linkedListRandomFill(linkedList, 10, 100);
linkedList = getSortedListOfUniqueValues(linkedList);
System.out.println(linkedList);
}
public static void linkedListRandomFill(
LinkedList<Integer> linkedList,
int size,
int limit){
Random rnd = new Random();
for(int i = 0; i < size; i++){
linkedList.add(rnd.nextInt(limit));
}
}
public static LinkedList<Integer> getSortedListOfUniqueValues(LinkedList<Integer> list){
SortedSet<Integer> sortedSet = new TreeSet<Integer>(list);
return new LinkedList<Integer>(sortedSet);
}
}

How do filter out this list with java 8 streams and functional interfaces?

if I have a list of arrays like this (pseudo java code):
Note the list valsSorted will be always sorted with x[0] asc and x[1] desc order.
List valsSorted = {[1 5][1 4][1 3][2 1][3 2][3 1][4 2][4 1][5 1][6 2][6 1]};
How do I filter this list with Java 8 streams and lambdas so that I get:
result = {[1 5][2 1][3 2][4 2][5 1][6 2]}
The first item of the array (x[0]) is ID and the second is a version number. So the rule is give all distinct IDs with the highest version back.
If I would use a for loop the following code would be fine:
ArrayList<int[]> result= new ArrayList();
int keep = -1;
for (int[] x : valsSorted) {
int id = x[0];
int version = x[1];
if(keep == id) continue;
keep = id;
result.add(x);
}
Your use of the word "distinct" suggests using the distinct() stream operation. Unfortunately that operation is hardwired to use the equals() method of the stream elements, which isn't useful for arrays. One approach for dealing with this would be to wrap the arrays in a wrapper object that has the semantics of equality that you're looking for:
class Wrapper {
final int[] array;
Wrapper(int[] array) { this.array = array; }
int[] getArray() { return array; }
#Override
public boolean equals(Object other) {
if (! (other instanceof Wrapper))
return false;
else
return this.array[0] == ((Wrapper)other).array[0];
}
#Override
public int hashCode() { ... }
}
Then wrap up your object before distinct() and unwrap it after:
List<int[]> valsDistinct =
valsSorted.stream()
.map(Wrapper::new)
.distinct()
.map(Wrapper::getArray)
.collect(toList());
This makes one pass over the data but it generates a garbage object per value. This also relies on the stream elements being processed in-order since you want the first one.
Another approach would be to use some kind of stateful collector, but that will end up storing the entire result list before any subsequent processing begins, which you said you wanted to avoid.
It might be worth considering making the data elements be actual classes instead of two-element arrays. This way you can provide a reasonable notion of equality, and you can also make the values comparable so that you can sort them easily.
(Credit: technique stolen from this answer.)
class Test{
List<Point> valsSorted = Arrays.asList(new Point(1,5),
new Point(1,4),
new Point(1,3),
new Point(2,1),
new Point(3,2),
new Point(3,1),
new Point(4,2),
new Point(4,1),
new Point(5,1),
new Point(6,2),
new Point(6,1));
public Test(){
List<Point> c = valsSorted.stream()
.collect(Collectors.groupingBy(Point::getX))
.values()
.stream()
.map(j -> j.get(0))
.collect(Collectors.toList());
for(int i=0; i < c.size(); i++){
System.out.println(c.get(i));
}
}
public static void main(String []args){
Test t = new Test()
}
}
I decided to use the point class and represent the ID field as x and the version number as Y. So from there if you create a stream and group them by ID. You can call the values method which returns a Collection of Lists Collection<List<Point>>. You can then call the stream for this Collection and get the first value from each list which according to your specifications is ordered with descending version number so it should be the the highest version number. From there all you have to do is collect them into a list, array or whatever you see necessary and assign it as needed.
The only problem here is that they are printed out of order. That should be an easy fix though.

Java sort list containing list on index value of list?

I have a nested list like below (but it has 1,000's of the holder lists within the one main list). Say I need to sort the main list listEmailData by the value for each of its holder lists on the holder.get(2) index. I can't seem to figure out how to do this any advice is appreciated.
ArrayList listEmailData;
ArrayList holder = new ArrayList();
listEmailData.add(3)
listEmailData.add(323)
listEmailData.add(2342)
listEmailData.add(holder)
EDIT: To clarify, I have a list where each list entry contains a sub-list, within this sub-list a specific index contains a value that is a ranking. I need to sort the main list based on this ranking value within each sub-list.
2ND EDIT: Thanks for the help on this, got it working but its seems that its putting larger numbers first and large numbers later, I was hoping to reverse this so it goes from largest to smallest as I am
You should implement Comparator<T> to compare lists, then call
Collections.sort(listEmailData, comparator);
Your comparator would have to compare any two "sublists" - e.g. by fetching a particular value. For example:
public class ListComparator implements Comparator<List<Integer>>
{
private final int indexToCompare;
public ListComparator(int indexToCompare)
{
this.indexToCompare = indexToCompare;
}
public int compare(List<Integer> first, List<Integer> second)
{
// TODO: null checking
Integer firstValue = first.get(indexToCompare);
Integer secondValue = second.get(indexToCompare);
return firstValue.compareTo(secondValue);
}
}
Note that this is using generics - hopefully your real code is too.

List of Lists of Lists

I'm new to Java and I need to make a list of lists of lists. I could do it in python because an element of a list can be a list so in an embedded list list[0] would refer to a list and list[0][0] would refer to the zeroeth element of the embedded list. Is there any easy way to implement this behavior in java?
All the other answers are technically correct, but IMHO if you implement a rough List of Lists of Lists you are not treating your data at the right level of abstraction. For example I am pretty sure that a List of Lists already means "something" in your business domain. Encapsulate this "something" in another object so you can just have a List<Something> instead of a difficult to use and maintain List<List<List<Object>>>.
As Mario says, you probably need to abstract out your data a little further. But, the following will do what you need.
In Java you would so something like:
List<List<List<Object>>> listOfListsOfLists =new ArrayList<List<List<Object>>>();
Then to access the items, you would use:
listOfListsOfLists.get(a).get(b).get(c);
Or, to iterate over everything:
for (List<List<Object>> list2: listOfListsOfLists) {
for (List<Object> list1: list2) {
for (Object o: list1) {
// use `o`
}
}
}
Since all of these answers make me barf, can I just add the suggestion that you either
Create a data type to express your data while encapsulating the details of the structure, or at least
Create a key type that wraps an int[] (but overrides equals and hashCode properly) and use a HashMap instead? It's typically rare that your whole 3-dimensional structure will be filled up much anyway.
Even better you could encapsulate that map and use varargs for clean access.
public class NDimensionalArray<V> {
private final int dimensions;
private final Map<Key, V> values = new HashMap<Key, V>();
private NDimensionalArray(int dimensions) {
this.dimensions = dimensions;
}
public V get(int... indices) {
checkIndices(indices);
return values.get(new Key(indices));
}
public void set(V value, int... indices) {
checkIndices(indices);
values.put(new Key(indices), value);
}
private void checkIndices(int[] indices) {
if ( indices.length != dimensions ) {
throw new IllegalArgumentException();
}
}
private static final class Key {
private final int[] indices;
private Key(int[] indices) {
this.indices = indices;
}
#Override
public int hashCode() {
return Arrays.hashCode(indices);
}
#Override
public boolean equals(Object obj) {
return Arrays.equals(indices, ((Key)obj).indices);
}
}
}
If people have examples of established collections libraries that already do this sort of thing, let me know and I'll add links.
While it is certainly true that you can construct a List<List<List<whatever>>> in Java, I can't help but wonder, Why do you want to do this? Not that it's inconceivable that this is the best solution to your problem, but wow, like why?
I guess I could imagine something like
public class Employee ...
List<Employee> store; // all the employees in a store
List<List<Employee>> city; // all the store lists for a city
List<List<List<Employee>>> nation; // all the store lists for the nation
But would you really want to process it that way? I don't know, it depends on what you need to do with it.
A comprehensive example showing List-of-List with collections and generics (Java 1.5+)
// declare the list of lists
List<List<String>> listOfListOfStrings = new ArrayList<List<String>>();
// populate
List<String> listOfStrings = new ArrayList<String>(); // one inner list
listOfStrings.add("one-one");
listOfStrings.add("one-two");
listOfListOfStrings.add(listOfStrings);
listOfStrings = new ArrayList<String>(); // and another one
listOfStrings.add("two-one");
listOfStrings.add("two-two");
listOfListOfStrings.add(listOfStrings);
// access
String oneOne = listOfListOfStrings.get(0).get(0); // first element of first inner list
String twoTwo = listOfListOfStrings.get(1).get(1); // second element of second inner list

Categories

Resources