import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class PowerSet {
public static final <E> Collection<Set<E>> of(Set<E> s) {
List<E> src = new ArrayList<>(s);
if (src.size() > 30) {
throw new IllegalArgumentException("Set too big " + s);
}
return new AbstractList<Set<E>>() {
#Override
public int size() {
return 1 << src.size(); // 2 to the power srcSize
}
#Override
public boolean contains(Object o) {
return o instanceof Set && src.containsAll((Set) o);
}
#Override
public Set<E> get(int index) {
Set<E> result = new HashSet<>();
for (int i = 0; index != 0; i++, index >>= 1) {
if ((index & 1) == 1) {
result.add(src.get(i));
}
}
return result;
}
};
}
public static void main(String[] args) {
Collection<Set<String>> set = new HashSet<>();
set.add()... }
I have this code I got from Java Effective as how implement
power set but I am confused how to initialise this set and
fill it with values. There is interface with three overridden
methods, concretely contains, get and size. What does of in class
declaration mean?
To initialize PowerSet instance you need to call it's constructor PowerSet(), though it'll be useless since there is no object related underlying logic in it.
"of" is a static method declared in PowerSet, accepting a set with size <= 30 and returning a List of Sets with logic of power set.
It is implemented by extension of AbstractList.
Set<Long> input = new HashSet<Long>();
input.add(1L);
input.add(2L);
List<Set<Long>> example = PowerSet.<Long>of(input);
So, example.get(0) will result with an empty HashSet, example.get(1) == {1}; example.get(2) == {2}, example.get(3) == {1, 2}
You can rewrite it in a more conventional format:
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class PowerSet<E> extends AbstractList<Set<E>> {
private List<E> src;
public PowerSet(Set<E> s){
//copying set contains to a list to access by index
src = new ArrayList<>(s);
}
#Override
public int size() {
return 1 << src.size(); // 2 to the power srcSize
}
#Override
public boolean contains(Object o) {
return o instanceof Set && src.containsAll((Set) o);
}
#Override
public Set<E> get(int index) {
Set<E> result = new HashSet<>();
for (int i = 0; index != 0; i++, index >>= 1) {
if ((index & 1) == 1) {
result.add(src.get(i));
}
}
return result;
}
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add()...
PowerSet<String> = new PowerSet(set);
}
Related
Below is my code (can be copy paste in https://www.compilejava.net/ with -ea as command line option).
I have an Object called Main. I have Main inside a List. If 2 properties (a and b) are equal to another Main object in the list, property strings should be concatenated. Furthermore, duplicates (when the 2 properties are equal) should than be removed (so the list can not contain 2 or more Mains in which both a and b are the same).
I tried it with a HashMap, hashCode, but I can not figure it out well. Note: I use OpenJDK-12 and can not use newer versions.
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class Main {
final int a;
final int b;
final List<String> strings;
Main(int a, int b, List<String> strings) {
this.a = a;
this.b = b;
this.strings = strings;
}
private static Main generateMain0() {
return new Main(0, 1, createListWithOneElement("merge me with main1"));
}
public static void main(String[] args) {
Main main0 = generateMain0();
Main main1 = new Main(0, 1, createListWithOneElement("merge me with main2"));
Main main2 = new Main(0, 2, createListWithOneElement("leave me alone"));
Main main3 = new Main(0, 2, createListWithOneElement("leave me alone also"));
List<Main> mains = new ArrayList<>();
mains.add(main0);
mains.add(main1);
mains.add(main2);
mains.add(main3);
// Do magic here to remove duplicate and concat property strings
// main1 should be removed, since property a and b were equal to main0 property a and b
assert mains.size() == 3;
Main main0Copy = generateMain0();
main0Copy.strings.add("merge me with main2");
// The first element should be main0. It should also contain
// the strings of main1 since property a and b were equal
assert mains.get(0).equals(main0Copy);
assert mains.get(1).equals(main2);
assert mains.get(2).equals(main3);
}
private static List<String> createListWithOneElement(String value) {
List<String> l = new ArrayList<>();
l.add(value);
return l;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Main main = (Main) o;
return a == main.a &&
b == main.b &&
strings.equals(main.strings);
}
#Override
public int hashCode() {
return Objects.hash(a, b, strings);
}
}
If, as you said in the comments, you can use a fully custom List, you can try the code below.
Internally, it uses a combination of a List and a Map to find out if a combination of a and b was already added to the "List". If yes, it adds all strings of the given Main to the existing Main. If not, it adds the given Main the the list.
package example;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainList {
private final List<Main> mains;
private final Map<Key, Main> lookup;
public MainList() {
this.mains = new ArrayList<>();
this.lookup = new HashMap<>();
}
public Main get(int index) {
return this.mains.get(index);
}
public void add(Main main) {
final Key key = new Key(main.a, main.b);
Main existingMain = this.lookup.get(key);
if (existingMain == null) {
this.mains.add(main);
this.lookup.put(key, main);
} else {
existingMain.strings.addAll(main.strings);
}
}
public void remove(Main main) {
final Key key = new Key(main.a, main.b);
Main existingMain = this.lookup.get(key);
if (existingMain != null) {
if (existingMain.equals(main)) {
this.mains.remove(existingMain);
this.lookup.remove(key);
} else {
existingMain.strings.removeAll(main.strings);
}
}
}
public void remove(int index) {
final Main removedMain = this.mains.remove(index);
final Key key = new Key(removedMain.a, removedMain.b);
this.lookup.remove(key);
}
public int size() {
return this.mains.size();
}
private static class Key {
private final int a;
private final int b;
private Key(int a, int b) {
this.a = a;
this.b = b;
}
#Override
public boolean equals(Object object) {
if (this == object) {
return true;
} else if (object == null || getClass() != object.getClass()) {
return false;
}
Key key = (Key) object;
return this.a == key.a && this.b == key.b;
}
#Override
public int hashCode() {
return 31 * this.a + 31 * this.b;
}
}
}
This question already has answers here:
How to find an object in an ArrayList by property
(8 answers)
Closed 4 years ago.
I am maintaining a sorted ArrayList of objects (by overwriting the add method as shown here) where each object has 2 attributes: a and b. How can I retrieve an object for which a equals 5?
I cannot use a map, because the value which I want to sort the list on must be able to accept duplicates (which is why this answer is not applicable here).
Code:
class TimeMap {
List<MyType> list = new ArrayList<KVT>() {
public boolean add(KVT mt) {
int index = Collections.binarySearch(this, mt, new SortByTime());
if (index < 0) index = ~index;
super.add(index, mt);
return true;
}
};
}
class KVT{//value-timestamp object
String value;
int timestamp;
public VT(String v, int t){
value=v;
timestamp=t;
}
}
class SortByTimestamp implements Comparator<KVT>{
public int compare(KVT a, KVT b){
return a.timestamp.compareTo(b.timestamp);
}
}
I have written a small example using java8 streams where you can get the object from the ArrayList by a property of the object.
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Test> list = Arrays.asList(new Test(1, 2), new Test(5, 6), new Test(3, 4));
Test test = list.stream().filter(obj -> obj.a == 5).findFirst().orElse(null);
System.out.println(test.a);
}
}
class Test {
int a;
int b;
Test(int a, int b) {
this.a = a;
this.b = b;
}
}
Hope this will give you an idea
Here is an mcve demonstrating retrieval by timestamp as well as some other enhancement:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class TimeMap {
private List<KVT> list;
TimeMap() {
list = new ArrayList<>() {
#Override
public boolean add(KVT mt) {
super.add(mt); //add
Collections.sort(this, new SortByTimestamp()); //resort after add
return true;
}
};
}
boolean add(KVT mt){return list.add(mt);}
KVT getByTimeStamp(int timestamp){
for(KVT mt : list){
if(timestamp == mt.timestamp)
return mt;
}
return null;
}
//returns a copy of list
List<KVT> getListCopy() { return new ArrayList<>(list) ;};
//test
public static void main(String[] args) {
TimeMap tm = new TimeMap();
tm.add(new KVT("A", 2));
tm.add(new KVT("B", -3));
tm.add(new KVT("C", 1));
System.out.println(tm.getListCopy());
System.out.println(tm.getByTimeStamp(1));
}
}
class KVT{
String value;
int timestamp;
public KVT(String v, int t){
value=v;
timestamp=t;
}
#Override
public String toString(){ return value+" ("+timestamp+")";}
//todo add getters
}
class SortByTimestamp implements Comparator<KVT>{
#Override
public int compare(KVT a, KVT b){
//compareTo can not be applied to primitives
return Integer.valueOf(a.timestamp).compareTo(b.timestamp);
}
}
here is the code of C# which i am trying to convert
ArrayList.BinarySearch(Object, IComparer)
what it does is to comparer a node class object with a compare class object and returns -1, 0 or positive integer.
i have searched a lot and tried to convert it in java but could not do so. i'll need a method, instructions, library or anything that could help me achieve it.
class Class1
{
[STAThread]
static void Main(string[] args)
{
ArrayList SolutionPathList = new ArrayList();
//Create a node containing the goal state node_goal
Node node_goal = new Node(null,null,1,15,15);
//Create a node containing the start state node_start
Node node_start = new Node(null,node_goal,1,0,0);
//Create OPEN and CLOSED list
SortedCostNodeList OPEN = new SortedCostNodeList ();
SortedCostNodeList CLOSED = new SortedCostNodeList ();
//Put node_start on the OPEN list
OPEN.push (node_start);
}
SortedNode class is:
public class SortedCostNodeList
{
ArrayList _list;
NodeComparer _nodeComparer;
public SortedCostNodeList()
{
_list = new ArrayList ();
_nodeComparer = new NodeComparer ();
}
public int push (Node n)
{
int k = _list.BinarySearch (n,_nodeComparer);
if (k==-1) // no element
_list.Insert (0,n);
else if (k<0) // find location by complement
{
k=~k;
_list.Insert (k,n);
}
else if (k>=0)
_list.Insert (k,n);
return k;
}
and nodecomparer class is:
public class NodeComparer:IComparer
{
public NodeComparer()
{
}
public int Compare(object x, object y)
{
return ((Node)x).totalCost - ((Node) y).totalCost ;
}
}
i am unable to implement this piece of code
//int k = _list.BinarySearch (n,_nodeComparer);
any help?
You can use Arrays.binarySearch() to perform binary search on an array of Object.
I have created a sample program. Hope it helps.
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
#Getter #Setter
#AllArgsConstructor
class Node {
private long totalCost;
}
public class StackOverFlow {
public static void main(String... args) {
final List<Node> list = new ArrayList<>();
list.add(new Node(10));
list.add(new Node(20));
list.add(new Node(30));
list.add(new Node(40));
list.add(new Node(50));
list.add(new Node(60));
list.add(new Node(70));
final Node searchKey = new Node(60);
int index = Arrays.binarySearch(list.toArray(new Node[list.size()]), searchKey, new Comparator<Node>() {
#Override
public int compare(Node o1, Node o2) {
return (int) (o1.getTotalCost() - o2.getTotalCost());
}
});
System.out.print("Found at " + index);
}
}
Update:
Try this
class NodeComparator implements Comparator<Node> {
#Override
public int compare(Node o1, Node o2) {
return (int) (o1.getTotalCost() - o2.getTotalCost());
}
}
class SortedCostNodeList {
ArrayList<Node> list;
NodeComparator nodeCompartor;
public SortedCostNodeList() {
this.list = new ArrayList<>();
this.nodeCompartor = new NodeComparator();
}
public int push(Node n) {
int k = Arrays.binarySearch(this.list.toArray(new Node[list.size()]), n, this.nodeCompartor);
if (k == -1) // no element
this.list.add(0, n);
else if (k < 0) // find location by complement
{
k = ~k;
this.list.add(k, n);
} else if (k >= 0)
this.list.add(k, n);
return k;
}
// ...
}
ObservableList listeners can receive Change events with permutation set.
Simultaneously, among list operations, I see only ones to delete or insert elements.
Is it possible to perform such operation on list, which will cause permutation reported?
UPDATE
Here is the clarification code:
public class ObservableListPermutation {
public static void main(String[] args) {
ObservableList<String> list = FXCollections.observableArrayList();
list.add("timbuktu");
list.add("timid");
list.addListener(new ListChangeListener<String>() {
#Override
public void onChanged(Change<? extends String> c) {
while(c.next()) {
if( c.wasPermutated() ) {
System.out.println("Was permutated");
}
}
}
});
System.out.println("Sorting by library:");
Collections.sort(list);
System.out.println("Sorting by own:");
Collections2.sort(list);
}
public static class Collections2 {
public static void sort(List<String> list) {
String element = list.remove(0);
list.add(element);
}
}
}
As you see, my custom permutation does not cause permutation event, because it is done by removing and adding elements. How to implement custom permutation, so that it cause permutation event?
UPDATE 2
If I try to trace sort() with debugger, I am unable to enter the code of sort().
To elaborate on #ItachiUchiha's answer and #fabian's comment, any single operation that modifies an ObservableList will notify change listeners. So there is no way to trigger a "permutation event" on an ObservableList by calling a sequence of operations that each modify the list (each operation would notify listeners independently).
So to support permutations that are not supported out of the box (i.e. by FXCollections.sort(), FXCollections.shuffle(), FXCollections.rotate(), and FXCollections.reverse()), you need to implement your own ObservableList, defining (or possibly overriding) single entry-point methods that trigger a permutation. The ModifiableObservableListBase class provides a convenient starting point.
Here is a simple example:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javafx.collections.ModifiableObservableListBase;
public class PermutatingObservableList<E> extends ModifiableObservableListBase<E> {
private final List<E> source ;
public PermutatingObservableList(List<E> source) {
this.source = source ;
}
public void permute(int[] permutation) {
checkPermutation(permutation);
beginChange();
List<E> temp = new ArrayList<>(source);
for (int i = 0 ; i < size() ; i++) {
source.set(i, temp.get(permutation[i]));
}
nextPermutation(0, size(), permutation);
endChange();
}
public void pairwiseSwap() {
int[] permutation = new int[size()];
for (int i = 0; i+1 < permutation.length ; i+=2) {
permutation[i] = i+1 ;
permutation[i+1] = i ;
}
if (permutation.length % 2 == 1) {
permutation[permutation.length - 1] = permutation.length - 1 ;
}
permute(permutation);
}
private void checkPermutation(int[] permutation) {
boolean valid = permutation.length == size();
Set<Integer> values = IntStream.range(0, size()).boxed().collect(Collectors.toSet());
for (int i=0; i<permutation.length && valid ; i++) {
valid = values.remove(new Integer(permutation[i]));
}
if (! valid) {
throw new IllegalArgumentException("Invalid permuation: "+Arrays.toString(permutation)+"\n"
+"Permutation must be same length as list and must contain each of the values "
+ "0-"+(size()-1)+" exactly once");
}
}
#Override
public E get(int index) {
return source.get(index);
}
#Override
public int size() {
return source.size();
}
#Override
protected void doAdd(int index, E element) {
source.add(index, element);
}
#Override
protected E doSet(int index, E element) {
return source.set(index, element);
}
#Override
protected E doRemove(int index) {
return source.remove(index);
}
}
and a test:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javafx.collections.ListChangeListener;
public class PermutingObservableListTest {
public static void main(String[] args) {
List<String> numbers = Arrays.asList("One", "Two", "Three", "Four", "Five");
PermutatingObservableList<String> list = new PermutatingObservableList<>(new ArrayList<>(numbers));
list.addListener(new ListChangeListener<String>() {
#Override
public void onChanged(Change<? extends String> c) {
while (c.next())
System.out.println(c.wasPermutated());
System.out.println(IntStream.range(0, list.size())
.map(c::getPermutation)
.mapToObj(Integer::toString)
.collect(Collectors.joining(", ")));
}
}
});
list.pairwiseSwap();
System.out.println(list);
}
}
which produces the output
true
1, 0, 3, 2, 4
[Two, One, Four, Three, Five]
A very simple operation a List to report Permutation would be to sort the items in the List.
For example, the following code would print true.
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import java.util.Collections;
public class PermutationTest {
public static void main(String[] args) {
ObservableList<String> list =
FXCollections.observableArrayList("Z", "Y", "X");
list.addListener(new ListChangeListener<String>() {
#Override
public void onChanged(Change<? extends String> c) {
c.next();
System.out.println(c.wasPermutated());
}
});
Collections.sort(list);
}
}
Answers to additional question :
I would like to cause it myself, without calling black box methods. Suppose I have instance of ObservableList and nothing more and would like to code some manipulation, which causes permutation, How would I do this?
This is not possible if you are using the ObservableList provided by FXCollections util class because of the way ObservableList is implemented in it.
Considering the following points :
Whenever you add or remove elements a MappingChange is triggered.
ListChangeListener#wasPermutated() checks if length of the int array returned by getPermutation() is greater than zero.
In case of MappingChange, the getPermuatation() always returns an int of length 0.
Now, you must be wondering (like I was), how does it work when we do a sort on the same List?
It turns out the ObservableListWrapper (which is the base for creating list in FXCollections) overrides sort() and then forces a SimplePermutationChange.
Is there an alternative?
You can create your own custom ObservableList by extending ModifiableObservableListBase as stated by this comment and shown in this answer.
I have made a Priority Queue class with an array list, but I am having trouble with the insert and delMin (delete minimum areas). I cannot create more functions and here is my code:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class MyMinPQ<E extends Comparable<E>> implements Iterable<E> {
private ArrayList<E> pq;
private int N;
public MyMinPQ() {
pq = new ArrayList<E>();
}
public E delMin(){
E minVal = min();
pq.remove(0);
N--;
return minVal;
}
public E min (){
if (isEmpty())
throw new NoSuchElementException();
return pq.get(0);
}
public void insert (E item){
for (int i = 0; i < N; i++){
pq.add(item);
if (pq.get(i) > pq.get(i+1)) {
E tmp = pq.get(i);
pq.set(i+1, tmp);
}
}
N++;
}
public boolean isEmpty() {
return N == 0;
}
public int size() {
return N;
}
public Iterator<E> iterator() {
return new Iterator<E>(){
int current = 0;
public boolean hasNext() {
return current != size();
}
public E next() {
if (hasNext())
return pq.get(current++);
else throw new NoSuchElementException( );
}
public void remove() {
throw new UnsupportedOperationException( );
}
};
}
}
At the insert portion of the code, I know that I have to sort the new additions to Arraylist but I am having issues with going about this. I tried to compare the values that is within the list, but eclipse does not allow it based on how I formatted it. When I use compareTo, it does not work with my iterator and everything goes into disarray.
My question is how can I go about modifying my insert function so it can sort new items in descending order? Will my delMin() also have to change because of it?
try this
public void insert(E item) {
int i = 0;
while (i < N && pq.get(i).compareTo(item) <= 0) {
i++;
}
N++;
}